MyBatisPlus自定义全局SQL注入器
一、ISqlInjector自动注入器接口
通过实现MyBatisPlus的ISqlInjector接口可以自定义各种sql,注入到全局中,相当于自定义的MyBatisPlus自动注入的方法。之前需要在xml中进行配置的sql语句,现在通过扩展ISqlInjector接口在加载MyBatis环境时就注入。
DefaultSqlInjector是默认SQL注入器,它继承了AbstractSqlInjector,如果想要扩展SQL注入器,可以通过继承DefaultSqlInjector来实现
/*** SQL 默认注入器** @author hubin* @since 2018-04-10*/
public class DefaultSqlInjector extends AbstractSqlInjector {@Overridepublic 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());}
}
AbstractSqlInjector类实现了ISqlInjector接口
/*** SQL 自动注入器** @author hubin* @since 2018-04-07*/
public abstract class AbstractSqlInjector implements ISqlInjector {private static final Log logger = LogFactory.getLog(AbstractSqlInjector.class);@Overridepublic 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);}}}/*** * 获取 注入的方法*
** @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注入器
创建一个类,将方法和sql做映射
public class MysqlDeleteAll extends AbstractMethod{@Overridepublic MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {String sql = "delete from " + tableInfo.getTableName();String methodName = "deleteAll";// 进行预编译得到sqlSource对象SqlSource sqlSource = languageDriver.createSqlSource(configuration,sql,modelClass);//添加到delete操作的Statement中也就是相当于将预编译sql和其它的delete相关的编译后的sql存在一起//将EmployeeMapper中定义的deleteAll处理成对应的MapperedStatement对象,加入到configuration对象中return addDeleteMappedStatement(mapperClass, methodName,sqlSource);}
}
创建自定义的注入器,继承DefaultSqlInjector,将sql与方法绑定的实例交给Spring来管理
/*** 自定义SQL注入器*/
public class MySqlInjector extends DefaultSqlInjector{public List<AbstractMethod> getMethodList(Class<?> mapperClass) {/* 如果只需增加方法,保留MP自带方法* 可以super.getMethodList() 再add** */List<AbstractMethod> methodList = super.getMethodList(mapperClass);methodList.add(new MysqlDeleteAll());return methodList;}
}
将自定义方法名添加到继承了BaseMapper的EmployeeMapper中
/*** * Mapper 接口*
** @author Jian* @since 2021-05-21*/
public interface EmployeeMapper extends BaseMapper<Employee> {public int deleteAll();}
将自定义注入器注册到Spring容器中,并且将自定义的SQL注入器注册到全局策略配置
<bean id="globalConfig" class="com.baomidou.mybatisplus.core.config.GlobalConfig"><property name="dbConfig"><bean class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig"><property name="tableUnderline" value="true">property><property name="idType" value="AUTO">property><property name="tablePrefix" value="tbl_">property>bean>property><property name="sqlInjector" ref="mySqlInjector">property>bean><bean id="mySqlInjector" class="mpGenerator.injector.MySqlInjector">bean>
测试自定义注入器的deleteAll方法
@Testpublic void testDeleteAll(){ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");EmployeeMapper employeeMapper = context.getBean("employeeMapper",EmployeeMapper.class);int result = employeeMapper.deleteAll();System.out.println("result: " + result);}
打印日志:

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
