通过实现MyBatisPlus的 ISqlInjector 接口可以自定义各种sql,注入到全局中,相当于自定义的MyBatisPlus 自动注入的方法。之前需要在xml中进行编写sql语句,现在通过扩展 ISqlInjector 接口在加载MyBatis-Plus环境时就注入。
ISqlInjector自动注入器接口
/**
* SQL 自动注入器
*
* @author hubin
* @since 2018-04-07
*/
public abstract class AbstractSqlInjector implements ISqlInjector {
private static final Log logger = LogFactory.getLog(AbstractSqlInjector.class);
@Override
public void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass) {
Class<?> modelClass = extractModelClass(mapperClass);
if (modelClass != null) {
String className = mapperClass.toString();
Set<String> mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration());
if (!mapperRegistryCache.contains(className)) {
List<AbstractMethod> methodList = this.getMethodList(mapperClass);
if (CollectionUtils.isNotEmpty(methodList)) {
TableInfo tableInfo = TableInfoHelper.initTableInfo(builderAssistant, modelClass);
// 循环注入自定义方法
methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo));
} else {
logger.debug(mapperClass.toString() + ", No effective injection method was found.");
}
mapperRegistryCache.add(className);
}
}
}
/**
* <p>
* 获取 注入的方法
* </p>
*
* @param mapperClass 当前mapper
* @return 注入的方法集合
* @since 3.1.2 add mapperClass
*/
public abstract List<AbstractMethod> getMethodList(Class<?> mapperClass);
/**
* 提取泛型模型,多泛型的时候请将泛型T放在第一位
*
* @param mapperClass mapper 接口
* @return mapper 泛型
*/
protected Class<?> extractModelClass(Class<?> mapperClass) {
Type[] types = mapperClass.getGenericInterfaces();
ParameterizedType target = null;
for (Type type : types) {
if (type instanceof ParameterizedType) {
Type[] typeArray = ((ParameterizedType) type).getActualTypeArguments();
if (ArrayUtils.isNotEmpty(typeArray)) {
for (Type t : typeArray) {
if (t instanceof TypeVariable || t instanceof WildcardType) {
break;
} else {
target = (ParameterizedType) type;
break;
}
}
}
break;
}
}
return target == null ? null : (Class<?>) target.getActualTypeArguments()[0];
}
}
/**
* SQL 默认注入器
*
* @author hubin
* @since 2018-04-10
*/
public class DefaultSqlInjector extends AbstractSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
return Stream.of(
new Insert(),
new Delete(),
new DeleteByMap(),
new DeleteById(),
new DeleteBatchByIds(),
new Update(),
new UpdateById(),
new SelectById(),
new SelectBatchByIds(),
new SelectByMap(),
new SelectOne(),
new SelectCount(),
new SelectMaps(),
new SelectMapsPage(),
new SelectObjs(),
new SelectList(),
new SelectPage()
).collect(toList());
}
}
上述就是默认的sql注入器,由此我们可以看到,当我们的mapper接口继承了BaseMapper后的17个方法就在此注入的
我们点开一个Delete查看
/**
* 根据 entity 条件删除记录
*
* @author hubin
* @since 2018-04-06
*/
public class Delete extends AbstractMethod {
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
String sql;
SqlMethod sqlMethod = SqlMethod.LOGIC_DELETE;
if (tableInfo.isWithLogicDelete()) {
sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), sqlLogicSet(tableInfo),
sqlWhereEntityWrapper(true, tableInfo),
sqlComment());
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
return addUpdateMappedStatement(mapperClass, modelClass, getMethod(sqlMethod), sqlSource);
} else {
sqlMethod = SqlMethod.DELETE;
sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(),
sqlWhereEntityWrapper(true, tableInfo),
sqlComment());
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
return this.addDeleteMappedStatement(mapperClass, getMethod(sqlMethod), sqlSource);
}
}
}
自定义sql注入器
创建 DeleteAll 并继承 AbstractMethod
/**
* 定义 delete All
*/
public class DeleteAll extends AbstractMethod {
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
//注意: 此方法名要和你自己的mapper中一致
String methodName = "deleteAll";
String sql = "delete from " + tableInfo.getTableName();
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, Object.class);
return this.addDeleteMappedStatement(mapperClass, methodName, sqlSource);
}
}
创建自定义的注入器,继承 AbstractSqlInjector
/**
* 自定义全局sql注入
*/
public class MySqlInjector extends AbstractSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
return Stream.of(new DeleteAll())
.collect(toList());
}
}
mapper中使用
public interface DeptMapper extends BaseMapper<Dept> {
int deleteAll();
}
注入到ioc容器
@Bean
public MySqlInjector mySqlInjector(){
return new MySqlInjector();
}