zoukankan      html  css  js  c++  java
  • 一次读懂mybatis中的缓存机制

    缓存功能针对于查询(没听说果UPDATE,INSERT语句要缓存什么,都是直接执行的)

    默认情况下,mybatis会启用一级缓存。

    如果使用同一个session对象调用了相同的SELECT语句,则直接会从缓存中返回结果,而不是再查询一次数据库。

    注意:session调用commit或close方法后,这个session中的一级缓存就会被清空

    例如: 根据日志输出可以看出,下面代码只会发出一条sql查询语句

    SqlSession sqlSession = MyBatisSqlSessionFactory.openSession();
    OneToManyMapper mapper = sqlSession.getMapper(OneToManyMapper.class);
    Tutor findTutorById1
    = mapper.findTutorById(1); System.out.println(findTutorById1); Tutor findTutorById2 = mapper.findTutorById(1); System.out.println(findTutorById2);

    日志文件输出:

    2019-10-16 19:15:39,870 [DEBUG] com.briup.mappers.OneToManyMapper.findTutorById - ==> Preparing: select * from tutors where tutor_id=?
    2019-10-16 19:15:39,999 [DEBUG] com.briup.mappers.OneToManyMapper.findTutorById - ==> Parameters: 1(Integer)
    2019-10-16 19:15:40,218 [DEBUG] com.briup.mappers.OneToManyMapper.findAddressById - ====> Preparing: select * from addresses where addr_id = ?
    2019-10-16 19:15:40,218 [DEBUG] com.briup.mappers.OneToManyMapper.findAddressById - ====> Parameters: 1(Integer)
    2019-10-16 19:15:40,220 [DEBUG] com.briup.mappers.OneToManyMapper.findAddressById - <==== Total: 1
    2019-10-16 19:15:40,221 [DEBUG] com.briup.mappers.OneToManyMapper.findCoursesByTutor - ====> Preparing: select * from courses where tutor_id=?
    2019-10-16 19:15:40,221 [DEBUG] com.briup.mappers.OneToManyMapper.findCoursesByTutor - ====> Parameters: 1(Integer)
    2019-10-16 19:15:40,226 [DEBUG] com.briup.mappers.OneToManyMapper.findCoursesByTutor - <==== Total: 2
    2019-10-16 19:15:40,226 [DEBUG] com.briup.mappers.OneToManyMapper.findTutorById - <== Total: 1

    Tutor [tutorId=1, name=null, email=zs@briup.com, phone=PhoneNumber [countryCode=123, stateCode=456, number=7890], address=Address [addrId=1, street=redSt, city=kunshan, state=W, zip=12345, country=china], courses=[Course [courseId=1, name=JavaSE, description=JavaSE, startDate=Thu Jan 10 00:00:00 CST 2019, endDate=Sun Feb 10 00:00:00 CST 2019], Course [courseId=3, name=MyBatis, description=MyBatis, startDate=Thu Jan 10 00:00:00 CST 2019, endDate=Wed Feb 20 00:00:00 CST 2019]]]

    Tutor [tutorId=1, name=null, email=zs@briup.com, phone=PhoneNumber [countryCode=123, stateCode=456, number=7890], address=Address [addrId=1, street=redSt, city=kunshan, state=W, zip=12345, country=china], courses=[Course [courseId=1, name=JavaSE, description=JavaSE, startDate=Thu Jan 10 00:00:00 CST 2019, endDate=Sun Feb 10 00:00:00 CST 2019], Course [courseId=3, name=MyBatis, description=MyBatis, startDate=Thu Jan 10 00:00:00 CST 2019, endDate=Wed Feb 20 00:00:00 CST 2019]]]

    从以上日志可以分析出来,这个select语句只发了一次,第二次的查询用的是第一次查询的缓存

    二级缓存: 在不同的session对象之间可以共享缓存的数据
    1.mybatis-config.xml文件中保证<setting name="cacheEnabled" value="true"/>设置中是缓存功能是开启的,默认就是开启的true
    2.在需要二级缓存的xml映射文件中,手动开启缓存功能,在根元素中加入一个标签即可:<cache/>
    3.一个session查询完数据之后,需要调用commit或者close方法后,这个数据才会进入到二级缓存中,然后其他session就可以共享到这个缓存数据了

    注意:默认情况下,被二级缓存保存的对象需要实现序列化接口。

    例如:
    mybatis-config.xml:

    <settings>
    <setting name="cacheEnabled" value="true"/>
    </settings>

    xml映射文件:

    <mapper namespace="com.briup.mappers.SpecialMapper">
    <cache/>
    <select> ..</select>
    <select> ..</select>
    <select> ..</select>
    </mapper>

    测试代码:

    @Test
    public void test_cache2(){
    SqlSession session1 = null;
    SqlSession session2 = null;
    try {
    session1 = MyBatisSqlSessionFactory.openSession();
    session2 = MyBatisSqlSessionFactory.openSession();
    
    SpecialMapper mapper1 = session1.getMapper(SpecialMapper.class);
    SpecialMapper mapper2 = session2.getMapper(SpecialMapper.class);
    
    User user1 = mapper1.findUserById(56);
    System.out.println(user1);
    session1.commit();
    
    User user2 = mapper2.findUserById(56);
    System.out.println(user2);
    session2.commit();
    } catch (Exception e) {
    e.printStackTrace();
    }finally {
    if(session1!=null)session1.close();
    if(session2!=null)session2.close();
    }
    }

    日志文件输出:

    2019-10-16 19:29:22,443 [DEBUG] com.briup.mappers.OneToManyMapper - Cache Hit Ratio [com.briup.mappers.OneToManyMapper]: 0.0
    2019-10-16 19:29:23,449 [DEBUG] com.briup.mappers.OneToManyMapper.findTutorById - ==> Preparing: select * from tutors where tutor_id=?
    2019-10-16 19:29:23,648 [DEBUG] com.briup.mappers.OneToManyMapper.findTutorById - ==> Parameters: 1(Integer)
    2019-10-16 19:29:23,805 [DEBUG] com.briup.mappers.OneToManyMapper - Cache Hit Ratio [com.briup.mappers.OneToManyMapper]: 0.0
    2019-10-16 19:29:23,805 [DEBUG] com.briup.mappers.OneToManyMapper.findAddressById - ====> Preparing: select * from addresses where addr_id = ?
    2019-10-16 19:29:23,806 [DEBUG] com.briup.mappers.OneToManyMapper.findAddressById - ====> Parameters: 1(Integer)
    2019-10-16 19:29:23,808 [DEBUG] com.briup.mappers.OneToManyMapper.findAddressById - <==== Total: 1
    2019-10-16 19:29:23,808 [DEBUG] com.briup.mappers.OneToManyMapper - Cache Hit Ratio [com.briup.mappers.OneToManyMapper]: 0.0
    2019-10-16 19:29:23,809 [DEBUG] com.briup.mappers.OneToManyMapper.findCoursesByTutor - ====> Preparing: select * from courses where tutor_id=?
    2019-10-16 19:29:23,809 [DEBUG] com.briup.mappers.OneToManyMapper.findCoursesByTutor - ====> Parameters: 1(Integer)
    2019-10-16 19:29:23,814 [DEBUG] com.briup.mappers.OneToManyMapper.findCoursesByTutor - <==== Total: 2
    2019-10-16 19:29:23,814 [DEBUG] com.briup.mappers.OneToManyMapper.findTutorById - <== Total: 1

    Tutor [tutorId=1, name=null, email=zs@briup.com, phone=PhoneNumber [countryCode=123, stateCode=456, number=7890], address=Address [addrId=1, street=redSt, city=kunshan, state=W, zip=12345, country=china], courses=[Course [courseId=1, name=JavaSE, description=JavaSE, startDate=Thu Jan 10 00:00:00 CST 2019, endDate=Sun Feb 10 00:00:00 CST 2019], Course [courseId=3, name=MyBatis, description=MyBatis, startDate=Thu Jan 10 00:00:00 CST 2019, endDate=Wed Feb 20 00:00:00 CST 2019]]]

    2019-10-16 19:29:23,825 [DEBUG] com.briup.mappers.OneToManyMapper - Cache Hit Ratio [com.briup.mappers.OneToManyMapper]: 0.25

    Tutor [tutorId=1, name=null, email=zs@briup.com, phone=PhoneNumber [countryCode=123, stateCode=456, number=7890], address=Address [addrId=1, street=redSt, city=kunshan, state=W, zip=12345, country=china], courses=[Course [courseId=1, name=JavaSE, description=JavaSE, startDate=Thu Jan 10 00:00:00 CST 2019, endDate=Sun Feb 10 00:00:00 CST 2019], Course [courseId=3, name=MyBatis, description=MyBatis, startDate=Thu Jan 10 00:00:00 CST 2019, endDate=Wed Feb 20 00:00:00 CST 2019]]]

    可以看出,sqlSession2这个对象第二次查询的时候,命中了缓存

    2019-10-16 19:29:23,825 [DEBUG] com.briup.mappers.OneToManyMapper - Cache Hit Ratio [com.briup.mappers.OneToManyMapper]: 0.25(缓存命中率0.25)

    二级缓存补充说明
      1. 映射语句文件中的所有select语句将会被缓存
      2. 映射语句文件中的所有insert,update和delete语句会刷新缓存
      3. 缓存会使用Least Recently Used(LRU,最近最少使用的)算法来收回。
      4. 缓存会根据指定的时间间隔来刷新。
      5. 缓存会存储1024个对象

    cache标签常用属性:
    <cache
    eviction="FIFO" <!--回收策略为先进先出-->
    flushInterval="60000" <!--自动刷新时间60s-->
    size="512" <!--最多缓存512个引用对象-->
    readOnly="true"/> <!--true表示对象不能被写出去,即不可以被序列化,false表示可以写出去,即可以被序列化,默认值是false-->

  • 相关阅读:
    树的直径的两种求法
    2018CCPC吉林赛区(重现赛)部分题解
    2019中国大学生程序设计竞赛-女生专场(重现赛)部分题解C-Function(贪心+优先队列) H-clock(模拟)
    HDU-1693 Eat the Trees(插头DP)
    【巷子】---redux---【react】
    【巷子】---flux---【react】
    【JavaScript算法】---希尔排序
    【JavaScript算法】---快速排序法
    【JavaScript算法】---插入排序
    【深拷贝VS浅拷贝】------【巷子】
  • 原文地址:https://www.cnblogs.com/Magic-Li/p/11687818.html
Copyright © 2011-2022 走看看