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 {

    @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());
    }
}

AbstractSqlInjector类实现了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注入器

创建一个类,将方法和sql做映射

public class MysqlDeleteAll extends AbstractMethod{
    @Override
    public 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;
    }
}

将自定义方法名添加到继承了BaseMapperEmployeeMapper

/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author Jian
 * @since 2021-05-21
 */
public interface EmployeeMapper extends BaseMapper<Employee> {

    public int deleteAll();

}

将自定义注入器注册到Spring容器中,并且将自定义的SQL注入器注册到全局策略配置

    <!--定义MyBatisPlus全局策略配置-->
    <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>

        <!--将自定义的SQL注入器注册到全局-->
        <property name="sqlInjector" ref="mySqlInjector"></property>

    </bean>

    <!--定义自定义的注入器bean-->
    <bean id="mySqlInjector" class="mpGenerator.injector.MySqlInjector"></bean>

测试自定义注入器的deleteAll方法

    @Test
    public void testDeleteAll(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        EmployeeMapper employeeMapper = context.getBean("employeeMapper",EmployeeMapper.class);

        int result = employeeMapper.deleteAll();

        System.out.println("result: " + result);
    }

打印日志:
在这里插入图片描述

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在 MyBatis Plus 中,你可以自定义主键生成来生成自定义的主键值。以下是一个示例: 1. 创建一个实现了 IdentifierGenerator 接口的自定义主键生成类,例如 CustomIdGenerator: ```java public class CustomIdGenerator implements IdentifierGenerator { @Override public Serializable nextId(Object entity) { // 这里编写自己的主键生成逻辑 // 返回生成的主键值 } } ``` 2. 在实体类中使用 @TableId 注解指定使用自定义主键生成,例如: ```java public class User { @TableId(type = IdType.ASSIGN_ID, generator = "customIdGenerator") private Long id; // 其他属性和方法省略 } ``` 3. 在 MyBatis Plus 的配置文件中配置自定义主键生成,例如 application.properties 或 application.yml: ```yaml mybatis-plus: global-config: db-config: id-type: auto # 设置全局的主键类型为自动增长 configuration: id-generator-type: custom # 设置自定义主键生成 ``` 4. 在 MyBatis Plus 的配置类中将自定义主键生成注册到 MyBatis 的全局配置中,例如: ```java @Configuration public class MybatisPlusConfig { @Bean public IdentifierGenerator customIdGenerator() { return new CustomIdGenerator(); } @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 添加其他拦截 return interceptor; } } ``` 通过以上步骤,你就可以使用自定义的主键生成来生成自定义的主键值了。请根据你的实际需求来编写自己的主键生成逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值