一、MyBatis缓存介绍

  MyBatis 提供了一级缓存二级缓存的支持

       1. 一级缓存: 默认开启,基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Session,当 Session flush  close 之后,该Session中的所有Cache就将清空。在同一个SqlSession中,执行相同的查询SQL,第一次会去查询数据库,并写到缓存中;第二次直接从缓存中取。当执行SQL时两次查询中间发生了增删改操作,则SqlSession的缓存清空。

注意:

每次查询会先去缓存中找,如果找不到,再去数据库查询,然后把结果写到缓存中。Mybatis的内部缓存使用一个HashMap,key为hashcode+statementId+sql语句。Value为查询出来的结果集映射成的java对象。

SqlSession执行insert、update、delete等操作commit后会清空该SQLSession缓存。

  2. 二级缓存:需要手动开启,与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。在同一个namespace下的mapper文件中,执行相同的查询SQL,第一次会去查询数据库,并写到缓存中;第二次直接从缓存中取。当执行SQL时两次查询中间发生了增删改操作,则二级缓存清空。

注意:

二级缓存是mapper级别的。Mybatis默认是没有开启二级缓存。

第一次调用mapper下的SQL去查询用户信息。查询到的信息会存到该mapper对应的二级缓存区域内。

第二次调用相同namespace下的mapper映射文件中相同的SQL去查询用户信息。会去对应的二级缓存内取结果。

如果调用相同namespace下的mapper映射文件中的增删改SQL,并执行了commit操作。此时会清空该namespace下的二级缓存。

  3. 对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存Namespaces)的进行了 C/U/D(增删改) 操作后,默认该作用域下所有 select 中的缓存将被clear。

二、开启二级缓存示例

1、  在核心配置文件SqlMapConfig.xml中加入以下内容(开启二级缓存总开关)

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

2、在映射文件中,加入以下内容,开启二级缓存

 <mapper namespace="me.gacl.mapping.userMapper">
<!-- 开启二级缓存 -->
<cache/>

字面上看就是这样。这个简单语句的效果如下:

  • 映射语句文件中的所有 select 语句将会被缓存。
  • 映射语句文件中的所有 insert,update 和 delete 语句会刷新缓存。
  • 缓存会使用 Least Recently Used(LRU,最近最少使用的)算法来收回。
  • 根据时间表(比如 no Flush Interval,没有刷新间隔), 缓存不会以任何时间顺序 来刷新。
  • 缓存会存储列表集合或对象(无论查询方法返回什么)的 1024 个引用。
  • 缓存会被视为是 read/write(可读/可写)的缓存,意味着对象检索不是共享的,而 且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

所有的这些属性都可以通过缓存元素的属性来修改。比如:

 <cache
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>

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

可用的收回策略有:

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

默认的是 LRU。

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

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

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

3、实现序列化

由于二级缓存的数据不一定都是存储到内存中,它的存储介质多种多样,所以需要给缓存的对象(实体类)执行序列化。

如果该类存在父类,那么父类也要实现序列化。

4、禁用二级缓存和刷新二级缓存

禁用二级缓存:该statement中设置userCache=false可以禁用当前select语句的二级缓存,即每次查询都是去数据库中查询,默认情况下是true,即该statement使用二级缓存。

 <select id="findUserByName" parameterType="java.lang.String" resultType="com.study.mybatis.model.UserModel" userCache="false" >
select * from t_user where username LIKE '%${value}%'
</select>

刷新二级缓存:

 <select id="findUserByName" parameterType="java.lang.String" resultType="com.study.mybatis.model.UserModel" flushCache="true" >
select * from t_user where username LIKE '%${value}%'
</select>

三、使用自定义缓存

除了这些自定义缓存的方式,你也可以通过实现你自己的缓存或为其他第三方缓存方案 创建适配器来完全覆盖缓存行为。

 <cache type="com.domain.something.MyCustomCache"/>

这个示 例展示了如何使用 一个 自定义的缓存实 现。type 属性指定的类必须实现org.mybatis.cache.Cache 接口。这个接口是MyBatis 框架中很多复杂的接口之一,但是简单给定它做什么就行。

 public interface Cache {
String getId();
int getSize();
void putObject(Object key, Object value);
Object getObject(Object key);
boolean hasKey(Object key);
Object removeObject(Object key);
void clear();
ReadWriteLock getReadWriteLock();
}

缓存配置和缓存实例是绑定在 SQL 映射文件的命名空间的。因此,所有在相同命名空间的语句正如绑定的缓存一样。 语句可以修改和缓存交互的方式,或在语句的基础上使用两种简单的属性来完全排除它们。默认情况下,语句可以这样来配置:

 <select ... flushCache="false" useCache="true"/>
<insert ... flushCache="true"/>
<update ... flushCache="true"/>
<delete ... flushCache="true"/>

因为那些是默认的,你明显不能明确地以这种方式来配置一条语句。相反,如果你想改变默认的行为,只能设置flushCache和useCache属性。比如,在一些情况下你也许想排除从缓存中查询特定语句结果,或者你也许想要一个查询语句来刷新缓存。相似地,你也许有一些更新语句依靠执行而不需要刷新缓存。

Mybatis系列(四):Mybatis缓存的更多相关文章

  1. MyBatis系列四 之 智能标签进行查询语句的拼接

    MyBatis系列四 之 智能标签进行查询语句的拼接 使用Foreach进行多条件查询 1.1 foreach使用数组进行多条件查询 在MyBatis的映射文件中进行如下配置 <!--根据数组进 ...

  2. mybatis系列-15-查询缓存

    15.1     什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 一级缓存是SqlSession级别的缓存.在操作数据库时需要 ...

  3. 深入浅出Mybatis系列四-配置详解之typeAliases别名(mybatis源码篇)

    注:本文转载自南轲梦 注:博主 Chloneda:个人博客 | 博客园 | Github | Gitee | 知乎 上篇文章<深入浅出Mybatis系列(三)---配置详解之properties ...

  4. mybatis学习系列四--mybatis generator逆向工程

    采用命令行方式执行逆向工程 1.配置文件generatorConfig.xml 保存在目录:D:\E\workspace\eclipse\mybatis_generator <?xmlversi ...

  5. 深入浅出Mybatis系列一-Mybatis入门

    注:本文转载自南轲梦 注:博主 Chloneda:个人博客 | 博客园 | Github | Gitee | 知乎 最近两年 springmvc + mybatis 的在这种搭配还是蛮火的,楼主我呢, ...

  6. mybatis学习四 mybatis的三种查询方式

    <select id="selAll" resultType="com.caopeng.pojo.Flower"> select * from fl ...

  7. 深入迁出mybatis系列

    本系列教程均源于南柯梦,经好库文摘转发,感谢南柯梦的辛苦整理. 深入迁出mybatis系列 深入浅出Mybatis系列(一)---Mybatis入门 深入浅出Mybatis系列(二)---配置简介(m ...

  8. Mybatis系列全解(四):全网最全!Mybatis配置文件XML全貌详解

    封面:洛小汐 作者:潘潘 做大事和做小事的难度是一样的.两者都会消耗你的时间和精力,所以如果决心做事,就要做大事,要确保你的梦想值得追求,未来的收获可以配得上你的努力. 前言 上一篇文章 <My ...

  9. Mybatis系列(四)映射文件

    转自:https://blog.csdn.net/chris_mao/article/details/48811507 Mybatis的真正强大,在于她对SQL的映射,这也是她吸引人的地方.实现相同的 ...

随机推荐

  1. Oracle客户端使用sqlldr导数据中文乱码问题解决方法

    String strctl = "OPTIONS (skip=0)" + // 0是从第一行开始 1是 从第二行 CHARACTERSET AL32UTF8 是为了解决导入中文为乱 ...

  2. Linux系统Apache服务 - 配置 HTTP 的虚拟机主机

    接Linux系统Apache服务 - 配置HTTP的默认主页 1.创建/srv目录,作为httpd的文件目录,并创建/srv/default/www和/srv/www1.example.com/www ...

  3. NGUI的UISprite动态染色的一种方法

    本文主要参考iwinterice 的 NGUI的UISprite动态染色的一种解决方案 文章. 参考参考,就是既参详又拷贝,-,-||| 相关理论依据,还请去移步 NGUI的UISprite动态染色的 ...

  4. 【转】Linux mysql停止失败的解决办法 Stopping MySQL database server mysqld [fail]

    root@ubuntu:/# /etc/init.d/mysql stop * Stopping MySQL database server mysqld [fail] root@ubuntu:/# ...

  5. js弹出层的插件

    1.jquery.fancybox.pack.js 2.artdialog 3.

  6. 【JavaScript】脚本

    javascript: void((function() { var as = document.getElementsByTagName('a'); for (var i = 0, j = as.l ...

  7. mysql 添加外键时 error 150 问题总汇

    当你试图在mysql中创建一个外键的时候,这个出错会经常发生,这是非常令人沮丧的.像这种不能创建一个.frm 文件的报错好像暗示着操作系统的文件的权限错误或者其它原因,但实际上,这些都不是的,事实上, ...

  8. [转]mybatis如何直接 执行传入的任意sql语句 并按照顺序取出查询的结果集

    原文地址:https://www.cnblogs.com/wuyun-blog/p/5769096.html 需求: 1.直接执行前端传来的任何sql语句,parameterType="St ...

  9. Thinkphp在Tpl中调用common.php中的公共函数

    Common/common.php //产生随机验证码 function random($length, $chars = '0123456789') { //随机生成的逻辑 return $hash ...

  10. <Effective Django>读书笔记

    In Django parlance, a project is the final product, and it assembles one or more applications togeth ...