问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

多次查询缓存的问题 flushCache为什么失效

发布网友 发布时间:2022-04-25 22:39

我来回答

1个回答

热心网友 时间:2022-06-18 07:00

最近在使用mybatis的过程中,发现一个问题。如果在同一个事物中,多次同一个查询sql在mybatis的执行过程中,只会查询一次数据库,后几次所返回的对象是mybatis在在内部做了缓存。 Property property = this.findByPropertyId("123"); property.setPropertyId(null);; property = this.findByPropertyId("123"); System.out.println(property.getPropertyId()); 以上的代码,打印的结果为 null , 但是我们所期望的可能是 123 , 我不知道这是mybatis的一个bug还是故意这样去设计的.mybatis在执行查询语句的时候,会在本地做一份缓存信息.在BaseExecutor类中: private List queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { List 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 List 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 == 0 && ms.isFlushCacheRequired()) { clearLocalCache(); } List list; try { queryStack++; list = resultHandler == null ? (List) 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 == 0) { 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) localCache.getObject(key) : null; 代码中看出。 所以当第一次查询放入缓存之后,在外部修改了任何一个值之后,mybatis内部缓存的值也会被修改,而且下次查询不会查询数据库,直接返回缓存中被修改过的值 ms.isFlushCacheRequired() 这段代码的判断是基于了一个MappedStatement 类中的flushCacheRequired 的属性做判断的。flushCacheRequired 变量可以通过注解的方式和xml的方式来配置 1.注解:注解的方式是通过 @Options 注解中 flushCache 的配置 2.配置文件:xml中每一个select 都可以设置 flushCache 的属性 flushCache 设置成true之后,本sql的每次查询都会清空缓存后在执行
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
婴儿突然变的睡觉多了怎么办 宝宝奶量没增加但是睡眠时间变长怎么回事 孩子出现哪些行为时,意味着孩子进入到猛涨期?家长该做些什么? 1岁宝宝睡眠突然增多是怎么回事 李冰冰与自己小十六岁的男友感情稳定,你会介意找一个比自己小的人结婚... 二月份是什么星座呢 二月份的星座是什么座 十二星座对应月份 2月份是什么座是什么星座 2月份出生的什么星座 hibernate 二级缓存如何使用,还有查询缓存 MYSQL会把查询的结果缓存多久 PL/SQL 查询缓存问题 怎样用ehcache实现多查询缓存 二级缓存和查询缓存有区别吗 谁能帮我解释下Hibernate 一级缓存 二级缓存 以及查询缓存? EF6 有查询缓存,怎么办 mybatis 中的查询缓存是什么意思 如何查询缓存时间 hibernate 二级缓存和查询缓存有什么区别 永顺县天禾莓茶产业发展有限公司怎么样? 永顺县四明仙山莓茶种植专业合作社怎么样? 用阿里同事的电脑登陆钉钉可以吗 苹果手机游戏用QQ怎么充值 阿里新员工配什么电脑 永顺县毛坝丈岩溪莓茶专业合作社怎么样? 苹果手机能用Q币充值腾讯游戏吗? 苹果怎么在QQ里用q币给腾讯游戏充值? 苹果手机怎么用q币充值王者荣耀 莓茶和铁观音哪个好 hibernate怎么清除查询出来的缓存数据? MySql缓存问题。 求一套三星以上的酒店大堂设计图,包含cad平面图 立面图 ,以及3d效果图及3D原文件!!谢谢 唐嫣和罗晋的豪宅,两个人住三层别墅,种满鲜花就像仙境一样,你羡慕吗... 酒店大堂设计 绘制cad平面图,顶面图,立面图,地材铺装图,拼花、浮雕大样图,500平米 求一整套酒店设计的CAD图.. 这是三亚(或海南)哪个五星级大酒店的大堂内景?知道的说一下(三张照片是同一家) 如何成为酒店试睡员? 如图是某宾馆大厅到二楼的楼梯设计图,已知BC=6米,AB=9米,中间平台宽度DE为2米,DM,EN为平台的两根支柱 酒店客房三维立体设计图 两朵玫瑰花代表的是什么意思 两朵玫瑰花代表什么意思 飞利浦HX9352怎么样 飞利浦HX9352怎么样?飞利浦HX9352好吗 飞利浦 hx9352 黑钻 第一次电动牙刷怎么充电?平时充多久好? 飞利浦电动牙刷hx9352开机无反应 飞利浦hx9350是什么版本 飞利浦hx9352电动牙刷能用哪些型号的刷头? 飞利浦hx9352,hx6972哪个好 飞利浦电动牙刷hx9352第一次充电,充了了24小时灯还是一直闪烁.是什么原 ...