MyBatis的插件和缓存使用总结概述

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lichunericli/article/details/82315969

1. MyBatis的缓存概述

Configuration对象是MyBatis实现所有功能的基础,它包含了MyBatis中所有的配置,其内容是MyBatis配置文件中<settings>节点下的配置项。MyBatis是通过XMLConfigBuilder对象来解析配置文件的,在解析过程中调用了XPathParser类的evalNode方法来返回XNode对象,XNode对象保存了解析后的对应节点下的所有信息,然后将解析出来的值设置到Configuration中,其中也包括解析mapper节点,例如sql解析,缓存和别名等等。在SqlSession和SqlSessionFactory中有提供获取配置Configuration的方法。

MyBatis会为每个命名空间创建缓存实例,每个缓存的实现的构造函数必须接收String类型的cache id,Mybatis也会将命名空间作为Id传递给构造函数,MyBatis也有提供SPI给cache提供者。MyBatis在CacheKey中通过List来保存所需要更新的对象,但实际上List中保存的是对象的哈希码,如果在同时将多个对象加入列表中时发生了哈希碰撞,此时会根据equals方法来严格区分每个对象是否一致。

MyBatis有提供多种简单的缓存实现方案,差不多都是通过decorators模式装饰后使用,其数据结构基本是List和Map。在众多的缓存实现中,TransactionalCache是值得关注的,TransactionalCache是第二级缓存事务缓冲区,它会保存会话期间要添加到第二级缓存中的所有缓存项。当调用commit或回滚会话时,将把Entries发送到缓存。增加了对阻塞缓存的支持,因此任何返回缓存丢失的get()后面都跟着put(),这样与key相关联的任何锁都可以被释放。MyBatis有提供简单事务缓存管理器来管理事务缓存,最终被CachingExecutor使用。

在Session包中,也有提供本地缓存机制来防止循环引用和加速重复嵌套查询。本地缓存机制默认值为SESSION,通常这种情况下会缓存一个会话中执行的所有查询。若将本地缓存机制设置值为STATEMENT,本地会话仅用在语句执行上,对相同SqlSession的不同调用将不会共享数据。

2. MyBatis的插件概述

MyBatis的插件是在运行时进行拦截处理的,Plugin采用了动态代理来寻找需要拦截的方法,调用Interceptor.intercept来插入对应的逻辑。实际应用中如果要实现定制的MyBatis功能插件,只需要实现Mybatis的Intercepter接口方法即可。在InterceptorChain类中存在拦截器链List<Interceptor> interceptors = new ArrayList<Interceptor>(),通过pluginAll(target)方法来循环调用每个Interceptor.plugin方法来实现插件功能。

在Plugin中获取到的要改变行为的类通常是:ParameterHandler,ResultSetHandler,StatementHandler和Executor。由源码可知道在session包中的Configuration类中,在创建ParameterHandler,ResultSetHandler,StatementHandler和Executor【注意不同类型的执行器的创建】时,会发现如下所示代码interceptorChain.pluginAll(XXX)来触发插件的执行。如果要让其它的拦截也生效,可以通过覆盖Plugin.wrap方法来达到拦截其它类的功能。

总结:在SqlSession执行底层数据的操作时,会通过Configuration来创建ParameterHandler,ResultSetHandler等对象来进行辅助处理,在实际运用中使用最多的插件应该是PageHelper分页插件。

 

猜你喜欢

转载自blog.csdn.net/lichunericli/article/details/82315969