【mybatis】多次查询缓存的问题
转自:http://cheng-xinwei.iteye.com/blog/2021700?utm_source=tuicool&utm_medium=referral
最近在使用mybatis的过程中,发现一个问题。如果在同一个事物中,多次同一个查询sql在mybatis的执行过程中,只会查询一次数据库,后几次所返回的对象是mybatis在在内部做了缓存。
Property property = this.findByPropertyId("");
property.setPropertyId(null);;
property = this.findByPropertyId("");
System.out.println(property.getPropertyId());
以上的代码,打印的结果为 null , 但是我们所期望的可能是 123 , 我不知道这是mybatis的一个bug还是故意这样去设计的.mybatis在执行查询语句的时候,会在本地做一份缓存信息.在BaseExecutor类中:
private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
List<E> list;
localCache.putObject(key, EXECUTION_PLACEHOLDER);
try {
list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
} finally {
localCache.removeObject(key);
}
localCache.putObject(key, list);
if (ms.getStatementType() == StatementType.CALLABLE) {
localOutputParameterCache.putObject(key, parameter);
}
return list;
可以看到在queryFromDatabase方法中,查询数据库返回结果之后,mybatis编制了一个cachekey的对象,作为key,返回结果作为value,放入了缓存当中(这个地方没有使用拷贝的函数,所以只要外部修改了值,内部缓存中的值信息也会被修改)
之后再下次查询的时候,会依据一个判断,是否需要执行缓存信息,同样是在BaseExecutor类中。
@SuppressWarnings("unchecked")
public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());
if (closed) throw new ExecutorException("Executor was closed.");
if (queryStack == && ms.isFlushCacheRequired()) {
clearLocalCache();
}
List<E> list;
try {
queryStack++;
list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;
if (list != null) {
handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);
} else {
list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
}
} finally {
queryStack--;
}
if (queryStack == ) {
for (DeferredLoad deferredLoad : deferredLoads) {
deferredLoad.load();
}
deferredLoads.clear(); // issue #601
if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
clearLocalCache(); // issue #482
}
}
return list;
}
看到mybatis判断了 ms.isFlushCacheRequired() 的返回数据,如果为 true 会执行 clearLocalCache 方法,清空缓存信息。如果缓存中获取不到的话,才会继续去查询数据库。
可以从 list = resultHandler == null ? (List<E>) localCache.getObject(key) : null; 代码中看出。
所以当第一次查询放入缓存之后,在外部修改了任何一个值之后,mybatis内部缓存的值也会被修改,而且下次查询不会查询数据库,直接返回缓存中被修改过的值
ms.isFlushCacheRequired() 这段代码的判断是基于了一个MappedStatement 类中的flushCacheRequired 的属性做判断的。flushCacheRequired 变量可以通过注解的方式和xml的方式来配置
1.注解:注解的方式是通过 @Options 注解中 flushCache 的配置
2.配置文件:xml中每一个select 都可以设置 flushCache 的属性
flushCache 设置成true之后,本sql的每次查询都会清空缓存后在执行。
【mybatis】多次查询缓存的问题的更多相关文章
- mybatis中的查询缓存
一: 查询缓存 Mybatis提供查询缓存,用于减轻数据压力,提高数据库压力. Mybatis提供一级缓存和二级缓存. 在操作数据库时需要构造SqlSession对象,在对象中有一个数据结构(Hash ...
- 【Mybatis框架】查询缓存(一级缓存)
做Java的各位程序员们,估计SSH和SSM是我们的基础必备框架.也就是说我们都已经至少接触过了这两套常见的集成框架.当我们用SSH的时候,相信很多人都接触过hibernate的两级缓存,同样,相对应 ...
- Mybatis延迟加载和查询缓存
摘录自:http://www.linuxidc.com/Linux/2016-07/133593.htm 阅读目录 一.延迟加载 二.查询缓存 一.延迟加载 resultMap可以实现高级映射(使用a ...
- mybatis由浅入深day02_7查询缓存_7.2一级缓存_一级缓存应用
7 查询缓存 7.1 什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 一级缓存是SqlSession级别的缓存.在操作数据库时 ...
- 【Mybatis框架】查询缓存(二级缓存)
继上一篇博客,我们讲述了mybatis的一级缓存,接下来,我们来学习一下mybatis的二级缓存 博客链接地址: http://blog.csdn.NET/liweizhong193516/artic ...
- 7.4mybatis整合ehcache(mybatis无法实现分布式缓存必须和其他缓存框架整合)
<\mybatis\day02\14查询缓存-二级缓存-整合ehcache.av> mybatis的缓存机制(一级缓存二级缓存和刷新缓存)和mybatis整合ehcache-- 这里有做本 ...
- mybatis入门基础(八)-----查询缓存
一.什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 1.1. 一级缓存是sqlSession级别的缓存.在操作数据库时需要构造 ...
- MyBatis学习--查询缓存
简介 以前在使用Hibernate的时候知道其有一级缓存和二级缓存,限制ORM框架的发展都是互相吸收其他框架的优点,在Hibernate中也有一级缓存和二级缓存,用于减轻数据压力,提高数据库性能. m ...
- Mybatis学习记录(七)----Mybatis查询缓存
1. 什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 一级缓存是SqlSession级别的缓存.在操作数据库时需要构造 sql ...
- 八 mybatis查询缓存(一级缓存,二级缓存)和ehcache整合
1 查询缓存 1.1 什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存.
随机推荐
- ASP.NET Web API实践系列03,路由模版, 路由惯例, 路由设置
ASP.NET Web API的路由和ASP.NET MVC相似,也是把路由放在RouteTable中的.可以在App_Start文件夹中的WebApiConfig.cs中设置路由模版.默认的路由模版 ...
- 【CentOS】centos如何修改你的主机名
转载地址:https://www.linuxidc.com/Linux/2014-11/109238.htm ============================================= ...
- 详解Java Spring各种依赖注入注解的区别
注解注入顾名思义就是通过注解来实现注入,Spring和注入相关的常见注解有Autowired.Resource.Qualifier.Service.Controller.Repository.Comp ...
- 数据访问:Implementing Efficient Transactions
An OLTP scenario is characterized by a large number of concurrent operations that create, update, an ...
- jquery插件--在input下输入密码时提示大写锁定键
//密码大写输入提示 function capitalTip(id){ $('#' + id).after('<div class="capslock" id="c ...
- Spring Websocket实现文本、图片、声音、文件下载及推送、接收及显示(集群模式)
相关环境 Nginx,Spring5.x当前(要选择4.0+),tomcat8.x,Quartz 2.x集群(实际运用是Quartz的集群模式和单机模式共存的) 测试面页:http://sms.rey ...
- Spring MVC+Mybatis 多数据源配置
文章来自:https://www.jianshu.com/p/fddcc1a6b2d8 1. 继承AbstractRoutingDataSource AbstractRoutingDataSource ...
- [Web 前端] Jquery 复制元素,并修改属性, 追加到另一个元素后面
cp from : https://blog.csdn.net/cooledi/article/details/52813668 jquery 复制元素,并修改属性 $('#ID').clone() ...
- CSS3 Flex布局整理(一)
一.说明 1.在以往的布局方案中,都是基于盒装模型,依赖display属性+position属性+float属性等. 他对于那些特殊布局非常不方便,比如,垂直居中等. 并且不同浏览器的盒模型还有些差异 ...
- 优化算法动画演示Alec Radford's animations for optimization algorithms
Alec Radford has created some great animations comparing optimization algorithms SGD, Momentum, NAG, ...