MyBatis总结之缓存机制

版权声明:@AaronFo https://blog.csdn.net/sinat_33212645/article/details/85160888

目录

前言

1.一级缓存

2.二级缓存


前言

      MyBatis的查询缓存分为一级缓存和二级缓存,一级缓存是SqlSession级别的缓存,二级缓存是mapper级别的缓存,二级缓存是多个SqlSession共享的;MyBatis通过缓存机制减轻数据压力,提供数据库性能。

1.一级缓存

 1.1 同一个SqlSession ,多次调用同一个Mapper和同一个方法的同一个参数,只会进行一次数据库查询,然后把数据缓存到缓冲中,以后直接先从缓存中取出数据,不会直接去查数据库。

 1.2 MyBatis中一级缓存是默认开启的,即在查询中(一次SqlSession中)。只要当SqlSession不关闭,那么你的操作会默认存储使用一级缓存。

 1.3 需要注意的是,如果SqlSession执行了DML(insert,update,delete),并提交到数据库,MyBatis会清空SqlSession中的一级缓存,保证缓存的数据的实时性,避免出现脏读现象。

String config = "mybatis-config.xml"; 
InputStream inputStream = Resources.getResourceAsStream(config);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 

SqlSession sqlSession = sqlSessionFactory.openSession();

SysUser user = sqlSession.selectOne("SysUserMapper.getByUUID", 080001); 
System.out.println(user); 
/*
* 一级缓存默认就会被使用
*/ 
user = sqlSession.selectOne(SysUserMapper.getByUUID", 01); 
System.out.println(user); 
sqlSession.close(); 
/*
   1. 必须是同一个SqlSession,如果sqlSession对象已经close()过了就不可能用了 
*/ 
sqlSession= MyBatisUtil.getSqlSession(); 
user = sqlSession.selectOne(SysUserMapper.getByUUID", 01); 
System.out.println(user); 
/*
  2. 查询条件必须是一样的
 */ 
user = sqlSession.selectOne(SysUserMapper.getByUUID", 02); 
System.out.println(user); 
/*  
3. 没有执行过sqlSession.clearCache()清理缓存
 */ 
//sqlSession.clearCache();
 user = sqlSession.selectOne(SysUserMapper.getByUUID", 02);
 System.out.println(user); 
/*
4. 没有执行过增删改的操作(这些操作都会清理缓存)
 */ 
session.update("SysUserMapper.updateUser",
new SysUser(02, "user", 23)); 
user = session.selectOne(SysUserMapper.getByUUID", 02); 
System.out.println(user);

2.二级缓存

 2.1 二级缓存是mapper级别的缓存,使用二级缓存,多个SqlSession使用同一个Mapper的sql去操作数据库,得到的数据会存到二级缓存区域,以HashMap形式进行存储。

 2.2 MyBatis 默认不会开启二级缓存,需要在setting全局参数中配置开启二级缓存。

   2.2.1 mybatis-config.xml配置

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

   2.2.2 开启当前mapper的namespace下的二级缓存:xxxxMapper.xml

<!-- 创建一个LRU缓存,每隔60秒刷新,最大缓存对象512个,而且返回的对象被认为是只读的 -->
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true" />

    1)flushInterval:刷新间隔,默认是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新;

    2)size:缓存数目,默认值是1024;

    3)readOnly:只读,默认是false;

    4)eviction:回收策略,默认LRU;

LRU 最近最少回收策略,移除长时间不被使用对象
FIFO 先进先出策略
SOFT 软引用策略,移除基于垃圾回收状态和软引用规则的对象
WEAK 弱引用策略,更积极移除基于垃圾回收状态和弱引用规则的对象

2.3 需要注意的是,使用二级缓存时,与查询结果映射的Java对象必须实现java.io.Seriailizable接口的序列化和反序列化操作。因为二级缓存数据存储介质多样,不一定在内存,也可能是在硬盘或者远程服务器。

猜你喜欢

转载自blog.csdn.net/sinat_33212645/article/details/85160888
今日推荐