Mybatis 官方定义
MyBatis是支持定制化SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以对配置和原生Map使用简单的XML或注解,将接口和Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
一级缓存
优化重复查询问题;
每个SqlSession中都设置一个自己的缓存(Session级,一个会话中的所有语句共享这个缓存;sta'tement级:支队当前statement有效,具体是每一个SqlSession中持有了自己的Executor,每一个Executor中有一个Local Cache。当用户发起查询时,Mybatis会根据当前执行的MappedStatement生成一个key,去Local Cache中查询,如果缓存命中的话,返回。如果缓存没有命中的话,则写入Local Cache,最后返回结果给用户。
配置:
//在Mybatis配置文件中配置(默认为SESSION级别) <setting name="localCacheScope" value="SESSION"/>
对于select statement,根据其生成的 key(statement Id + Offset +Limmit + Sql + Params) 在缓存中寻找,命中不多说,未命中是在数据库执行,并将返回数据缓存。
updata,delete,insert 操作都会清空缓存。
问题:
多个SqlSession的时候容易引起脏数据。
二级级缓存
多个SqlSession共享数据。
开启二级缓存后,会使用CachingExecutor装饰Executor,在进入后续执行前,先在CachingExecutor进行二级缓存的查询。
//Mybatis 配置文件中 <setting name="cacheEnabled" value="true"/> //在映射文件中 声明这个namespace使用二级缓存 <cache/> //或者 //在映射文件中 生命这个映射文件与xxxMapper共享一个二级缓存 <cache-ref namespace="xxx.xxxMapper"/>
Mybatis的二级缓存相对于一级缓存来说,实现了SqlSession之间缓存数据的共享,同时粒度更加的细,能够到Mapper级别,通过Cache接口实现类不同的组合,对Cache的可控性也更强。
问题:
多表查询容易出现脏数据。
cache基于本地,分布式环境下必然出现脏数据;
总结:
Mybatis缓存不完善。