可以说,90%的小伙伴,都是冲着Mybatis-Plus基础mapper不用写的特点,入坑的。
那么Mybatis-Plus,是如何基于Mybatis,实现基础通用mapper呢?
答案,就是继承&覆写,Mybatis的MapperAnnotationBuilder。
Mybatis的MapperAnnotationBuilder,原先是为了提供对@Select等注解的解析。Mybatis-Plus通过继承&重写其中的parse方法,实现了Mybatis-Plus自身通用Mapper的注入。
有关MapperRegistry之前的流程,详见前文对Mybatis初始化流程中,mapper注入的部分。 MybatisMapperAnnotationBuilder /** * 继承 * 只重写了 {@link MapperAnnotationBuilder#parse} 和 #getReturnType * 没有XML配置文件注入基础CRUD方法 * @author Caratacus * @since 2017-01-04 */ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder { @Override public void parse() { String resource = type.toString(); if (!configuration.isResourceLoaded(resource)) { loadXmlResource(); configuration.addLoadedResource(resource); String mapperName = type.getName(); assistant.setCurrentNamespace(mapperName); parseCache(); parseCacheRef(); InterceptorIgnoreHelper.InterceptorIgnoreCache cache = InterceptorIgnoreHelper.initSqlParserInfoCache(type); for (Method method : type.getMethods()) { if (!canHaveStatement(method)) { continue; } if (getAnnotationWrapper(method, false, Select.class, SelectProvider.class).isPresent() && method.getAnnotation(ResultMap.class) == null) { parseResultMap(method); } try { InterceptorIgnoreHelper.initSqlParserInfoCache(cache, mapperName, method); SqlParserHelper.initSqlParserInfoCache(mapperName, method); parseStatement(method); } catch (IncompleteElementException e) { configuration.addIncompleteMethod(new MybatisMethodResolver(this, method)); } } try { if (GlobalConfigUtils.isSupperMapperChildren(configuration, type)) { parserInjector(); } } catch (IncompleteElementException e) { configuration.addIncompleteMethod(new InjectorResolver(this)); } } parsePendingMethods(); } // 核心方法。进行定制化的通用mapper注入 void parserInjector() { GlobalConfigUtils.getSqlInjector(configuration).inspectInject(assistant, type); } // 其他方法(略) } Insert
Mybatis-Plus下BaseMapper的通用Mapper方法,实现都在com.baomidou.mybatisplus.core.injector.methods下。
这里,就以Insert为例,简单解析一下。
有关Mybatis-Plus的lambda表达式的实现,涉及的点比较多。这里给一些建议:首先对函数式编程&流式编程有足够的了解,其次需要对wrapper的使用有一定认识,最后剖析Mybatis-Plus中对应部分。
具体实现,详见:
com.baomidou.mybatisplus.core.conditions.AbstractLambdaWrapper
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper
com.baomidou.mybatisplus.core.toolkit.LambdaUtils
com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda
com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper
com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper
最后,愿与诸君共进步。
五、附录 补充driver加载:jdbc下的driver加载分为三种方式:
driverManager会在第一次调用时,会通过loadInitialDrivers()静态方法,对系统变量中的jdbc.drivers进行驱动注册
直接调用driverManager的register()方法,进行注册。
具体驱动,在初始化时,会调用driverManager的register()方法,进行注册。例:Class.forName("oracle.jdbc.driver.OracleDriver");