MyBatis总结八:缓存介绍(一级缓存,二级缓存)

简介

为数据库的查询进行缓存,是减少数据库压力的主要途径。分为一级缓存和二级缓存。

一级缓存:session级别缓存,作用于当前会话。

二级缓存:SessionFactory级别缓存,作用于整个SessionFactory,多个会话之间可以共享缓存

 

一级缓存:

特点:

  • mybatis的一级缓存默认就是开启的,并且无法关闭。

  • mybatis的一级缓存作用域是当前session,一次openSession()后,如果相同的statement和相同参数,则不进行查询而是从缓存命中并且返回,如果没有命中则查询数据库。

  • 任何的增删改操作都会导致缓存被清空

  • 缓存会使用 Least Recently Used(LRU,最近最少使用的)算法来收回

测试一级缓存:

    @Test
    public void testLevelOneCache() throws Exception {
        User user1 = mapper.getUserById(1);
        System.out.println(user1);
        System.out.println("---------------------------");
        User user2 = mapper.getUserById(1);
        System.out.println(user2);
    }

输出结果:

我们可以看出来 第二次查询的时候 并没有执行sql语句 而是从缓存中读取的。

 

二级缓存:

特点:

  • 二级缓存需要手动开启,开启的方式是在Mapper.xml中添加标签:<cache/>

  • 二级缓存的作用域是整个SessionFactory,并且是同一个Mapper中,如果namespace、statement和SQL参数一致,则缓存命中

  • 映射语句文件中的所有select语句将会被缓存。

  • 映射语句文件中的所有insert,update和delete语句会刷新缓存。

  • 缓存会使用Least Recently Used(LRU,最近最少使用的)算法来收回。

  • 缓存会根据指定的时间间隔来刷新。

  • 缓存默认会存储1024个对象

开启二级缓存:

<mapper namespace="com.zy.mapper.UserMapper">
    <!--开启二级缓存-->
    <cache />

测试二级缓存:

注意这里有个前提条件,就是User类必须继承Serializable接口

public class UserMapperTest {
    UserMapper mapper;
    SqlSessionFactory sqlSessionFactory;
    SqlSession sqlSession;

    @Before
    public void setUp() throws Exception {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        sqlSession = sqlSessionFactory.openSession(true);
        mapper = sqlSession.getMapper(UserMapper.class);
    }

    @Test
    public void testLevelTwoCache() {
        // 一次会话中
        // 1 第1次查询
        User user1 = mapper.getUserById(1);
        System.out.println(user1);

        // 关闭session
        sqlSession.close();
        // 重新开启session
        sqlSession = sqlSessionFactory.openSession(true);
        // 重新获取mapper
        mapper = sqlSession.getMapper(UserMapper.class);
        System.out.println("------------------------------------------");

        // 2 第2次查询
        User user2 = mapper.getUserById(1);
        System.out.println(user2);
    }

}

cache标签常用属性:

<cache 
eviction="FIFO"  <!--回收策略为先进先出-->
flushInterval="60000" <!--自动刷新时间60s-->
size="512" <!--最多缓存512个引用对象-->
readOnly="true"/> <!--只读-->

 

这个更高级的配置创建了一个 FIFO 缓存,并每隔 60 秒刷新,存数结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会 导致冲突。

可用的收回策略有:

  • LRU – 最近最少使用的:移除最长时间不被使用的对象。

  • FIFO – 先进先出:按对象进入缓存的顺序来移除它们。

  • SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。

  • WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

默认的是 LRU。

flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒 形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。

size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的 可用内存资源数目。默认值是 1024。

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

 

另外mybatis-config.xml中的settings中有个参数叫做cacheEnabled,默认为true表示开启缓存,如果设置为flase所有的缓存将消失。

 

posted @ 2017-04-08 21:45  青衫仗剑  阅读(504)  评论(0编辑  收藏  举报