前言
探究MyBatis Plus提供的预定义CRUD接口的实现方式。
两种方式
MBP提供两种包含预定义CRUD的接口:
com.baomidou.mybatisplus.extension.service.IService
com.baomidou.mybatisplus.core.mapper.BaseMapper
其中IService
接口是针对业务逻辑层的封装,并提供了批处理操作。BaseMapper
则是对DAO层CRUD的封装。
BaseMapper
BaseMapper
的接口规范很简单,看代码就能明白,重点是了解MBP如何实现的BaseMapper
。
在使用MyBatis的情况下,我们定义了Mapper接口,然后会在对应的XML文件中提供动态SQL及映射关系,或者直接在Mapper接口方法上添加注解,MyBatis将XML中的配置或者注解作为元数据进行解析,然后将解析后的SQL语句存至org.apache.ibatis.session.Configuration
。MBP在MyBatis的基础上只做增强不做改变,则只要能够实现原pipeline将元数据解析成动态SQL存至org.apache.ibatis.session.Configuration
即可。
MyBatis Plus的整体思路是使用自己的组件替换MyBatis中的组件,以实现自定义的逻辑。其中MybatisPlusAutoConfiguration
类替代了MyBatis的自动配置类,这个类中包含MybatisPlusProperties
属性。MybatisPlusProperties
包含mapperLocations
字段用于解析Mapper XML文件的位置,并汇总为Resource
数组。
在MybatisPlusAutoConfiguration#sqlSessionFactory
函数中,包含XML位置的Resource
数组被设置到MybatisSqlSessionFactoryBean.mapperLocations
下(MybatisSqlSessionFactoryBean
也是MBP替换组件)。而后在MybatisSqlSessionFactoryBean#buildSqlSessionFactory
函数中,XML文件被逐个读取并解析。
1 | if (this.mapperLocations != null) { |
其中XMLMapperBuilder
在解析过程中会调用XMLMapperBuilder#bindMapperForNamespace
方法。
1 | private void bindMapperForNamespace() { |
此时的configuration
为MybatisSqlSessionFactoryBean
传入的targetConfiguration
,即MybatisConfiguration
(MBP替换组件)。此时MybatisMapperRegistry#addMapper
调用MybatisMapperRegistry#addMapper
方法。
MybatisMapperRegistry
也是一个MBP替换组件,继承并替换掉原本的MapperRegistry
,其addMapper
方法如下。
1 | public <T> void addMapper(Class<T> type) { |
最终调用MBP自定义的MybatisMapperAnnotationBuilder#parse
方法,如下。
1 |
|
通过全局缓存工具GlobalConfigUtils
获取ISqlInjector
实例,调用ISqlInjector#inspectInject
方法进行CRUD方法注入。在实现上,实际上是由AbstractSqlInjector
实现了ISqlInjector
接口,然后又由DefaultSqlInjector
继承AbstractSqlInjector
实现最终注入。
1 | // AbstractSqlInjector |
其中每一个函数都是继承了com.baomidou.mybatisplus.core.injector.AbstractMethod
的类,包含一个inject
注入方法。
IService
IService
的实现在com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
。
IService
依赖于Spring容器,而BaseMapper
不依赖,原因是IService
实例中会注入一个BaseMapper
实例用于做CRUD操作,也就是上面的那一套。
IService
还支持批量操作,这部分源码比较好看,调用链路是:com.baomidou.mybatisplus.extension.toolkit.SqlHelper#executeBatch -> org.apache.ibatis.session#flushStatements
参考文献
[1] https://blog.csdn.net/wjw465150/article/details/126896276
[2] https://blog.csdn.net/zzuhkp/article/details/120174101
后记
首发于 silencezheng.top,转载请注明出处。