文章目录
1 MyBatis缓存
1.1 一级缓存
MyBatis的一级缓存默认开启,作用范围是SqlSession级别的,也就是说某个SqlSession进行某个查询操作后会将该结果暂时缓存起来,而后在所有的SqlSession没有对该表进行插入、修改、删除操作的情况下,当这个SqlSession再次发起此查询时SqlSession不会去数据库执行查询操作,而是直接从缓存拿出上次查询的结果。不同的SqlSession之间缓存的数据互不影响。
经过测试,发现使用同一个SqlSession执行了两次查询,代码如下:
@GetMapping("/list")
public List<User> getAllUser() {
List<User> users = userMapper.selectAll();
List<User> users1 = userMapper.selectAll();
return users;
}
结果:
2019-04-22 10:58:11.974 DEBUG 9168 --- [nio-8080-exec-2] c.f.m.mapper.UserMapper.selectAll : ==> Preparing: SELECT * FROM user
2019-04-22 10:58:11.975 DEBUG 9168 --- [nio-8080-exec-2] c.f.m.mapper.UserMapper.selectAll : ==> Parameters:
2019-04-22 10:58:11.976 DEBUG 9168 --- [nio-8080-exec-2] c.f.m.mapper.UserMapper.selectAll : <== Total: 2
2019-04-22 10:58:11.977 DEBUG 9168 --- [nio-8080-exec-2] c.f.m.mapper.UserMapper.selectAll : ==> Preparing: SELECT * FROM user
2019-04-22 10:58:11.977 DEBUG 9168 --- [nio-8080-exec-2] c.f.m.mapper.UserMapper.selectAll : ==> Parameters:
2019-04-22 10:58:11.979 DEBUG 9168 --- [nio-8080-exec-2] c.f.m.mapper.UserMapper.selectAll : <== Total: 2
查询资料得出原因,只有同一个事务中的查询MyBatis的一级缓存才生效,加上@Transactional执行代码,结果只进行了一次查询:
2019-04-22 11:02:09.818 DEBUG 9168 --- [nio-8080-exec-1] c.f.m.mapper.UserMapper.selectAll : ==> Preparing: SELECT * FROM user
2019-04-22 11:02:09.819 DEBUG 9168 --- [nio-8080-exec-1] c.f.m.mapper.UserMapper.selectAll : ==> Parameters:
2019-04-22 11:02:09.820 DEBUG 9168 --- [nio-8080-exec-1] c.f.m.mapper.UserMapper.selectAll : <== Total: 2
1.2 二级缓存
MyBatis的二级缓存是基于Mapper级别的,也就是说多个SqlSession去使用某个Mapper的查询语句时,得到的缓存数据是可共用的。同一级缓存一样,有修改操作就会刷新缓存。二级缓存需要在mapper.xml文件中加入缓存配置:
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
eviction:收回策略
- LRU – 最近最少使用的:移除最长时间不被使用的对象。 (默认)
- FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
- SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
- WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
flushInterval:缓存时间
size:存储大小,单位引用
去掉事务代码进行测试:
@GetMapping("/list")
public List<User> getAllUser() {
List<User> users = userMapper.selectAll();
List<User> users1 = userMapper.selectAll();
return users;
}
结果发现第一次查询连接数据库,之后都是直接获取缓存结果:
2019-04-22 11:32:13.017 DEBUG 12616 --- [nio-8080-exec-7] c.f.m.mapper.UserMapper.selectAll : ==> Preparing: SELECT * FROM user
2019-04-22 11:32:13.017 DEBUG 12616 --- [nio-8080-exec-7] c.f.m.mapper.UserMapper.selectAll : ==> Parameters:
2019-04-22 11:32:13.019 DEBUG 12616 --- [nio-8080-exec-7] c.f.m.mapper.UserMapper.selectAll : <== Total: 3
2019-04-22 11:32:13.020 DEBUG 12616 --- [nio-8080-exec-7] c.freesky.mybatistest.mapper.UserMapper : Cache Hit Ratio [com.freesky.mybatistest.mapper.UserMapper]: 0.6666666666666666
2019-04-22 11:32:18.706 DEBUG 12616 --- [nio-8080-exec-9] c.freesky.mybatistest.mapper.UserMapper : Cache Hit Ratio [com.freesky.mybatistest.mapper.UserMapper]: 0.7142857142857143
2019-04-22 11:32:18.707 DEBUG 12616 --- [nio-8080-exec-9] c.freesky.mybatistest.mapper.UserMapper : Cache Hit Ratio [com.freesky.mybatistest.mapper.UserMapper]: 0.75
2019-04-22 11:32:20.292 DEBUG 12616 --- [nio-8080-exec-1] c.freesky.mybatistest.mapper.UserMapper : Cache Hit Ratio [com.freesky.mybatistest.mapper.UserMapper]: 0.7777777777777778
2019-04-22 11:32:20.292 DEBUG 12616 --- [nio-8080-exec-1] c.freesky.mybatistest.mapper.UserMapper : Cache Hit Ratio [com.freesky.mybatistest.mapper.UserMapper]: 0.8
更新测试:
@GetMapping("/list1")
public List<User> getAllUser1() {
//更新
userMapper.updateById(3L, "新名字");
return userMapper.selectAll();
}
结果发现更新之后需要重新连接数据库进行查询:
2019-04-22 11:34:15.647 DEBUG 12616 --- [nio-8080-exec-7] c.f.m.mapper.UserMapper.updateById : ==> Preparing: UPDATE user SET name = ? WHERE id = ?
2019-04-22 11:34:15.648 DEBUG 12616 --- [nio-8080-exec-7] c.f.m.mapper.UserMapper.updateById : ==> Parameters: 新名字(String), 3(Long)
2019-04-22 11:34:15.704 DEBUG 12616 --- [nio-8080-exec-7] c.f.m.mapper.UserMapper.updateById : <== Updates: 1
2019-04-22 11:34:15.705 DEBUG 12616 --- [nio-8080-exec-7] c.freesky.mybatistest.mapper.UserMapper : Cache Hit Ratio [com.freesky.mybatistest.mapper.UserMapper]: 0.6666666666666666
2019-04-22 11:34:15.705 DEBUG 12616 --- [nio-8080-exec-7] c.f.m.mapper.UserMapper.selectAll : ==> Preparing: SELECT * FROM user
2019-04-22 11:34:15.705 DEBUG 12616 --- [nio-8080-exec-7] c.f.m.mapper.UserMapper.selectAll : ==> Parameters:
2019-04-22 11:34:15.706 DEBUG 12616 --- [nio-8080-exec-7] c.f.m.mapper.UserMapper.selectAll : <== Total: 3