mybatis-plus高级功能 实现自定义通用方法详解

前言

MP在一开始就给大家提供了很多通用的方法,在DefaultSqlInjector这个类中,在MethodList这个集合当中包含的都是通用方法类,如果想要使用自定义通用方法,也需要添加到这个集合当中。

/**
 * SQL 默认注入器
 *
 * @author hubin
 * @since 2018-04-10
 */
public class DefaultSqlInjector extends AbstractSqlInjector {
 
    @Override
    public List<AbstractMethod> getMethodList() {
        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());
    }
}

实现自定义方法-以删除时填充为例:

  1. 创建自定义方法的类
  • 类名是DelFillUserMethod,这个是自定义的,但是最好是见名知意的类名。
  • 继承AbstractMethod抽象类,AbstractMethod是抽象的注入方法类,每个通用方法也都继承了这个类,也是为了方便调用里面的方法
  • 重写injectMappedStatement方法,injectMappedStatement内是我们完成我们这个方法具体的逻辑。
  • CustomSqlMethod是自定义的枚举类,我在下面已经贴出来了,这样可以使代码更优雅,我没有选择用官方提供的SqlMethod,是因为我怕到时候不容易维护,所以写了一个自己的,这个全看个人😄。
  • 具体内容我在代码中也有注释。

/**
 * @auther: zpq
 * @date: 2020/11/9 19:55
 * @description: 删除并填充删除人信息
 */
public class DelFillUserMethod extends AbstractMethod {

  @Override
  public MappedStatement injectMappedStatement(
      Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {

    // 获取用户信息
    String userId = UserContext.getCurrent() == null ? null : UserContext.getCurrent().getId2();
    String userName = UserContext.getCurrent() == null ? null : UserContext.getCurrent().getName();

	// set 语句
    String set = "set useflag = 0,deletetime = now(),operatetime = now()";

    if (StringUtils.isNotBlank(userId)) set += ",set deleterid = " + userId;
    if (StringUtils.isNotBlank(userName)) set += ",set deleter = " + userName;

    // 拿到我们定义好的枚举
    CustomSqlMethod sqlMethod = CustomSqlMethod.DEL_FILL_USER;

    /** * 组装自己的sql */
    String sql =
        String.format(
            // 定义好的sql
            sqlMethod.getSql(),
            // 表名
            tableInfo.getTableName(),
            // set 的值
            set,
            // 主键(数据库字段名)
            tableInfo.getKeyColumn(),
            // 实体类属性名
            tableInfo.getKeyProperty(),
            // and 主键 = yes | 如果是false的话就是 and 主键 = no
            tableInfo.getLogicDeleteSql(true, true));

    // 动态SQL标签处理器
    SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, Object.class);

    // 交给mp大佬们处理执行
    return addUpdateMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource);
  }
}
  • CustomSqlMethod枚举类内容
/**
 * @auther: zpq
 * @date: 2020/11/10 14:29
 * @description: 自定义通用sql与方法名称
 */
public enum CustomSqlMethod {
    /**
     * 插入
     */
    INSERT_ONE("insert", "插入一条数据(选择字段插入)", "<script>\nINSERT INTO %s %s VALUES %s\n</script>"),

    /**
     * 删除
     */
    DELETE_BY_ID("deleteById", "根据ID 删除一条数据", "<script>\nDELETE FROM %s WHERE %s=#{%s}\n</script>"),

    /**
     * 逻辑删除
     */
    LOGIC_DELETE_BY_ID("deleteById", "根据ID 逻辑删除一条数据", "<script>\nUPDATE %s %s WHERE %s=#{%s} %s\n</script>"),

    /**
     * 逻辑删除 -> 修改
     */
    DEL_FILL_USER("delFillUser", "删除填充用户信息", "<script>\nUPDATE %s %s WHERE %s=#{%s} %s\n</script>"),
    BATCH_DEL_FILL_USER("batchDelFillUser", "批量删除填充用户信息", "<script>\nUPDATE %s %s WHERE %s IN (%s) %s\n</script>"),

    /**
     * 查询
     */
    SELECT_OBJS("selectObjs", "查询满足条件所有数据", "<script>%s SELECT %s FROM %s %s %s\n</script>");

    private final String method;
    private final String desc;
    private final String sql;

    CustomSqlMethod(String method, String desc, String sql) {
        this.method = method;
        this.desc = desc;
        this.sql = sql;
    }

    public String getMethod() {
        return method;
    }

    public String getDesc() {
        return desc;
    }

    public String getSql() {
        return sql;
    }

}
  1. 创建注入器,并把自定义的方法添加到集合当中。
  • 类名是CustomSqlInjector,自定义的
  • 继承DefaultSqlInjector并重写getMethodList,SQL 默认注入器上面也有提到过,我们得把我们自定义的方法加入到通用方法的集合methodList当中
/**
 * @auther: zpq
 * @date: 2020/11/9 20:00
 * @description: 自定义sql注入器
 * 把自定义的通用方法加入mp的方法集合
 */
@Component
public class CustomSqlInjector extends DefaultSqlInjector {

  @Override
  public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
    // 这里很重要,先要通过父类方法,获取到原有的集合,不然会自带的通用方法会失效的
    List<AbstractMethod> methodList = super.getMethodList(mapperClass);

    /***
     * 添加自定义方法类
     */
    methodList.add(new DelFillUserMethod());
    methodList.add(new BatchDelFillUserMethod());

    return methodList;
  }
}
  1. 最后一步就是在*.dao.*Mapper中加入自定义方法 如下:
  /**
   * @Description: 删除并填充删除人信息
   *
   * @param: id 主键id
   * @auther: zpq
   * @date: 2020/11/10 11:47 上午
   */
  int delFillUser(Serializable id);
  1. 其实以上就算完成了,但是如果同时有好几个Mapper需要用到这个自定义通用方法,这样可能不是那么优雅。
  • 我们创建一个通用SuperMapper,然后继承BaseMapper,这样的话,用到这个方法的mapper只需要继承SuperMapper就可以了,如下:
/**
 * @auther: zpq
 * @date: 2020/11/9 20:10
 * @description: 通用mapper
 */
public interface SuperMapper<T> extends BaseMapper<T> {

  /**
   * @Description: 删除并填充删除人信息
   *
   * @param: id 主键id
   * @auther: zpq
   * @date: 2020/11/10 11:47 上午
   */
  int delFillUser(Serializable id);

  /**
   * @Description: 批量删除并填充删除人信息
   *
   * @param: idList 主键ID列表(不能为 null 以及 empty)
   * @auther: zpq
   * @date: 2020/11/10 3:12 下午
   */
  int batchDelFillUser(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
}
  1. 你可能也已经发现自定义的批量操作的通用方法,我直接贴出来:
/**
 * @auther: zpq
 * @date: 2020/11/10 14:59
 * @description: 批量删除填充用户信息
 */
public class BatchDelFillUserMethod extends AbstractMethod {

  @Override
  public MappedStatement injectMappedStatement(
      Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {

    // 获取用户信息
    String userId = UserContext.getCurrent() == null ? null : UserContext.getCurrent().getId2();
    String userName = UserContext.getCurrent() == null ? null : UserContext.getCurrent().getName();

    // 自己组装sql
    String set = "set useflag = 0,deletetime = now(),operatetime = now()";

    if (StringUtils.isNotBlank(userId)) set += ",set deleterid = " + userId;
    if (StringUtils.isNotBlank(userName)) set += ",set deleter = " + userName;

    // 拿到我们定义好的sql
    CustomSqlMethod sqlMethod = CustomSqlMethod.BATCH_DEL_FILL_USER;

    // 填充sql
    String sql =
        String.format(
            sqlMethod.getSql(),
            tableInfo.getTableName(),
            set,
            tableInfo.getKeyColumn(),
            // foreach in(ids)
            SqlScriptUtils.convertForeach("#{item}", COLLECTION, null, "item", COMMA),
            tableInfo.getLogicDeleteSql(true, true));

    // 动态SQL标签处理器
    SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, Object.class);

    return addUpdateMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource);
  }
}

结束语:

到此mybatis-plus高级功能 实现自定义通用方法详解就结束了,其实很简单,写其他方法也一样,对照着mybatis-plus源码照着抄就行哈哈哈。。。

MyBatis-Plus代码生成器提供了自定义模板的功能,可以根据自己的需求生成对应的代码。下面是自定义模板的处理步骤: 1. 在代码生成器的配置文件中,设置自定义模板的路径。例如: ``` <property name="templatePath" value="/templates/mybatis-plus"/> ``` 2. 在自定义模板路径下创建对应的模板文件。例如,创建一个模板文件 `Entity.java.vm`,用于生成实体类的代码。 3. 在模板文件中使用 Velocity 模板语言,编写生成代码的逻辑。例如: ``` package ${package_name}.${module_name}.entity; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; /** * <p> * ${table_comment} * </p> */ @Data @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) @TableName("${table_name}") public class ${entity_name} { private static final long serialVersionUID = 1L; #foreach($field in $fields) /** * ${field.comment} */ private ${field.javaType} ${field.name}; #end } ``` 4. 在代码生成器中配置要使用的自定义模板。例如: ``` <property name="templateConfig"> <bean class="com.baomidou.mybatisplus.generator.config.TemplateConfig"> <property name="entity" value="/templates/mybatis-plus/Entity.java.vm"/> <property name="mapper" value="/templates/mybatis-plus/Mapper.java.vm"/> <property name="xml" value="/templates/mybatis-plus/Mapper.xml.vm"/> <property name="service" value="/templates/mybatis-plus/Service.java.vm"/> <property name="serviceImpl" value="/templates/mybatis-plus/ServiceImpl.java.vm"/> <property name="controller" value="/templates/mybatis-plus/Controller.java.vm"/> </bean> </property> ``` 在这个例子中,我们配置了生成实体类、Mapper接口、Mapper XML文件、Service接口、Service实现类和Controller类的模板路径。 5. 运行代码生成器,即可根据自定义模板生成对应的代码。 注意:自定义模板的命名必须与 MyBatis-Plus 内置模板的命名一致,才能正确覆盖内置模板。例如,要自定义生成实体类的模板,必须将模板文件命名为 `Entity.java.vm`。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhopq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值