1.版本 : mybatis-plus-core 3.5.1
2.入口:MybatisPlusAutoConfiguration类sqlSessionFactory中的factory.getObject()
3.注入AbstractSqlInjector类中的inspectInject方法中
@Overridepublic void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass) {Class<?> modelClass = ReflectionKit.getSuperClassGenericType(mapperClass, Mapper.class, 0);if (modelClass != null) {String className = mapperClass.toString();Set<String> mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration());if (!mapperRegistryCache.contains(className)) {TableInfo tableInfo = TableInfoHelper.initTableInfo(builderAssistant, modelClass);List<AbstractMethod> methodList = this.getMethodList(mapperClass, tableInfo);if (CollectionUtils.isNotEmpty(methodList)) {// 循环注入自定义方法methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo));} else {logger.debug(mapperClass.toString() + ", No effective injection method was found.");}mapperRegistryCache.add(className);}}}
主要是下面两段逻辑:
(1).List<AbstractMethod> methodList = this.getMethodList(mapperClass, tableInfo); 这里的DefaultSqlInjector增加所有的默认方法
@Overridepublic List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {Stream.Builder<AbstractMethod> builder = Stream.<AbstractMethod>builder().add(new Insert()).add(new Delete()).add(new DeleteByMap()).add(new Update()).add(new SelectByMap()).add(new SelectCount()).add(new SelectMaps()).add(new SelectMapsPage()).add(new SelectObjs()).add(new SelectList()).add(new SelectPage());if (tableInfo.havePK()) {builder.add(new DeleteById()).add(new DeleteBatchByIds()).add(new UpdateById()).add(new SelectById()).add(new SelectBatchByIds());} else {logger.warn(String.format("%s ,Not found @TableId annotation, Cannot use Mybatis-Plus 'xxById' Method.",tableInfo.getEntityType()));}return builder.build().collect(toList());}
(2).methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo));这里实现默认方法的sql(inject中的injectMappedStatement方法)
public void inject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {this.configuration = builderAssistant.getConfiguration();this.builderAssistant = builderAssistant;this.languageDriver = configuration.getDefaultScriptingLanguageInstance();/* 注入自定义方法 */injectMappedStatement(mapperClass, modelClass, tableInfo);
}
4.UpdateById类实现AbstractMethod接口
public class UpdateById extends AbstractMethod {public UpdateById() {super(SqlMethod.UPDATE_BY_ID.getMethod());}/*** @since 3.5.0* @param name 方法名*/public UpdateById(String name) {super(name);}@Overridepublic MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {SqlMethod sqlMethod = SqlMethod.UPDATE_BY_ID;final String additional = optlockVersion(tableInfo) + tableInfo.getLogicDeleteSql(true, true);String sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(),sqlSet(tableInfo.isWithLogicDelete(), false, tableInfo, false, ENTITY, ENTITY_DOT),tableInfo.getKeyColumn(), ENTITY_DOT + tableInfo.getKeyProperty(), additional);SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);return addUpdateMappedStatement(mapperClass, modelClass, getMethod(sqlMethod), sqlSource);}
}
injectMappedStatement中生成全字段SQL脚本(
<script>
UPDATE xxxxx <set>
<if test="et['changeType'] != null">change_type=#{et.changeType},</if>
<if test="et['creator'] != null">creator=#{et.creator},</if>
<if test="et['createTime'] != null">create_time=#{et.createTime},</if>
update_time=now(),
</set> WHERE id=#{et.id} AND is_delete=0
</script>)
会被封装为 MyBatis 的 MappedStatement,并注册到 MyBatis 的 Configuration 中,
然后通过mapper代理调用