Mybatis缓存机制

1. Mybatis缓存机制

如果两次(或者多次)执行的查询SQL相同,每次都要从磁盘中去读数据,速度是受磁盘IO的限制.
如果加入缓存,相同的sql只有第一次需要从磁盘中查询数据,并且把数据缓存到内存中,那么从第二次查询开始,程序就可以直接从内存中快速的拿到数据

1.1 一级缓存

一级缓存 默认开启 ,作用范围是当前的 sqlSession ,又被称为 本地缓存

    SqlSession sqlSession1 = null;
try {
        sqlSession1 = MybatisUtil.createSession();
        Student2 student1 = (Student2)
                sqlSession1.selectOne("student2.selectStudentById", 1);
        Student2 student2 = (Student2)
                sqlSession1.selectOne("student2.selectStudentById", 1);
        System.out.println(student1.hashCode()+":"+student2.hashCode());
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        MybatisUtil.closeSession(sqlSession1);
    }

在这里插入图片描述

1.2 二级缓存

@Test
public void testSelectById() {
    SqlSession sqlSession1 = null;
    try {
        sqlSession1 = MybatisUtil.createSession();
        Student2 student1 = (Student2)
                sqlSession1.selectOne("student2.selectStudentById", 1);
        Student2 student2 = (Student2)
                sqlSession1.selectOne("student2.selectStudentById", 1);
        System.out.println(student1.hashCode()+":"+student2.hashCode());
        System.out.println(student1);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        MybatisUtil.closeSession(sqlSession1);
    }
    SqlSession sqlSession2 = null;
    try {
        sqlSession2 = MybatisUtil.createSession();
        Student2 student3 = (Student2)
                sqlSession2.selectOne("student2.selectStudentById", 1);
        student3.setName("cache被更改了");
        Student2 student4 = (Student2)
                sqlSession2.selectOne("student2.selectStudentById", 1);
        System.out.println(student3.hashCode()+":"+student4.hashCode());
        System.out.println(student3);
        System.out.println(student4);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        MybatisUtil.closeSession(sqlSession2);
    }
}
    <!-- 开启二级缓存 -->
    <!--
    1.eviction:指定内存的淘汰/回收策略
        LRU(Least Recently Used 默认) – 最近最少使用:移除最长时间不被使用的对象。比较符合我们的预期的,因为缓存就是希望保留热点数据,淘汰非热点数据
        FIFO(First In First Out) – 先进先出:类似于队列,按对象进入缓存的顺序来移除它们。
        SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。
        WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。比软引用更弱
    2. flushInterval:刷新间隔,单位是毫秒.默认是不刷新
    3. size:缓存的数量的上限,默认值是1024.超过就会触发淘汰策略
    4. readOnly:只读,默认是false(可读可写)
        -false的情况,缓存的对象必须要实现序列化接口,这是因为拿到的缓存对象不是原本缓存的对象,是因为在false的情况下,Mybatis对缓存的对象进行了拷贝,拷贝需要序列化,这样的情况,因为涉及到序列化的操作,所以效率会更慢一些,但是更安全
        -true代表只读,就是拿到的缓存对象就是原本缓存的那个对象
    -->
    <cache eviction="LRU" flushInterval="60000" size="1024" readOnly="false"/>

额外补充:

二级缓存的size,按照数量进行缓存,但是会将一个列表的对象只占用1个数量,所以一般不会对列表数据的查询结果进行缓存,可以通过两种方式解决该问题:

  1. <select/> 标签的 useCache 属性,将它设置为 false (默认为true)

    将其设置为 true 后,将会导致本条语句的结果被二级缓存缓存起来,默认值:对 select 元素
    为 true。

  2. <select/> 标签的 flushCache 属性,对于 <select/> 标签而言默认为false,对于 <insert/>,<update/>,<delete/> 而言 flushCache 默认为true

    将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值