mybatis 之缓存机制

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybatis 之缓存机制相关的知识,希望对你有一定的参考价值。

1、缓存机制的简单介绍:


    a、MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。缓存可以极大的提升查询效率。

    

    b、MyBatis 系统中默认定义了两级缓存:

    一级缓存和二级缓存:

    -  默认情况下,只有一级缓存(SqlSession 级别的缓存,也称为本地缓存)开启。

    -  二级缓存需要手动开启和配置,它是基于 namespace 级别的缓存。

    -  为了提高扩展性。MyBatis 定义了缓存接口 Cache。我们可以通过实现 Cache 接口来自定义二级缓存。


2、一级缓存:

        

    a、一级缓存(local cache),即本地缓存,作用域默认是 sqlSession。一级缓存是一直开启的,无法关闭;是 sqlSession 级别的一个 Map 。

    与数据库同一次会话期间查询到的数据会放到本地缓存中。

    以后如果需要获取相同的数据,直接从缓存中拿,没有必要再去查询数据库。


技术分享

    注:可以看到上图的控制台输出结果,sql 语句只向数据库发送了一条,在相同的会话下(同一个 SqlSession,相同的查询条件),获取到的是同一个对象。


    b、一级缓存失效的四种情况:


    -  不同的 SqlSession 对应不同的一级缓存


技术分享

    注:可以看到,发送了两条 sql 语句,并且返回的 Employee 类的对象是两个不同的对象。


    -  同一个 SqlSession 但是查询条件不同


技术分享


    -  同一个 SqlSession 两次查询期间执行了任何一次增删改操作


技术分享

    

    -  同一个 SqlSession 两次查询期间手动清空了缓存


技术分享

    

3、二级缓存:(全局缓存)基于 namespace 级别的缓存,一个 namespase 对应一个二级缓存:


    a、工作机制:

    -  一个会话,查询一条数据,这个数据就会被放在当前会话的一级缓存中。

    -  如果会话结束,一级缓存中的数据会被保存在二级缓存中;新的会话查询信息,就可以参照二级缓存。

    -  不同的 namsespace 查询出的数据会放在自己对应的缓存中。(map)

   

    b、实际出现的效果:

    数据会从二级缓存中获取。查出的数据都会默认先放在一级缓存中,只有会话提交或者关闭以后,一级缓存中的数据才会转移到二级缓存中。


    c、使用的方式:


        -  开启全局配置文件(我的文件名叫做 mybatis-config.xml)配置:<setting name="cacheEnabled" value="true"/>(手动配置,即使默认配置的属性是 true,防止版本更新时带来的问题)


技术分享


       -  在 mapper.xml sql 映射文件中配置 <cache></cache>使用二级缓存。(所以说是基于

namespace 的缓存)

        cache 标签中相关属性的配置:


        -  eviction:缓存的回收策略

        *  LRU    -  最近最少使用的,移除最长时间不被使用的对象(默认)

        *  FIFO   -  先进先出:按对象进入缓存的顺序来移除它们

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

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


        -  flushInterval:缓存刷新间隔

        *  缓存多长时间清空一下,默认不清空,设置一个毫秒值


        -  readOnly:是否只读

        *  true 只读:mybatis 认为所有从缓存中获取数据的操作都是只读操作,不会修改数据。但是 mybatis 为了加快获取速度,直接就会将数据在缓存中的引用交给用户。(不安全,但速度快) 

        *  false 非只读:mybatis 认为获取的数据可能被修改。mybatis 会利用序列化和反序列化的技术克隆一份新的数据给你。安全,但是速度慢。(默认设置,javabean 类需要实现 Serializable 接口)

    

        - size:缓存中存放多少元素


        - type="":指定自定义缓存的全类名。(实现 Cache 接口即可)


    我们来看看示例的代码:


技术分享


技术分享


技术分享


    注:做了相关设置后,测试代码输出结果显示,只发送了一条 sql 语句,因为在 openSession 对象关闭后,mybatis 默认会先从二级缓存中取出数据。(因为底层是序列化和反序列化机制,所以返回的对象并不相同,但属性相同)

    在新的会话进入后,查询数据会先到二级缓存中查找,后到一级缓存中查找,最后才是数据库中查找。




    



本文出自 “12392717” 博客,请务必保留此出处http://12402717.blog.51cto.com/12392717/1932302

以上是关于mybatis 之缓存机制的主要内容,如果未能解决你的问题,请参考以下文章

聊聊MyBatis缓存机制

聊聊MyBatis缓存机制

Java框架之MyBatis 07-动态SQL-缓存机制-逆向工程-分页插件

MyBatis缓存机制-二级缓存

《深入理解mybatis原理4》 MyBatis缓存机制的设计与实现

Mybatis缓存机制