MyBatis_學(xué)習(xí)筆記匯總

閱讀需要20分鐘

一惩妇、MyBatis的開始

官方文檔開始

MyBatis是什么

  • 持久層框架
  • 支持定制化 SQL搪哪、存儲(chǔ)過程以及高級(jí)映射
  • 避免幾乎所有的JDBC代碼和手動(dòng)設(shè)置參數(shù)以及獲得結(jié)果集
  • 可以使用簡(jiǎn)單的xml或者注釋來配置和映射原生類型猾愿、接口和Java的pojo(Plain Old Java Object嗅榕,普通老式Java對(duì)象)為數(shù)據(jù)庫中的記錄窥突。

MyBatis的Maven配置

        <!--mybatis-->
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>

持久化

  • 程序數(shù)據(jù)在持久狀態(tài)和瞬時(shí)狀態(tài)轉(zhuǎn)化的過程
  • 內(nèi)存特點(diǎn):斷電即失
  • 數(shù)據(jù)庫、io文件實(shí)現(xiàn)數(shù)據(jù)持久化

持久層

  • 完成持久化工作的代碼塊

MyBatis的優(yōu)點(diǎn)

  • 對(duì)數(shù)據(jù)庫進(jìn)行增刪改查
  • 簡(jiǎn)單、靈活
  • sql和代碼的分離经备,提高可維護(hù)性
  • 提供映射標(biāo)簽拭抬,支持對(duì)象與數(shù)據(jù)庫的orm字段關(guān)系映射
  • 提供對(duì)象關(guān)系映射標(biāo)簽,支持對(duì)象關(guān)系組建維護(hù)
  • 提供xml標(biāo)簽侵蒙,支持編寫動(dòng)態(tài)sql

第一個(gè)MyBatis程序

1. 配置pom.xml

  • 父工程
  1. 在一個(gè)maven項(xiàng)目中創(chuàng)建一個(gè)model
  2. 導(dǎo)入依賴造虎,子工程也可以使用這些依賴,而不用在子工程的xml中再次導(dǎo)入依賴
<!--父工程-->
    <groupId>com.vigil</groupId>
    <artifactId>Mybatis_Study</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <!--子工程-->
    <modules>
        <module>mybatis-01</module>
    </modules>

    <!--導(dǎo)入依賴-->
    <dependencies>
        <!--mysql驅(qū)動(dòng)-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!--mybatis-->
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>
        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

error:資源導(dǎo)出問題

  • 處理方式:在項(xiàng)目配置文件中加入下面的代碼
 <!--    在build中配置resources纷闺,來防止我們資源導(dǎo)出失敗的問題-->
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
            </resource>

            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
            </resource>
        </resources>
    </build>

2. 子工程項(xiàng)目配置

  • 這里使用默認(rèn)生成的就行
<parent>
        <artifactId>Mybatis_Study</artifactId>
        <groupId>com.vigil</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>mybatis-01</artifactId>

3. 數(shù)據(jù)庫

  • 用于查詢的簡(jiǎn)單數(shù)據(jù)庫
create table user
(
    id   int(20)     not null comment 'id'
        primary key,
    name varchar(20) not null comment 'name',
    pwd  varchar(20) not null comment 'password'
)
    charset = utf8;
  • idea連接數(shù)據(jù)庫

4. 編寫對(duì)應(yīng)數(shù)據(jù)庫的JavaBean:User類

5. 編寫MyBatis的配置文件

XML 配置文件中包含了對(duì) MyBatis 系統(tǒng)的核心設(shè)置算凿,包括獲取數(shù)據(jù)庫連接實(shí)例的數(shù)據(jù)源(DataSource):需要對(duì)應(yīng)自己的數(shù)據(jù)庫進(jìn)行配置
以及決定事務(wù)作用域和控制方式的事務(wù)管理器(TransactionManager)。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&amp;characterEncoding=UTF-8&amp;useJDBCCompliantTimezoneShift=true&amp;useLegacyDatetimeCode=false&amp;serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="20201123"/>
            </dataSource>
        </environment>
    </environments>

    <!--每一個(gè)Mapper.xml文件都需要到mybatis的配置文件下注冊(cè)-->
    <mappers>
        <mapper resource="com/vigil/dao/UserMapper.xml"></mapper>
    </mappers>

</configuration>

6. 編寫獲得數(shù)據(jù)庫連接的工具類

每個(gè)基于 MyBatis 的應(yīng)用都是以一個(gè) SqlSessionFactory 的實(shí)例為核心的犁功。SqlSessionFactory 的實(shí)例可以通過 SqlSessionFactoryBuilder 獲得氓轰。而 SqlSessionFactoryBuilder 則可以從 XML 配置文件或一個(gè)預(yù)先配置的 Configuration 實(shí)例來構(gòu)建出 SqlSessionFactory 實(shí)例。

package com.vigil.util;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

//SqlSessionFactory  --->  SqlSession
public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            //獲取SqlSessionFactory對(duì)象
            // 要先獲得SqlSessionFactoryBuilder對(duì)象浸卦,在數(shù)據(jù)庫資源文件中獲得
//從 XML 文件中構(gòu)建 SqlSessionFactory 的實(shí)例非常簡(jiǎn)單署鸡,建議使用類路徑下的資源文件進(jìn)行配置。 但也可以使用任意的輸入流(InputStream)實(shí)例限嫌,比如用文件路徑字符串或 file:// URL 構(gòu)造的輸入流靴庆。MyBatis 包含一個(gè)名叫 Resources 的工具類,它包含一些實(shí)用方法怒医,使得從類路徑或其它位置加載資源文件更加容易炉抒。
            String resource = "mybatis-config.xml";
            InputStream inputStream =  Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //既然有了 SqlSessionFactory,顧名思義裆熙,我們可以從中獲得 SqlSession 的實(shí)例端礼。
    // SqlSession 提供了在數(shù)據(jù)庫執(zhí)行 SQL 命令所需的所有方法。你可以通過 SqlSession 實(shí)例來直接執(zhí)行已映射的 SQL 語句入录。
    public static SqlSession getSqlSession() {
        return sqlSessionFactory.openSession();
    }
}

7. 編寫Mapper接口(對(duì)應(yīng)javaweb的dao接口蛤奥,操作數(shù)據(jù)庫)

public interface UserDao {
    List<User> getUserList();
}

8. 編寫Mapper的對(duì)應(yīng)xml文件

類似javaweb里面的DaoImpl類
需要注意的是:
1、namespace(命名空間)=綁定一個(gè)對(duì)應(yīng)的Dao\Mapper接口名:com.vigil.dao.UserDao
2僚稿、重寫方法 --> select查詢語句凡桥,id對(duì)應(yīng)mapper中方法名字,resultType對(duì)應(yīng)返回類型
全限定名:映射-->com.vigil.dao.UserDao.getUserList

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--1蚀同、namespace(命名空間)=綁定一個(gè)對(duì)應(yīng)的Dao\Mapper接口-->
<mapper namespace="com.vigil.dao.UserDao">
    <!--2缅刽、重寫方法 -->
    <!--select查詢語句,id對(duì)應(yīng)方法名字蠢络,resultType對(duì)應(yīng)返回類型(全限定名) -->
    <select id="getUserList" resultType="com.vigil.pojo.User">
        select * from mybatis.user
    </select>
</mapper>

9. 注冊(cè)mapper.xml(尤其重要)

每一個(gè)Mapper.xml文件都需要到mybatis的配置文件下注冊(cè)

    <!--每一個(gè)Mapper.xml文件都需要到mybatis的配置文件下注冊(cè)-->
    <mappers>
        <mapper resource="com/vigil/dao/UserMapper.xml"></mapper>
    </mappers>

10. 測(cè)試Mapper

package com.vigil.dao;

import com.vigil.pojo.User;
import com.vigil.util.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class UserDaoText {
    @Test
    public void text() {
        // 獲得SqlSession對(duì)象衰猛,從而執(zhí)行sql語句
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        // 執(zhí)行sql
        //方式一:getMapper
        // userDao是在web時(shí)對(duì)數(shù)據(jù)層操作的一個(gè)叫法,Data Access Object數(shù)據(jù)庫訪問對(duì)象
        // 而在Mybatis中則叫mapper刹孔,通過類名得到這個(gè)類的一個(gè)實(shí)例啡省,反射和多態(tài)性
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        List<User> userList = userDao.getUserList();

        //方式二,方法后不用加括號(hào),
        // 對(duì)于結(jié)果的返回是要確切知道方法的返回類型卦睹,然后需要選擇對(duì)應(yīng)的sqlsession方法并且進(jìn)行強(qiáng)制轉(zhuǎn)換
        // List<User> userList = sqlSession.selectList("com.vigil.dao.UserDao.getUserList");

        for (User user : userList) {
            System.out.println(user.toString());
        }

        //關(guān)閉SqlSession
        sqlSession.close();
    }
}

方式一(優(yōu)先選擇):在對(duì)應(yīng)的映射器接口調(diào)用方法畦戒。
命名就可以直接映射到在命名空間中同名的映射器類,并將已映射的 select 語句匹配到對(duì)應(yīng)名稱结序、參數(shù)和返回類型的方法障斋。

UserDao userDao = sqlSession.getMapper(UserDao.class);
List<User> userList = userDao.getUserList();

方式二:用全限定名 “com.vigil.dao.UserDao.getUserList” 來調(diào)用映射語句,風(fēng)險(xiǎn)在于:對(duì)于結(jié)果的返回是要確切知道方法的返回類型徐鹤,然后需要選擇對(duì)應(yīng)的sqlsession方法并且進(jìn)行強(qiáng)制轉(zhuǎn)換

List<User> userList = sqlSession.selectList("com.vigil.dao.UserDao.getUserList");

mapper.xml的注意項(xiàng):

  1. id:對(duì)應(yīng)命名空間的接口的方法名
  2. resultType:sql語句執(zhí)行的返回值類型
  3. parameterType:傳入方法中參數(shù)的類型
  4. 對(duì)象中的屬性垃环,可以直接根據(jù)變量名取出來
  5. 標(biāo)簽名和sql語句要一一匹配,是select的sql語句就對(duì)應(yīng)select標(biāo)簽凳干,是update的sql語句就對(duì)應(yīng)update標(biāo)簽
  6. mybatis配置文件中注冊(cè)時(shí)晴裹,mapper標(biāo)簽對(duì)應(yīng)的 resource 標(biāo)簽要使用mapper的相對(duì)類路徑(com/vigil/dao/UserMapper.xml)注意是用的" / "
  7. 取值符號(hào):#{}被济,括號(hào)內(nèi)填寫變量名
  8. 參數(shù)取出關(guān)聯(lián)著設(shè)置

(1)Map傳遞參數(shù)救赐,直接在sql中取出key即可!【parameterType="Map"】
(2)對(duì)象傳遞參數(shù)只磷,直接在sql中取對(duì)象的屬性即可经磅!【parameterType="Object"】
(3)只有一個(gè)基本參數(shù)的情況下,可以直接在sql中取到【可以不寫】
(4)多個(gè)參數(shù)建議用Map钮追,或者是注解

CRUD

1. namespace(命名空間)

命名空間的作用有兩個(gè)预厌,一個(gè)是利用更長(zhǎng)的全限定名來將不同的語句隔離開來,同時(shí)也實(shí)現(xiàn)了你上面見到的接口綁定元媚。

  • 全限定名(比如 "com.vigil.dao.UserDao.getUserList")將被直接用于查找及使用轧叽。

編寫步驟

  1. 編寫接口
  2. 編寫對(duì)應(yīng)的mapper中的sql語句
  3. 測(cè)試:增刪改需要提交事務(wù)

2. select

  • interface
    //根據(jù)id查詢用戶
    User getUserById(int id);
  • mapper.xml
    <select id="getUserById" parameterType="int" resultType="com.vigil.pojo.User">
        select * from mybatis.user where id = #{id}
    </select>
  • test
    @Test
    public void getUserById() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        User user = mapper.getUserById(1);

        System.out.println(user.toString());

        sqlSession.close();
    }

3. Insert

  • interface
    //插入一個(gè)新用戶
    int addUser(User user);
  • mapper.xml
    <!--對(duì)象中的屬性,可以直接根據(jù)變量名取出來-->
    <insert id="addUser" parameterType="com.vigil.pojo.User">
        insert into mybatis.user (id, name, pwd) values (#{id},#{name},#{pwd})
    </insert>
  • test
    @Test
    public void addUser() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        int i = mapper.addUser(new User(4,"23","144352543"));
        System.out.println(i);

        //事務(wù)提交
        sqlSession.commit();

        sqlSession.close();
    }

4. update

  • interface
    //修改用戶
    int updateUser(User user);
  • mapper.xml
    <update id="updateUser" parameterType="com.vigil.pojo.User">
        update mybatis.user set name = #{name}, pwd = #{pwd} where id = #{id}
    </update>
  • test
    @Test
    public void updateUser() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        int i = mapper.updateUser(new User(4, "扯一扯", "12323"));
        System.out.println(i);
        //事務(wù)提交
        sqlSession.commit();

        sqlSession.close();
    }

5. delete

  • interface
    //刪除一個(gè)用戶
    int deleteUser(int id);
  • mapper.xml
    <delete id="deleteUser" parameterType="int">
        delete from mybatis.user where id = #{id}
    </delete>
  • test
    @Test
    public void deleteUser() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        int i = mapper.deleteUser(4);
        System.out.println(i);
        //事務(wù)提交
        sqlSession.commit();
        sqlSession.close();
    }

Map

前提:實(shí)體類刊棕、或者數(shù)據(jù)庫中的表炭晒,字段或者參數(shù)過多,考慮使用Map傳參

  • interface
    //根據(jù)id查詢用戶
    User getUserByIdMap(Map<String,Object> map);
  • mapper.xml
    <select id="getUserByIdMap" parameterType="map" resultType="com.vigil.pojo.User">
        select * from mybatis.user where id = #{userid}
    </select>
  • test
    public void getUserByIdMap() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("userid",1);
        User user = mapper.getUserByIdMap(map);
        System.out.println(user);
        sqlSession.close();
    }

模糊查詢

  1. Java代碼執(zhí)行時(shí)甥角,傳遞通配符% %
  2. 在sql拼接中使用通配符
    模糊查詢的4種實(shí)現(xiàn)方式



二网严、MyBatis配置簡(jiǎn)單解析

(一)、核心配置文件

  • mybatis-config.xml
  • MyBatis 的配置文件包含了會(huì)深深影響 MyBatis 行為的設(shè)置和屬性信息

configuration(配置)
properties(屬性)
settings(設(shè)置)
typeAliases(類型別名)
typeHandlers(類型處理器)
objectFactory(對(duì)象工廠)
plugins(插件)
environments(環(huán)境配置)
environment(環(huán)境變量)
transactionManager(事務(wù)管理器)
dataSource(數(shù)據(jù)源)
databaseIdProvider(數(shù)據(jù)庫廠商標(biāo)識(shí))
mappers(映射器)

(二)嗤无、環(huán)境變量(environment)

  • MyBatis 可以配置適應(yīng)多種環(huán)境
  • 盡管可以配置多個(gè)環(huán)境震束,但每個(gè) SqlSessionFactory 實(shí)例只能選擇一種環(huán)境。
  • MyBatis 默認(rèn)的事務(wù)管理器是jdbc当犯,連接池:POOLED

(三)垢村、屬性(properties)

通過properties屬性來實(shí)現(xiàn)引入配置文件

這些屬性可以在外部進(jìn)行配置,并可以進(jìn)行動(dòng)態(tài)替換嚎卫。你既可以在典型的 Java 屬性文件中配置這些屬性嘉栓,也可以在 properties 元素的子元素中設(shè)置。

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
username=root
password=20201123

在配置文件中引入

  • xml中標(biāo)簽位置有限定
    image
    <!--引入外部配置文件-->
    <properties resource="db.properties">
        <property name="password" value="20201123"/>
    </properties>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
  • 可以直接引入外部文件
  • 可以在其中增加一些屬性配置
  • 如果兩個(gè)文件中同名的字段,最后讀取作為方法參數(shù)傳遞的屬性胸懈,并覆蓋之前讀取過的同名屬性担扑。

(四)、類型別名(typeAliases)

  • 類型別名可為 Java 類型設(shè)置一個(gè)縮寫名字趣钱。
  • 僅用于 XML 配置涌献,意在降低冗余的全限定類名書寫。

第一種方法

    <typeAliases>
        <typeAlias type="com.vigil.pojo.User" alias="User"></typeAlias>
    </typeAliases>

第二種方法
指定一個(gè)包名首有,MyBatis 會(huì)在包名下面搜索需要的 Java Bean燕垃,比如掃描一個(gè)實(shí)體類的包,他的默認(rèn)別名就為這個(gè)類的 類名井联,首字母小寫

    <typeAliases>
        <package name="com.vigil.pojo"/>
    </typeAliases>
  • 在實(shí)體類比較少的時(shí)候卜壕,使用第一種方式
  • 如果實(shí)體類比較多,使用第二種方式
  • 還可以使用注解的方式結(jié)合第二種方式起別名:
@Alias("User) public class User{}

(五)烙常、設(shè)置(settings)

設(shè)置名 描述 有效值 默認(rèn)值
cacheEnabled 全局性地開啟或關(guān)閉所有映射器配置文件中已配置的任何緩存 true \ false true
lazyLoadingEnabled 延遲加載的全局開關(guān)轴捎。當(dāng)開啟時(shí),所有關(guān)聯(lián)對(duì)象都會(huì)延遲加載蚕脏。 特定關(guān)聯(lián)關(guān)系中可通過設(shè)置 fetchType 屬性來覆蓋該項(xiàng)的開關(guān)狀態(tài)侦副。 true \ false false
logImpl 指定 MyBatis 所用日志的具體實(shí)現(xiàn),未指定時(shí)將自動(dòng)查找 SLF4J \ LOG4J \ LOG4J2 \ JDK_LOGGING \ COMMONS_LOGGING \ STDOUT_LOGGING \ NO_LOGGING 未設(shè)置

(六)驼鞭、映射器(mappers)

MapperRegistry:注冊(cè)綁定我們的mapper文件
方式一: 使用相對(duì)于類路徑的資源引用 -

    <!--每一個(gè)Mapper.xml文件都需要到mybatis的配置文件下注冊(cè)-->
    <mappers>
        <mapper resource="com/vigil/dao/UserMapper.xml"></mapper>
    </mappers>

方式二: 使用class文件綁定注冊(cè)(使用映射器接口實(shí)現(xiàn)類的完全限定類名)

    <mappers>
        <mapper class="com.vigil.dao.UserMapper"></mapper>
    </mappers>

方式三: 使用掃描包進(jìn)行注入綁定(將包內(nèi)的映射器接口實(shí)現(xiàn)全部注冊(cè)為映射器)

    <mappers>
<!--        <mapper resource="com/vigil/dao/UserMapper.xml"></mapper>-->
<!--        <mapper class="com.vigil.dao.UserMapper"></mapper>-->
        <package name="com.vigil.dao"/>
    </mappers>

方式二和方式三必須的注意點(diǎn)

  • 接口和他的Mapper配置文件必須同名
  • 接口和他的Mapper配置文件必須在同一個(gè)包下

(七)秦驯、 生命周期和作用域

image

作用域、生命周期挣棕,是至關(guān)重要的译隘,因?yàn)殄e(cuò)誤的使用會(huì)導(dǎo)致非常嚴(yán)重的并發(fā)問題。

SqlSessionFactoryBuilder

  • 一旦創(chuàng)建了 SqlSessionFactory洛心,就不再需要它了
  • 局部方法變量

SqlSessionFactory

  • 可以想象為:數(shù)據(jù)庫連接池
  • SqlSessionFactory 一旦被創(chuàng)建就應(yīng)該在應(yīng)用的運(yùn)行期間一直存在固耘,沒有任何理由丟棄它或重新創(chuàng)建另一個(gè)實(shí)例。
  • 因此 SqlSessionFactory 的最佳作用域是應(yīng)用作用域
  • 最簡(jiǎn)單的就是使用單例模式或者靜態(tài)單例模式

SqlSession

  • 連接到連接池的一個(gè)請(qǐng)求
  • SqlSession 的實(shí)例不是線程安全的皂甘,因此是不能被共享的玻驻,所以它的最佳的作用域是請(qǐng)求或方法作用域
  • 用完之后需要趕緊關(guān)閉,否則資源被占用偿枕!


    image

這里面的每一個(gè)mapper璧瞬,就代表一個(gè)具體的業(yè)務(wù)




三、解決MyBatis_屬性名和字段名不一致

屬性名和字段名不一致導(dǎo)致查詢結(jié)果為空的問題

表中的字段名:
image

對(duì)應(yīng)的JavaBean實(shí)體類

public class User {
    private int id;
    private String name;
    private String password;
}

密碼的字段是不一致的
最后測(cè)試渐夸,返回的User對(duì)象的password屬性是空的

原因:列名不匹配

select * from mybatis.user where id = #{id}
--類型處理器
select id,name,pwd from mybatis.user where id = #{id}

解決方法:

(一)嗤锉、起別名(更改的是:sql語句)

MyBatis 會(huì)在幕后自動(dòng)創(chuàng)建一個(gè) ResultMap,再根據(jù)屬性名來映射列到 JavaBean 的屬性上墓塌。如果列名和屬性名不能匹配上瘟忱,可以在 SELECT 語句中設(shè)置列別名(這是一個(gè)基本的 SQL 特性)來完成匹配奥额。

    <select id="getUserById" parameterType="int" resultType="User">
        select id,name,pwd as password from mybatis.user where id = #{id}
    </select>

(二)、使用resultMap

上面沒有一個(gè)需要顯式配置 ResultMap访诱,完全可以不用顯式地配置它們垫挨。
顯式使用外部的 resultMap,是解決列名不匹配的另外一種方式触菜。

    <!--結(jié)果集映射-->
    <resultMap id="UserMap" type="User">
        <!--column數(shù)據(jù)庫中的字段九榔,property實(shí)體類中的屬性-->
        <result column="id" property="id"></result>
        <result column="name" property="name"></result>
        <result column="pwd" property="password"></result>
    </resultMap>

在引用它的語句中設(shè)置 resultMap 屬性就行了(注意去掉了 resultType 屬性)。

    <select id="getUserById" resultMap="UserMap">
        select id,name,pwd from mybatis.user where id = #{id}
    </select>

官方文檔_結(jié)果映射




四涡相、MyBatis日志簡(jiǎn)單使用

日志工廠

數(shù)據(jù)庫操作的錯(cuò)誤通過日志來查找是比較方便的

  • 過去:sout哲泊、debug
  • 現(xiàn)在:日志工廠

logImpl: 指定 MyBatis 所用日志的具體實(shí)現(xiàn),未指定時(shí)將自動(dòng)查找

  • SLF4J
  • LOG4J
  • LOG4J2
  • JDK_LOGGING
  • COMMONS_LOGGING
  • STDOUT_LOGGING
  • NO_LOGGING

使用日志工廠

  • 默認(rèn)情況下催蝗,日志工廠是 沒設(shè)置 的
  • 在MyBatis中具體使用哪一個(gè)日志切威,在核心配置文件中,配置
  • STDOUT_LOGGING標(biāo)準(zhǔn)日志輸出
    <!--STDOUT_LOGGING標(biāo)準(zhǔn)日志輸出-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
  • 日志輸出的重要信息

Opening JDBC Connection
Created connection 1263793464.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b53f538]
==> Preparing: select * from mybatis.user where id = ?
==> Parameters: 2(Integer)
<== Columns: id, name, pwd
<== Row: 2, 李四, 324332
<== Total: 1

User{id=2, name='李四', pwd='324332'}
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b53f538]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b53f538]
Returned connection 1263793464 to pool.

LOG4J

什么是LOG4J丙号?

  • log for Java:Java的日志
  • 使用Log4j可以控制日志信息輸送的目的地是控制臺(tái)先朦、文件、GUI組件
  • 可以控制每一條日志的輸出格式
  • 通過定義每一條日志信息的級(jí)別
  • 通過一個(gè)配置文件來靈活地進(jìn)行配置槽袄,而不需要修改應(yīng)用的代碼烙无。

使用LOG4J

1. 導(dǎo)入jar包

    <dependencies>
        <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>

2. log4j.properties

#將等級(jí)為DEBUG的日志信息輸出到console和file這兩個(gè)目的地锋谐,console和file的定義在下面的代碼
log4j.rootLogger=DEBUG,console,file

#控制臺(tái)輸出的相關(guān)設(shè)置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#文件輸出的相關(guān)設(shè)置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/vigil.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

#日志輸出級(jí)別
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

3. 配置log4j為日志的實(shí)現(xiàn)

    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>

4. 日志輸出重要信息

[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Opening JDBC Connection
[org.apache.ibatis.datasource.pooled.PooledDataSource]-Created connection 306206744.
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@12405818]
[com.vigil.dao.UserMapper.getUserById]-==> Preparing: select * from mybatis.user where id = ?
[com.vigil.dao.UserMapper.getUserById]-==> Parameters: 2(Integer)
[com.vigil.dao.UserMapper.getUserById]-<== Total: 1
User{id=2, name='李四', pwd='324332'}
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@12405818]
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@12405818]
[org.apache.ibatis.datasource.pooled.PooledDataSource]-Returned connection 306206744 to pool.

在類里的簡(jiǎn)單應(yīng)用

  1. 在要使用LOG4J的類中遍尺,導(dǎo)入包:import.org.apache.log4j.Logger;
  2. 日志對(duì)象,參數(shù)為當(dāng)前類的class
static Logger logger = Logger.getLogger(UserDaoText.class);
  1. 日志級(jí)別
logger.info("info");
logger.debug("debug");
logger.error("error");



五涮拗、MyBatis簡(jiǎn)單分頁

分頁作用:==減少數(shù)據(jù)的處理量==

(一)乾戏、 使用LImit分頁(物理分頁)

//語法:select * from 表名 limit startIndex,pageSize
select * from user limit 3; #[0,3)-->0,1,2,從0開始拿3個(gè)數(shù)據(jù)

使用MyBatis實(shí)現(xiàn)分頁三热,核心是sql語句

  1. 接口
    //分頁鼓择,查詢用戶,傳參是map就漾,壞處是不規(guī)范
    List<User> getUserByLimit(Map<String,Integer> map);
  1. Mapper.xml
    <!--結(jié)果集映射-->
    <resultMap id="UserMap" type="User">
        <!--column數(shù)據(jù)庫中的字段呐能,property實(shí)體類中的屬性-->
<!--        <result column="id" property="id"></result>-->
<!--        <result column="name" property="name"></result>-->
        <result column="pwd" property="password"></result>
    </resultMap>
    
    <select id="getUserByLimit" parameterType="map" resultMap="UserMap">
        select * from mybatis.user limit #{startIndex},#{pageSize}
    </select>
  1. 測(cè)試
    @Test
    public void testLimit() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        map.put("startIndex",0);
        map.put("pageSize",2);
        List<User> users = mapper.getUserByLimit(map);
        for(User user : users) {
            System.out.println(user);
        }
        sqlSession.close();
    }

(二)、使用RowBounds分頁(邏輯分頁)

  • 不使用sql實(shí)現(xiàn)分頁
  1. 接口
    //使用RowBounds分頁
    List<User> getUserByRowBounds();
  1. Mapper.xml
    <!--結(jié)果集映射-->
    <resultMap id="UserMap" type="User">
        <!--column數(shù)據(jù)庫中的字段抑堡,property實(shí)體類中的屬性-->
<!--        <result column="id" property="id"></result>-->
<!--        <result column="name" property="name"></result>-->
        <result column="pwd" property="password"></result>
    </resultMap>

    <select id="getUserByRowBounds" resultMap="UserMap">
        select * from mybatis.user
    </select>
  1. 測(cè)試
@Test
    public void getUserByRowBounds() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        //使用RowBounds實(shí)現(xiàn)
        RowBounds rowBounds = new RowBounds(1, 2);

        //使用Java代碼層面實(shí)現(xiàn)分頁
        List<User> userList = sqlSession.selectList("com.vigil.dao.UserMapper.getUserByRowBounds", null, rowBounds);

        for(User user : userList) {
            System.out.println(user);
        }
        sqlSession.close();
    }

limit 和 rowbounds 的區(qū)別

limit
limit.png
rowbounds
rowbounds.png

(三)摆出、PageHelper

(四)、面向接口編程

面向接口編程.png




六首妖、MyBatis復(fù)雜查詢_簡(jiǎn)單實(shí)現(xiàn)

復(fù)雜查詢環(huán)境搭建

數(shù)據(jù)庫文件

CREATE TABLE `teacher` (
  `id` INT(10) NOT NULL,
  `name` VARCHAR(30) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO teacher(`id`, `name`) VALUES (1, '魚佬'); 

CREATE TABLE `student` (
  `id` INT(10) NOT NULL,
  `name` VARCHAR(30) DEFAULT NULL,
  `tid` INT(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fktid` (`tid`),
  CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小紅', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小張', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1'); 
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');

項(xiàng)目搭建

  1. 導(dǎo)入mybatis
  2. 編寫資源文件
  3. 編寫mybatis核心配置文件
  • 引入外部資源文件:properties
  • 日志:settings
  • 起別名:typeAliases
  • 環(huán)境(數(shù)據(jù)庫資源):environments-->transactionManager偎漫、dataSource
  1. 編寫實(shí)體類
  2. 編寫Mapper接口
  3. 編寫Mapper.xml
  • mapper標(biāo)簽的命名空間:綁定接口
  • 選擇sql對(duì)應(yīng)的標(biāo)簽,綁定方法
  • 書寫sql語句
  1. 到MyBatis的核心配置文件中注冊(cè)mapper
  2. 測(cè)試

多對(duì)一處理(association)

查詢學(xué)生信息以及對(duì)應(yīng)老師的信息
思路: 1.查詢學(xué)生信息 有缆;2.根據(jù)tid查找相對(duì)應(yīng)的老師

一象踊、按照結(jié)果嵌套處理(類似聯(lián)表查詢)

    <select id="getStudentsByResult" resultMap="StudentWithTeacherByResult">
        select s.id sid,s.name sname,t.name tname,tid
        from mybatis.teacher t , mybatis.student s
        where t.id = s.tid
    </select>

    <resultMap id="StudentWithTeacherByResult" type="Student">
        <result property="id" column="sid"></result>
        <result property="name" column="sname"></result>
        <association property="teacher" javaType="Teacher">
            <result property="name" column="tname"></result>
            <result property="id" column="tid"></result>
        </association>
    </resultMap>

二温亲、按照查詢嵌套處理(類似子查詢)

    <select id="getStudents" resultMap="StudentWithTeacher">
        select * from mybatis.student
    </select>

    <select id="getTeacher" resultType="Teacher">
        select * from mybatis.teacher where id = #{tid}
    </select>

    <resultMap id="StudentWithTeacher" type="Student">
        <result property="id" column="id"></result>
        <result property="name" column="name"></result>
        <!--復(fù)雜的屬性,單獨(dú)處理杯矩,對(duì)象:association  集合:collection-->
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"></association>
    </resultMap>

一對(duì)多處理

一栈虚、按照結(jié)果嵌套處理(類似聯(lián)表查詢)

    <select id="getTeacherByResult" parameterType="int" resultMap="teacher">
        select s.id sid,s.name sname,t.id tid,t.name tname
        from mybatis.teacher t , mybatis.student s
        where t.id = s.tid and t.id = #{id}
    </select>

    <resultMap id="teacher" type="Teacher">
        <result property="id" column="tid"></result>
        <result property="name" column="tname"></result>

        <!--復(fù)雜的屬性,我們需要單獨(dú)處理  對(duì)象:association  集合:collection
        javaType=""指定的屬性的類型
        集合中的泛型信息史隆,使用ofType獲取
        -->
        <collection property="students" ofType="Student">
            <result property="id" column="sid"></result>
            <result property="name" column="sname"></result>
        </collection>
    </resultMap>

二节芥、按照查詢嵌套處理(類似子查詢)

    <select id="getTeacher" resultMap="TeacherWithStudent">
        select * from mybatis.teacher where id = #{id}
    </select>

    <select id="getStudent" resultType="Student">
        select * from mybatis.student where tid = #{id}
    </select>

    <resultMap id="TeacherWithStudent" type="Teacher">
        <result property="id" column="id"></result>
        <result property="name" column="name"></result>
        <collection property="students" column="id" javaType="List" ofType="Student" select="getStudent"></collection>
    </resultMap>

小結(jié)

resultMap.png
  1. 關(guān)聯(lián) - association【多對(duì)一】
  2. 集合 - collection【一對(duì)多】
  3. javaType:用來指定實(shí)體類中屬性的類型
  4. ofType:用來指定映射到List或者集合中的pojo類型,泛型中的約束類型

注意

  • 保證SQL的可讀性
  • 字段和屬性名問題
  • 日志查看



七逆害、MyBatis動(dòng)態(tài)SQL

  • 動(dòng)態(tài)SQL:根據(jù)不同的條件生成不同的SQL語句
  • 本質(zhì)還是sql語句头镊,但卻可以在sql層面上,執(zhí)行一個(gè)邏輯代碼

動(dòng)態(tài) SQL 元素和 JSTL 或基于類似 XML 的文本處理器相似魄幕。

  • if
  • choose(when相艇,otherwise)
  • trim(where,set)
  • foreach

環(huán)境搭建

  1. 數(shù)據(jù)庫
CREATE TABLE `blog`(
`id` VARCHAR(50) NOT NULL COMMENT '博客id',
`title` VARCHAR(100) NOT NULL COMMENT '博客標(biāo)題',
`author` VARCHAR(30) NOT NULL COMMENT '博客作者',
`create_time` DATETIME NOT NULL COMMENT '創(chuàng)建時(shí)間',
`views` INT(30) NOT NULL COMMENT '瀏覽量'
)ENGINE=INNODB DEFAULT CHARSET=utf8
  1. 新建工程

  2. 編寫資源文件

  3. 編寫MyBatis核心文件

  • 引入外部資源文件
  • 日志設(shè)置
  • 駝峰命名轉(zhuǎn)化設(shè)置
  • 起別名
  • 數(shù)據(jù)庫環(huán)境配置
  • 當(dāng)編寫好mapper要記得注冊(cè)
  1. 編寫工具類
  • 獲得SqlSession的工具類
  • 獲得隨機(jī)字符串的工具類
  1. 實(shí)體類:JavaBean

  2. 實(shí)體類接口

  3. 編寫對(duì)應(yīng)接口的mapper

  • namespace
  • 選擇對(duì)應(yīng)sql語句標(biāo)簽
  • 編寫sql語句
  1. 測(cè)試

IF

  1. 接口
   //查詢博客
    List<Blog> queryBlogIf(Map map);
  1. Mapper.xml
    <select id="queryBlogIf" parameterType="map" resultType="Blog">
        select * from mybatis.blog where 1 = 1
        <if test="title != null">
            and title = #{title}
        </if>
        <if test="author != null">
            and author = #{author}
        </if>
    </select>
  1. 測(cè)試
    @Test
    public void queryBlogIf() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

        HashMap map = new HashMap();
        map.put("title","會(huì)議廳");
        List<Blog> blogs = mapper.queryBlogIf(map);

        for(Blog blog : blogs) {
            System.out.println(blog);
        }
        sqlSession.close();
    }

choose(when纯陨,otherwise)

  • 類似switch語句
    <select id="queryBlogChoose" parameterType="map" resultType="Blog">
        select * from mybatis.blog
        <where>
            <choose>
                <when test="title != null">
                    title = #{title}
                </when>
                <when test="author != null">
                    author = #{author}
                </when>
                <otherwise>
                    views >= #{views}
                </otherwise>
            </choose>
        </where>
    </select>

trim(where坛芽,set)

  • where 標(biāo)簽,會(huì)識(shí)別追加語句的出現(xiàn)翼抠,是否過濾and或or
    這也說明了咙轩,追加語句最好都加上and或or
    <select id="queryBlogIf" parameterType="map" resultType="Blog">
        select * from mybatis.blog
        <where>
            <if test="title != null">
                and title = #{title}
            </if>
            <if test="author != null">
                and author = #{author}
            </if>
        </where>
    </select>
  • set標(biāo)簽,動(dòng)態(tài)設(shè)置set關(guān)鍵字阴颖,同時(shí)會(huì)刪掉無關(guān)的逗號(hào)(where語句前面的逗號(hào))
   <update id="updateBlog" parameterType="map">
        update mybatis.blog
        <set>
            <if test="title != null">
                title = #{title},
            </if>
            <if test="author != null">
                author = #{author},
            </if>
        </set>
        where id = #{id}
    </update>

自定義 trim 元素來定制 where 元素的功能活喊。比如,和 where 元素等價(jià)的自定義 trim 元素為

<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ...
</trim>

set 元素等價(jià)的自定義 trim 元素

<trim prefix="SET" suffixOverrides=",">
  ...
</trim>

SQL片段

這個(gè)元素可以用來定義可重用的 SQL 代碼片段量愧,以便在其它語句中使用钾菊。 參數(shù)可以靜態(tài)地(在加載的時(shí)候)確定下來,并且可以在不同的 include 元素中定義不同的參數(shù)值偎肃。

  • 將復(fù)用高的sql語句抽取出來放到一個(gè)標(biāo)簽里煞烫,在其他sql便簽中使用id關(guān)聯(lián)使用
  1. 使用sql便簽將其抽取
    <sql id="if-title-author">
        <if test="title != null">
            and title = #{title}
        </if>
        <if test="author != null">
            and author = #{author}
        </if>
    </sql>
  1. 使用include標(biāo)簽和sql便簽的id將其引用
    <select id="queryBlogIf" parameterType="map" resultType="Blog">
        select * from mybatis.blog
        <where>
            <include refid="if-title-author"></include>
        </where>
    </select>
  1. 注意:
  • 最好基于單表來定義SQL片段
  • 不要加上where或者set語句,因?yàn)槠涮厥?/li>

Foreach

動(dòng)態(tài) SQL :對(duì)集合進(jìn)行遍歷(尤其是在構(gòu)建 IN 條件語句的時(shí)候)累颂。

(1)指定一個(gè)集合滞详,聲明可以在元素體內(nèi)使用的集合項(xiàng)(item)和索引(index)變量。指定開頭與結(jié)尾的字符串以及集合項(xiàng)迭代之間的分隔符紊馏。這個(gè)元素也不會(huì)錯(cuò)誤地添加多余的分隔符料饥。

  • 注意: 可以將任何可迭代對(duì)象(如 List、Set 等)瘦棋、Map 對(duì)象或者數(shù)組對(duì)象作為集合參數(shù)傳遞給 foreach稀火。當(dāng)使用可迭代對(duì)象或者數(shù)組時(shí),index 是當(dāng)前迭代的序號(hào)赌朋,item 的值是本次迭代獲取到的元素凰狞。當(dāng)使用 Map 對(duì)象(或者 Map.Entry 對(duì)象的集合)時(shí)篇裁,index 是鍵,item 是值赡若。
    <select id="queryBlogForeach" parameterType="map" resultType="Blog">
        select * from mybatis.blog
        <where>
            <foreach collection="ids" item="id" open="and id in (" close=")" separator=",">
                #{id}
            </foreach>
        </where>
    </select>

==> Preparing: select * from mybatis.blog WHERE id in ( ? )
==> Parameters: 1(Integer)

動(dòng)態(tài)sql核心:拼接sql

保證正確性:sql語句最好先在數(shù)據(jù)庫測(cè)試成功了达布,再去拼接sql語句




八、MyBatis緩存_簡(jiǎn)單了解

簡(jiǎn)介(了解)

  1. 緩存(cache)是什么
  • 存在內(nèi)存中的臨時(shí)數(shù)據(jù)
  • 將用戶經(jīng)常查詢的數(shù)據(jù)放在緩存(內(nèi)存)中逾冬,用戶去查詢數(shù)據(jù)就不用從磁盤上(關(guān)系型數(shù)據(jù)庫數(shù)據(jù)文件)查詢黍聂,從緩存中查詢,從而提高查詢效率身腻,解決了高并發(fā)系統(tǒng)的性能問題
  1. 為什么使用緩存
  • 減少和數(shù)據(jù)庫的交互次數(shù)产还,減少系統(tǒng)開銷,提高系統(tǒng)效率
  1. 什么樣的數(shù)據(jù)使用緩存
  • 經(jīng)常查詢并且不經(jīng)常改變的數(shù)據(jù)

MyBatis緩存

  • MyBatis包含一個(gè)非常強(qiáng)大的查詢緩存特性嘀趟,可以非常方便地定制和配置緩存脐区。緩存可以極大的提升查詢xiaolv
  • MyBatis系統(tǒng)中默認(rèn)定義了兩級(jí)緩存:一級(jí)緩存和二級(jí)緩存
  1. 默認(rèn)情況下,只有一級(jí)緩存開啟(SqlSession級(jí)別的緩存她按,也稱為本地緩存)
  2. 二級(jí)緩存需要手動(dòng)開啟和配置牛隅,基于namespace級(jí)別的緩存
  3. 為了提高擴(kuò)展性,MyBatis定義了緩存接口Cache酌泰,通過實(shí)現(xiàn)Cache接口自定義二級(jí)緩存

一級(jí)緩存

  • 一級(jí)緩存也叫本地緩存:SqlSession
  • 與數(shù)據(jù)庫同一次會(huì)話期間查詢到的數(shù)據(jù)會(huì)放到本地緩存中
  • 下一次如果需要獲得相同的數(shù)據(jù)媒佣,則直接從緩存中拿,除非緩存中沒有才會(huì)去查詢數(shù)據(jù)庫

緩存失效的情況:

  1. 查詢不同的東西
  2. 增刪改操作陵刹,可能會(huì)改變?cè)瓉淼臄?shù)據(jù)默伍,必定會(huì)刷新緩存
  3. 查詢不同的Mapper.xml
  4. 手動(dòng)清理緩存

小結(jié):

一級(jí)緩存是默認(rèn)開啟的,只在一次SqlSession中有效授霸,也就是拿到數(shù)據(jù)庫連接到關(guān)閉數(shù)據(jù)庫連接的這個(gè)區(qū)間段(一級(jí)緩存就是一個(gè)Map)

二級(jí)緩存

  • 二級(jí)緩存也叫全局緩存巡验,一級(jí)緩存作用域太低
  • 基于namespace級(jí)別的緩存,一個(gè)名稱空間碘耳,對(duì)應(yīng)一個(gè)二級(jí)緩存
  • 工作機(jī)制:
  1. 一個(gè)會(huì)話查詢一條數(shù)據(jù),這個(gè)數(shù)據(jù)會(huì)被放在當(dāng)前會(huì)話的一級(jí)緩存中
  2. 如果當(dāng)前會(huì)話關(guān)閉了框弛,這個(gè)會(huì)話對(duì)應(yīng)的一級(jí)緩存就沒了辛辨,但是開啟二級(jí)緩存后,這個(gè)一級(jí)緩存中的數(shù)據(jù)就會(huì)保存到二級(jí)緩存中
  3. 新的會(huì)話查詢信息瑟枫,會(huì)到二級(jí)緩存中獲取信息(假如沒有就到一級(jí)緩存斗搞,還是沒有則查詢數(shù)據(jù)庫)
  4. 不同的mapper查出的數(shù)據(jù)會(huì)放到自己對(duì)應(yīng)的緩存(map)中

使用二級(jí)緩存的步驟

  1. 開啟全局緩存
<!--顯式的開啟全局緩存-->
<setting name="cacheEnabled" value="true"/>
  1. 在要使用二級(jí)緩存的Mapper中開啟
<!--在當(dāng)前Mapper.xml中使用二級(jí)緩存-->
<cache/>
  1. 自定義參數(shù)
<!--在當(dāng)前Mapper.xml中使用二級(jí)緩存-->
<cache  eviction="FIFO"
        flushInterval="60000"
        size="512"
        readOnly="true" />
  1. error
    實(shí)體類需要序列化

小結(jié):

  • 只要開啟了二級(jí)緩存,在同一個(gè)Mapper下就有效
  • 所有的數(shù)據(jù)都會(huì)先放在一級(jí)緩存中
  • 只有當(dāng)會(huì)話提交慷妙,或者關(guān)閉的時(shí)候僻焚,一級(jí)緩存中的數(shù)據(jù)才會(huì)提交到二級(jí)緩存中

緩存原理

緩存原理.png

基于內(nèi)存的數(shù)據(jù)庫:Redis實(shí)現(xiàn)緩存

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末月趟,一起剝皮案震驚了整個(gè)濱河市上荡,隨后出現(xiàn)的幾起案子样悟,更是在濱河造成了極大的恐慌饱溢,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,946評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狞山,死亡現(xiàn)場(chǎng)離奇詭異全闷,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)萍启,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,336評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門总珠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人勘纯,你說我怎么就攤上這事局服。” “怎么了驳遵?”我有些...
    開封第一講書人閱讀 169,716評(píng)論 0 364
  • 文/不壞的土叔 我叫張陵腌逢,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我超埋,道長(zhǎng)搏讶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,222評(píng)論 1 300
  • 正文 為了忘掉前任霍殴,我火速辦了婚禮媒惕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘来庭。我一直安慰自己妒蔚,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,223評(píng)論 6 398
  • 文/花漫 我一把揭開白布月弛。 她就那樣靜靜地躺著肴盏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪帽衙。 梳的紋絲不亂的頭發(fā)上菜皂,一...
    開封第一講書人閱讀 52,807評(píng)論 1 314
  • 那天,我揣著相機(jī)與錄音厉萝,去河邊找鬼恍飘。 笑死,一個(gè)胖子當(dāng)著我的面吹牛谴垫,可吹牛的內(nèi)容都是我干的章母。 我是一名探鬼主播,決...
    沈念sama閱讀 41,235評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼翩剪,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼乳怎!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起前弯,我...
    開封第一講書人閱讀 40,189評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤蚪缀,失蹤者是張志新(化名)和其女友劉穎秫逝,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體椿胯,經(jīng)...
    沈念sama閱讀 46,712評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡筷登,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,775評(píng)論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了哩盲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片前方。...
    茶點(diǎn)故事閱讀 40,926評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖廉油,靈堂內(nèi)的尸體忽然破棺而出惠险,到底是詐尸還是另有隱情,我是刑警寧澤抒线,帶...
    沈念sama閱讀 36,580評(píng)論 5 351
  • 正文 年R本政府宣布班巩,位于F島的核電站,受9級(jí)特大地震影響嘶炭,放射性物質(zhì)發(fā)生泄漏抱慌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,259評(píng)論 3 336
  • 文/蒙蒙 一眨猎、第九天 我趴在偏房一處隱蔽的房頂上張望抑进。 院中可真熱鬧,春花似錦睡陪、人聲如沸寺渗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,750評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽信殊。三九已至,卻和暖如春汁果,著一層夾襖步出監(jiān)牢的瞬間涡拘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,867評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工须鼎, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鲸伴,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,368評(píng)論 3 379
  • 正文 我出身青樓晋控,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親姓赤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子赡译,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,930評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容