1.版本 : mybatis-plus-core 3.5.1
2.入口:MybatisPlusAutoConfiguration类sqlSessionFactory中的factory.getObject()
3.注入AbstractSqlInjector类中的inspectInject方法中
@Override
public 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增加所有的默认方法
@Override
public 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);
}
@Override
public 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代理调用