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
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了小程序应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值