TkMybatis:tkmapper功能扩展逻辑删除

文章介绍了在项目中因tk.mapper组件版本较低不支持逻辑删除,而通过自定义注解LogicDelete、扩展SqlHelper、提供者ExtBaseProvider以及创建ExtBaseMapper来实现逻辑删除的功能。主要步骤包括定义逻辑删除注解、更新字段处理、动态SQL生成以及定制Mapper接口。
摘要由CSDN通过智能技术生成

前言

项目中的数据删除需要执行逻辑删除,而不是物理删除,由于项目中数据访问层使用的tkmapper组件版本比较低,暂不支持逻辑删除操作(新版本已经支持),在此基础上通过tk提供的扩展自定义逻辑删除处理功能。

自定义扩展

POM引入库

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.18.20</version>
</dependency>

<!-- https://mvnrepository.com/artifact/tk.mybatis/mapper-spring-boot-starter -->
<dependency>
  <groupId>tk.mybatis</groupId>
  <artifactId>mapper-spring-boot-starter</artifactId>
  <version>2.0.4</version>
</dependency>

新增注解LogicDelete

代码如下:

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义逻辑删除注解
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface LogicDelete {

    /**
     * 正常的值:由于数据库使用的是number类型,所以我这边写默认值为0
     */
    String value() default "0";

    /**
     * 删除的值:由于数据库使用的是number类型,所以我这边写默认值为1
     */
    String devval() default "1";

}

扩展SqlHelper

代码如下:

import com.jyusun.origin.example.boot.tk.annotation.LogicDelete;
import lombok.experimental.UtilityClass;
import tk.mybatis.mapper.annotation.Version;
import tk.mybatis.mapper.entity.EntityColumn;
import tk.mybatis.mapper.mapperhelper.EntityHelper;
import tk.mybatis.mapper.mapperhelper.SqlHelper;
import tk.mybatis.mapper.version.VersionException;

import java.util.Set;

/**
 * 作用描述:扩展SqlHelper
 *
 * @author jyusun at 2023/6/2 17:02
 * @since 1.0.0
 */
@UtilityClass
public class ExtSqlHelper extends SqlHelper {

    /**
     * 逻辑删除sql拼接处理
     *
     * @param entityClass
     * @return
     */
    public static String logicDeleteSetColumns(Class<?> entityClass) {
        StringBuilder sql = new StringBuilder();
        sql.append("<set>");
        //获取全部列
        Set<EntityColumn> columnSet = EntityHelper.getColumns(entityClass);
        //对乐观锁的支持
        EntityColumn versionColumn = null;
        EntityColumn logicDelete = null;
        //当某个列有主键策略时,不需要考虑他的属性是否为空,因为如果为空,一定会根据主键策略给他生成一个值
        for (EntityColumn column : columnSet) {
            // 乐观锁注解获取
            if (column.getEntityField()
                      .isAnnotationPresent(Version.class)) {
                if (versionColumn != null) {
                    throw new VersionException(entityClass.getCanonicalName() + " 中包含多个带有 @Version " + 
                            "注解的字段,一个类中只能存在一个带有" + " @Version 注解的字段!");
                }
                versionColumn = column;
            }
            // 逻辑删除注解获取
            if (column.getEntityField()
                      .isAnnotationPresent(LogicDelete.class)) {
                if (logicDelete != null) {
                    throw new VersionException(entityClass.getCanonicalName() + " 中包含多个带有 @LogicDelete " + 
                            "注解的字段,一个类中只能存在一个带有 @LogicDelete 注解的字段!");
                }
                logicDelete = column;
            }
            if (!column.isId() && column.isUpdatable()) {
                if (column == versionColumn) {
                    Version version = versionColumn.getEntityField()
                                                   .getAnnotation(Version.class);
                    String versionClass = version.nextVersion()
                                                 .getCanonicalName();
                    //version = ${@tk.mybatis.mapper.version@nextVersionClass("versionClass", version)}
                    sql.append(column.getColumn())
                       .append(" = ${@tk.mybatis.mapper.version.VersionUtil@nextVersion(")
                       .append("@")
                       .append(versionClass)
                       .append("@class, ")
                       .append(column.getProperty())
                       .append(")},");
                }
                // 组装逻辑删除的set条件  set LogicDelete 注解标记的属性 isde = 1
                if (column == logicDelete) {
                    LogicDelete logic = logicDelete.getEntityField()
                                                     .getAnnotation(LogicDelete.class);
                    String delval = logic.delval();
                    sql.append(column.getColumn())
                       .append(" = ")
                       .append(delval)
                       .append(",");
                }
            }
        }
        sql.append("</set>");
        return sql.toString();
    }
}

扩展Provider

代码如下:

import org.apache.ibatis.mapping.MappedStatement;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
import tk.mybatis.mapper.mapperhelper.MapperTemplate;
import tk.mybatis.mapper.mapperhelper.SqlHelper;

/**
 * 作用描述:
 *  扩展 MapperTemplate
 *
 * @author jyusun at 2023/6/2 16:44
 * @since 1.0.0
 */
public class ExtBaseProvider extends MapperTemplate {
    public ExtBaseProvider(Class<?> mapperclass, MapperHelper mapperHelper) {
        super(mapperclass, mapperHelper);
    }

    public String customDeleteLogic(MappedStatement ms) {
        Class<?> entityClass = getEntityClass(ms);
        StringBuilder sql = new StringBuilder();
        sql.append(SqlHelper.updateTable(entityClass,tableName(entityClass)));
        sql.append(ExtSqlHelper.logicDeleteSetColumns(entityClass));
        sql.append(SqlHelper.wherePKColumns(entityClass));
        return sql.toString();
    }
}

扩展Mapper

代码如下:

import org.apache.ibatis.annotations.UpdateProvider;
import tk.mybatis.mapper.annotation.RegisterMapper;
import tk.mybatis.mapper.common.BaseMapper;

/**
 * 扩展 BaseMapper
 */
@RegisterMapper
public interface ExtBaseMapper<T> extends BaseMapper<T> {

    /**
     * 自定义逻辑删除
	 * 
	 * @param obj 数据对象
	 * @return {@code Integer} 操作状态
     */
    @UpdateProvider(type = ExtBaseProvider.class, method = "dynamicSQL")
    int customDeleteLogic(Object obj);
    
}

总结

  1. 自定定义注解:LogicDelete
  2. 更新处理:ExtSqlHelper 定义一个方法 logicDeleteSetColumns 拼接字段更新处理
  3. 自定义提供者:ExtBaseProvider extends MapperTemplate,主要用于动态生成SQL
  4. 自定义映射器:ExtBaseMapper 注册 @RegisterMapper
  5. ExtBaseMapper 自定义方法:customDeleteLogic 指定提供者,ExtBaseMapper 与 ExtBaseProvider 方法名对应
  6. ExtBaseMapper.customDeleteLogic 方法标记 @UpdateProvider注解并指定type 属性为上面定义的提供者,指定method 属性"dynamicSQL"(动态SQL)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值