您的位置:首页 > 其它

Mybatis缓存_7

2016-07-10 20:40 225 查看


一、MyBatis缓存介绍

  与大多数持久层框架一样,MyBatis 同样提供了一级缓存二级缓存的支持

      1.一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Session,当 Session
flush 或 close
 之后,该Session中的所有 Cache 就将清空

  2. 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如
Ehcache。

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


(1)Mybatis一级缓存具体分析

@Test
public void cache1() {

SqlSession session = null;
try {
// 获得会话
session = MyBatisUtil.getSqlSession(true);
// 映射sql的标识字符串
String statement = "com.hlx.dao.UserinfosMapper.myid";
logger.debug("----->查询数据1!");
// 执行插入操作
Userinfos student= session.selectOne(statement, 1);
System.out.println(student);
System.out.println(session);

logger.debug("----->查询数据2!");
//   一级缓存默认就会被使用
student= session.selectOne(statement, 1);
System.out.println(student);
System.out.println(session);
执行效果如下:(说明是同一个Session对象)



session.close();  //当 Session close 之后,该Session中的所有 Cache 就将清空。
//(1) 必须是同一个Session,如果session对象已经close()过了就不可能用了
session = MyBatisUtil.getSqlSession(true);
student= session.selectOne(statement, 1);
System.out.println(student);
System.out.println(session);

执行效果如下:(说明是不是同一个Session对象)






//(2) 查询条件是一样的,只是编号不一样
student= session.selectOne(statement, 3);
System.out.println(student);
System.out.println(session);执行效果如下:(说明是同一个Session对象,但必须重新查询一遍,缓存中没有此数据)



//(3)没有执行过session.clearCache()清理缓存
//session.clearCache(); //清理
student= session.selectOne(statement, 3);
System.out.println(student);
System.out.println(session);执行效果如下:(说明是同一个Session对象,缓存中有此数据,直接查询 )



执行效果如下:session.clearCache(); (说明是同一个Session对象,清理了缓存中的数据,重新查询 )






// //(4)执行过增删改的操作(这些操作都会清理缓存)
session.update("com.hlx.dao.UserinfosMapper.mod",new Userinfos(42, "李白", "000"));
//再次查询时,为null
student= session.selectOne(statement, 42);
System.out.println(student);
System.out.println(session);
执行效果如下:(说明是同一个Session对象,清理了缓存中的数据
)

(一级缓存Session/二级缓存Namespaces)的进行了
C/U/D 操作后,默认该作用域下所有 select 中的缓存将被clear。




(2)Mybatis二级缓存具体分析

   2.1) 、在UserinfosMapper.xml文件中(开启二级缓存)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!-- 为这个mapper指定一个唯一的namespace, namespace的值习惯上设置成包名+sql映射文件名,这样就能够保证namespace的值是唯一的
例如namespace="com.hlx.dao.UserinfosMapper"就是com.hlx.dao(包名)+UserinfosMapper(UserinfosMapper.xml文件去除后缀) -->
<mapper namespace="com.hlx.dao.UserinfosMapper">

<!-- 开启二级缓存 -->
<cache/>   2.2)、测试?

  


  2.3)、二级缓存补充说明

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

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

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

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

  5. 缓存会存储1024个对象

cache标签常用属性:

<mapper namespace="com.hlx.dao.UserinfosMapper">

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



二、Cache使用时的注意事项


1. 只能在【只有单表操作】的表上使用缓存

不只是要保证这个表在整个系统中只有单表操作,而且和该表有关的全部操作必须全部在一个
namespace
下。


 2. 在可以保证查询远远大于insert,update,delete操作的情况下使用缓存

    必须在1的前提下才可以! 


四、避免使用二级缓存

  二级缓存带来的好处远远比不上他所隐藏的危害。

缓存是以
namespace
为单位的,不同
namespace
下的操作互不影响。

insert,update,delete操作会清空所在
namespace
下的全部缓存。

通常使用MyBatis Generator生成的代码中,都是各个表独立的,每个表都有自己的
namespace


MyBatis目前的缓存方式来看是无解的。多表操作根本不能缓存。

如果你让他们都使用同一个
namespace
(通过
<cache-ref>
)来避免脏数据,那就失去了缓存的意义。

实际上就是说,二级缓存不能用!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: