MyBatis入门之二级缓存

心不动则不痛 提交于 2020-03-05 23:55:40

        mybatis的二级缓存是namespace级别的,不同于一级缓存,二级缓存是SqlSession共享的,并且默认是不开启的,如果要开启,需要在mybatis的配置文件中的settings节点下,手动设置:

        <!-- 开启二级缓存,默认是false -->
        <setting name="cacheEnabled" value="true"></setting>

由于示例代码与之前的博客:  MyBatis入门之一级缓存   基本相同,所以不贴重复的代码了,不同之处就是:

(1)mybatis-config.xml开启二级缓存

        <!-- 开启二级缓存,默认是false -->
        <setting name="cacheEnabled" value="true"></setting>

(2)UserMapper.xml中设置二级缓存的各种属性

    <!-- 设置二级缓存 -->
    <cache eviction="FIFO"
           flushInterval="60000"
           size="512"
           readOnly="true"/>

你也可以直接使用,表示都使用默认值

<cache/>

各个属性的意思(摘自mybatis官网):

这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。

可用的清除策略有:

  • LRU – 最近最少使用:移除最长时间不被使用的对象。
  • FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
  • SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。
  • WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。

默认的清除策略是 LRU。

flushInterval(刷新间隔)属性可以被设置为任意的正整数,设置的值应该是一个以毫秒为单位的合理时间量。 默认情况是不设置,也就是没有刷新间隔,缓存仅仅会在调用语句时刷新。

size(引用数目)属性可以被设置为任意正整数,要注意欲缓存对象的大小和运行环境中可用的内存资源。默认值是 1024。

readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓存对象的相同实例。 因此这些对象不能被修改。这就提供了可观的性能提升。而可读写的缓存会(通过序列化)返回缓存对象的拷贝。 速度上会慢一些,但是更安全,因此默认值是 false。

提示 二级缓存是事务性的。这意味着,当 SqlSession 完成并提交时,或是完成并回滚,但没有执行 flushCache=true 的 insert/delete/update 语句时,缓存会获得更新

(3)实体类User要实现序列化接口Serializable

 

2.测试类:

public class SecondLevelCache {
    public static void main(String[] args) throws IOException {
        //读取配置信息
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        //根据配置信息,创建SqlSession工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        //SqlSession工厂创建SqlSession
        SqlSession sqlSession = factory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        System.out.println("----------第一次查询开始-----------");
        User user = mapper.getUserById("123");
        System.out.println(user);
        System.out.println("----------第一次查询结束-----------");
        //一定要先关闭第一个SqlSession,不然二级缓存不起作用,暂时也不知道为什么
        sqlSession.close();

        //第二个SqlSession
        SqlSession sqlSession2 = factory.openSession();
        UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
        System.out.println("----------第二次查询开始-----------");
        User user2 = mapper2.getUserById("123");
        System.out.println(user2);
        System.out.println("----------第二次查询结束-----------");

        sqlSession2.close();

    }
}

测试结果:

可以看到,第二次查询没有发出sql语句,并且两个查询使用的SqlSession是不同的,说明了二级缓存是SqlSession共享的。

注意点:一定要先关闭第一个SqlSession,不然二级缓存不起作用,暂时也不知道为什么,有知道的朋友可以留言,不胜感激

        sqlSession.close();

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!