Mybatis - 一级缓存和二级缓存 -1
来源:互联网 发布:淘宝交易金额冻结 编辑:程序博客网 时间:2024/05/16 13:58
一级缓存是SqlSession级别的缓存。
- 在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。
- 不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。
- 一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。
- 当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。Mybatis默认开启一级缓存。
二级缓存是mapper级别的缓存
- 多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession去操作数据库得到数据会存在二级缓存区域,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
- 二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace;
- 不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。
- Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。
- 如果缓存中有数据就不用从数据库中获取,大大提高系统性能。
一级缓存测试:
默认作用域:session ;
@Test public void testCacheOne(){ /*set auto commit ,which equals to the above*/ SqlSession session = MybatisUtils.getFactory().openSession(true); String statement = "com.web.mapper.userMapper.getUser"; /*return the effect rows*/ User user = session.selectOne(statement, 1); System.out.println("result.."+user);// session.clearCache(); //测试缓存肯定针对同样的数据,如果id变为2,缓存里面没有。缓存测试无从谈起。 user = session.selectOne(statement, 1); System.out.println("result.."+user); System.out.println("***************************************************"); }
一级缓存默认开启,作用域为session。
- 缓存不清空时,连续查询:
@Test public void testCacheOne(){ /*set auto commit ,which equals to the above*/ SqlSession session = MybatisUtils.getFactory().openSession(true); String statement = "com.web.mapper.userMapper.getUser"; /*return the effect rows*/ User user = session.selectOne(statement, 1); System.out.println("result.."+user);// session.clearCache(); user = session.selectOne(statement, 1); System.out.println("result.."+user); System.out.println("***************************************************");}
- result as follows :
如上图所示,只进行了一次数据库查询。第二次查询的时候,默认使用了缓存。
- 缓存清空,进行第二次查询:
@Test public void testCacheOne(){ /*set auto commit ,which equals to the above*/ SqlSession session = MybatisUtils.getFactory().openSession(true); String statement = "com.web.mapper.userMapper.getUser"; /*return the effect rows*/ User user = session.selectOne(statement, 1); System.out.println("result.."+user); session.clearCache(); user = session.selectOne(statement, 1); System.out.println("result.."+user); System.out.println("***************************************************"); }
- result as follows :
如上图所示,两次都进行了数据库查询。
- 进行CUD操作,将默认清空缓存
....... session.update("com.web.mapper.userMapper.updateUser",new User(1, "mili", 21)); session.commit(); user = session.selectOne(statement, 1); System.out.println("result.."+user);......
- result as follows :
如上图所示,进行第三地查询时,将重新查询数据库。
同样,当session关闭时,即 session.close( ) ;将会清空缓存。
- 当xml配置属性
flushCache="true"
,也将不会使用缓存:
<!-- flushCache="true" useCache="false" --> <select id="getUser" parameterType="int" resultMap="UserMap" flushCache="true"> select * from t_user where id=#{id} </select>
- result as follows :
综上,清空session缓存的六种方式 :
① session.clearCache( ) ;
② execute update(增删改) ;
③ session.close( );
④ xml配置 flushCache="true"
;
⑤ rollback;
⑥ commit。
二级缓存测试:
|*************************************************************|
补充说明 :
- userMapper.xml中启用二级缓存的简单方式:
<cache></cache>
这是启动二级缓存的简单方式,有以下意思:
1.映射语句文件中的所有select语句将会被缓存;
2.映射语句文件中的所有CUD操作将会刷新缓存;
3.缓存会默认使用LRU(Least Recently Used)算法来收回;
1. LRU – 最近最少使用的:移除最长时间不被使用的对象。2. FIFO – 先进先出:按对象进入缓存的顺序来移除它们。3. SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。4. WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
4.缓存会根据指定的时间间隔来刷新(默认情况下没有刷新间隔,缓存仅仅调用语句时刷新);
5.缓存会存储列表集合或对象(无论查询方法返回什么),默认存储1024个对象。
6.缓存会被视为是read/write(可读/可写)的缓存,意味着检索对象不是共享的,而且可以安全地 被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
|*************************************************************|
e.g. : <mapper namespace="com.web.mapper.userMapper">
- 开启二级缓存:
<mapper namespace="com.web.mapper.userMapper"> <cache > <property name="eviction" value="LRU"/>//回收策略为LRU <property name="flushInterval" value="60000"/>//自动刷新时间间隔为60S <property name="size" value="1024"/>//最多缓存1024个引用对象 <property name="readOnly" value="true"/>//只读 </cache>......
- 如果想在命名空间中共享相同的缓存配置和实例,可以使用cache-ref 元素来引用另外一个缓存。
如下所示:
<cache-ref namespace="com.web.mapper.userMapper" />//引用userMapper 命名空间中的cache。
Tips:
① 默认作用域:Mapper(namespace) ;
② 实体类需要实现序列化接口Serializable ;
③ 确保数据写入二级缓存。
【Test1】
public void testCacheTwo(){ SqlSessionFactory factory = MybatisUtils.getFactory(); /*注意此处是从一个Factory 获取两个session*/ SqlSession session1 = factory.openSession(); SqlSession session2 = factory.openSession(); String statement = "com.web.mapper.userMapper.getUser"; /*return the effect rows*/ User user = session1.selectOne(statement, 1); System.out.println("result.."+user); //进行提交或者关闭将其数据写入二级缓存,否则将不会写入二级缓存// session1.commit(); session1.close(); user = session2.selectOne(statement, 1); System.out.println("result.."+user);// session2.commit(); }
- result as follows :
当执行以下方式时,将不会写入二级缓存:
① session.clearCache();
② update();
【注意】:
如果两个session不是从同一个Factory获取,那么二级缓存将不起作用。
如下所示:
SqlSession sqlSession1 = MybatisUtils.getFactory().openSession();SqlSession sqlSession2 = MybatisUtils.getFactory().openSession();......
- result as follows :
如图所示,两次都进行数据库查询。
命中率为0 !
Cache Hit Ratio [com.web.mapper.userMapper]: 0.0
- Mybatis - 一级缓存和二级缓存 -1
- mybatis一级缓存和二级缓存
- Mybatis 一级缓存和二级缓存
- MyBatis一级缓存和二级缓存
- mybatis 一级缓存和二级缓存
- Mybatis一级缓存和二级缓存
- mybatis一级缓存、二级缓存和自定义二级缓存
- MyBatis缓存分为一级缓存和二级缓存
- MyBatis一级缓存,二级缓存
- MyBatis 一级缓存,二级缓存
- mybatis一级缓存二级缓存
- mybatis 一级缓存和二级缓存简介
- 八、Mybatis一级缓存和二级缓存
- Mybatis的一级缓存和二级缓存-2
- 【Mybatis】(五)一级缓存和二级缓存
- MyBatis的一级缓存和二级缓存
- Mybatis的一级缓存和二级缓存机制
- mybatis--缓存(一级和二级缓存)
- 获取Android当前网络类型(2g、3g、4g、wifi)以及手机型号、版本号
- 控制反转(IoC)与依赖注入(DI)
- Html5多媒体相关的API---video
- java高并发处理
- Eclipse常用 快捷键
- Mybatis - 一级缓存和二级缓存 -1
- Linux进程
- [ios] respondsToSelector等常用判断方法
- SURE无偏估计推导
- opencv获取摄像头帧率分辨率
- 重复值判断练习
- C/C++ console程序隐藏console黑窗口
- 数据加签加密
- 小白笔记----------- 执行 hadoop checknative 报错 openssl: false Cannot load libcrypto.so