MyBatis常见的问题以及原理

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:收回策略

  1. LRU – 最近最少使用的:移除最长时间不被使用的对象。 (默认)
  2. FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
  3. SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
  4. 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
posted @ 2019-04-22 13:25  _chenyl  阅读(57)  评论(0编辑  收藏  举报