当前位置: 首页 > Web前端 > HTML

谈谈MybatisExecutor之CachingExecutor

时间:2023-03-27 23:15:58 HTML

聊Mybatis的Executor之CachingExecutorCachingExecutor先看下CachingExecutor类:publicclassCachingExecutorimplementsExecutor{privatefinalExecutordelegate;@Overridepublicintupdate(MappedStatementms,ObjectparameterObject)抛出SQLException{flushCacheIfRequired(ms);返回delegate.update(ms,parameterObject);}CachingExecutor的成员变量有一个Executor实例,这显然是一种装饰器模式。这个类是其他Executor实例的方法中的flushCacheIfRequired(),就是刷新缓存,所以这个类在其他类中除了缓存功能外,从query()方法也可以看出缓存先查找,缓存不会调用Executor实例的query()查询数据。这里的二级缓存就是二级缓存。我们通过它的query()方法来看二级缓存的逻辑:@OverridepublicListquery(MappedStatementms,ObjectparameterObject,RowBoundsrowBounds,ResultHandlerresultHandler,CacheKeykey,BoundSqlboundSql)throwsSQLException{缓存cache=ms.getCache();如果(缓存!=null){flushCacheIfRequired(毫秒);如果(ms.isUseCache()&&resultHandler==null){ensureNoOutParams(ms,boundSql);@SuppressWarnings("unchecked")Listlist=(List)tcm.getObject(cache,key);if(list==null){list=delegate.query(ms,parameterObject,rowBounds,resultHandler,key,boundSql);tcm.putObject(缓存,键,列表);}返回列表;}}returndelegate.query(ms,parameterObject,rowBounds,resultHandler,key,boundSql);}获取二级缓存对象,如果object不为空,说明开启了二级缓存,是否清除二级缓存根据select标签的flushCache配置决定。设置为true后,只要调用该语句,就会清除本地缓存和二级缓存。默认值:假。然后查看select标签的useCache属性,设置为true,会导致这条语句的结果被二级缓存缓存。默认值:如果select元素为真,则调用TransactionalCacheManager的getObject()方法获取二级缓存,如果一级缓存为空,则查询数据库,将结果写入缓存,最后返回列表。从代码中可以看出TransactionalCacheManager管理缓存。它有一个成员变量是一个map集合:MaptransactionalCaches=newHashMap<>();获取缓存的方式是先获取map中的TransactionalCache对象,然后调用TransactionalCache的getObject(key)方法。然后我们需要关注TransactionalCache类。事务缓存类TransactionalCacheTransactionalCache实现了Cache接口,用于记录事务秒publicclassTransactionalCacheimplementsCache{privatefinalMapentriesToAddOnCommit;@OverridepublicvoidputObject(Objectkey,Objectobject){entriesToAddOnCommit.put(key,object);}}entriesToAddOnCommit用于添加二级缓存中的数据,是指调用查询方法时,二级缓存中的数据只缓存在map集合entriesToAddOnCommit中,遍历集合保存数据当调用CachingExecutor的commit()方法时。到二级缓存缓存@Overridepublicvoidcommit(booleanrequired)throwsSQLException{delegate.commit(required);tcm.commit();二级缓存数据由其成员变量TransactionalCacheManager管理。值得一提的是,真正提交二级缓存数据是在事务提交后进行的,可以防止脏读