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>)来避免脏数据,那就失去了缓存的意义。
实际上就是说,二级缓存不能用!!
相关文章推荐
- 1040. Longest Symmetric String (25)
- 拍照和从相册中选取照片,并保存到SD卡上
- sdk (软件开发工具包)
- linux - 理解inode
- JAVA中switch是否支持String类型参数?
- 使用 Native API 创建进程
- 关于akka的mailbox的size问题
- Python开发【第五篇】:Python基础之杂货铺
- 私人定制 博客地图 浏览次数 以及评论体系
- Spark Streaming揭秘 Day32 WAL框架及实现
- Android自定义View——仿ViVO X6 极速闪充动画效果
- 私人定制 博客地图 浏览次数 以及评论体系
- orcle 按年度 月度 汇总
- iOS中自定义输入文本框的cell(UITextFieldCell)的使用技巧
- Hdu 5326 Work(超水的树形DP)
- 1702 素数判定 2
- Python开发【第四篇】:Python基础之函数
- PS学习地址
- 实现 fizzBuzz 函数,参数 num 与返回值的关系如下: 1、如果 num 能同时被 3 和 5 整除,返回字符串 fizzbuzz 2、如果 num 能被 3 整除,返回字符串 fizz 3
- 前景检测算法(十五)--LOBSTER算法