mybatis一级缓存和二级缓存

1.一级缓存

Mybatis默认开启一级缓存,不需要我们额外配置。

一级缓存的对象为SqlSession对象,每个SqlSession对象都有缓存区,同一个SqlSession对象获取到的mapper映射器多次执行相同的查询只会对数据库查询一次

一级缓存清空的时机:对数据库执行,增/删/改/事务提交(commit())/关闭close()时,一级缓存清空

2.二级缓存

Mybatis二级缓存的开启需要我们手动配置,二级缓存的对象为SqlSessionFactory,它存在于处理器的高速缓存(cache)中,注意:二级缓存的时数据,而不是对象,sqlSession取到数据后,会调用构造方法创建新的对象,然后把数据封装到对象中,所以我们得到的对象,地址不同。

  1. mybatis核心配置文件

    1. <settings>
              <setting name="cacheEnabled" value="true"/>
      </settings>
      
  2. 映射文件中声明

    1. <cache/>
      
  3. 映射文件中方法声明

    1. <select id="selectAll" resultType="user" useCache="true">
              select * from myb_test
      </select>
      

3.案例

查询数据中所有的用户,从而观察一级缓存和二级缓存

log4j日志文件:log4j日志是为了方便我们对数据库方法进行观察

  • maven

    • <dependencies>
              <dependency>
                  <groupId>org.mybatis</groupId>
                  <artifactId>mybatis</artifactId>
                  <version>3.5.7</version>
              </dependency>
              <dependency>
                  <groupId>org.projectlombok</groupId>
                  <artifactId>lombok</artifactId>
                  <version>1.18.22</version>
              </dependency>
              <dependency>
                  <groupId>mysql</groupId>
                  <artifactId>mysql-connector-java</artifactId>
                  <version>8.0.27</version>
              </dependency>
      
              <dependency>
                  <groupId>log4j</groupId>
                  <artifactId>log4j</artifactId>
                  <version>1.2.17</version>
              </dependency>
      </dependencies>
      
  • User.class

    • @Data
      @ToString
      public class User implements Serializable {
          private int id;
          private String name;
          private int age;
          private Date birthday;
      }
      
      
  • UserDao.class

    • public interface UserDao {
          /**
           * 查询所有用户
           * @return
           */
          List<User> selectAll();
      }
      
      
  • UserMapper.xml

    • <?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">
      <mapper namespace="com.z.dao.UserDao">
      <!--    二级缓存需要声明的配置2-->
      <!--    <cache/>-->
      
      <!--    二级缓存需要在方法上开启的配置3-->
      <!--    <select id="selectAll" resultType="user" useCache="true">-->
          <select id="selectAll" resultType="user" >
              select * from myb_test
          </select>
      
      </mapper>
      
  • mybatis-config.xml

    • <?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>
      <!--    二级缓存需要开启的核心设置1-->
      <!--    <settings>-->
      <!--        <setting name="cacheEnabled" value="true"/>-->
      <!--    </settings>-->
          <typeAliases>
              <package name="com.z.dto"/>
          </typeAliases>
          <environments default="development">
              <environment id="development">
                  <transactionManager type="JDBC"></transactionManager>
                  <dataSource type="POOLED">
                      <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                      <property name="url" value="jdbc:mysql://localhost:3307/train"/>
                      <property name="username" value="root"/>
                      <property name="password" value="520.hate"/>
                  </dataSource>
              </environment>
          </environments>
          <mappers>
              <mapper resource="mapper/UserMapper.xml"/>
          </mappers>
      </configuration>
      
  • 测试类

    • public class UserDaoTest {
          private SqlSessionFactory factory = null;
          private InputStream in = null;
          @Before
          public void init() throws IOException {
              in = Resources.getResourceAsStream("mybatis-config.xml");
              factory = new SqlSessionFactoryBuilder().build(in);
          }
      
          /**
           * 二级缓存测试
           */
          @Test
          public void secondCache(){
              SqlSession sqlSession1 = factory.openSession();
              SqlSession sqlSession2 = factory.openSession();
              SqlSession sqlSession3 = factory.openSession();
              sqlSession1.getMapper(UserDao.class).selectAll();
              sqlSession1.close(); //注意这里要close()清空一级缓存
              sqlSession2.getMapper(UserDao.class).selectAll();
              sqlSession2.close();//注意这里要close()清空一级缓存
              sqlSession3.getMapper(UserDao.class).selectAll();
              sqlSession3.close();//注意这里要close()清空一级缓存
          }
      
          /**
           * 一级缓存测试
           */
          @Test
          public void firstCache(){
              SqlSession sqlSession = factory.openSession();
              UserDao userDao = sqlSession.getMapper(UserDao.class);
              List<User> users1 = userDao.selectAll();
              List<User> users2 = userDao.selectAll();
              System.out.println(users1 == users2);
          }
          @After
          public void destroy() throws IOException {
              in.close();
          }
      }
      
  • log4j.xml

    • # Set root category priority to INFO and its only appender to CONSOLE.
      #log4j.rootCategory=INFO, CONSOLE            debug   info   warn error fatal
      log4j.rootCategory=debug, CONSOLE, LOGFILE
      
      # Set the enterprise logger category to FATAL and its only appender to CONSOLE.
      log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
      
      # CONSOLE is set to be a ConsoleAppender using a PatternLayout.
      log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
      log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
      log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
      
      # LOGFILE is set to be a File appender using a PatternLayout.
      log4j.appender.LOGFILE=org.apache.log4j.FileAppender
      log4j.appender.LOGFILE.File=D:\log
      log4j.appender.LOGFILE.Append=true
      log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
      log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
      

一级缓存测试:

在这里插入图片描述

从结果可以看出,两次查询只对数据库访问一次,且user2 == user1 结果为true,说明第二次查询是从sqlSession缓存中取数据的。

二级缓存测试:

在这里插入图片描述

虽然我们时使用sqlSession1,sqlSession2,sqlSession3对象都执行一次查询,但是从日志上可以看到,对数据库只执行了一次查询,说明第二和第三次查询操作都是从二级缓存之中获取数据的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值