版本
- jpa maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>3.3.1</version>
</dependency>
- springboot 版本:3.3.1
简单使用
只需在实体类上@SoftDelete 即可实现逻辑删除
例如:
@SoftDelete
public class Student {
// 省略。。。。
}
默认配置使用 DELETED策略,并作为布尔值存储在 deleted字段中。
@SoftDelete 的定义
@Target({ElementType.PACKAGE, ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Incubating
public @interface SoftDelete {
String columnName() default "";
SoftDeleteType strategy() default SoftDeleteType.DELETED;
Class<? extends AttributeConverter<Boolean, ?>> converter() default UnspecifiedConversion.class;
public interface UnspecifiedConversion extends AttributeConverter<Boolean, Object> {
}
}
columnName 为逻辑删除字段列名,converter 的一个数据库存在字段值到表示删除的转换器,比如如果我们想让1表示已删除0表示未删除可以用内置的NumericBooleanConverter 转换器。
进阶
自定义converter
只是使用0和1表示删除状态无法满足唯一索引的应用场景,我们可以使用删除时间表示删除状态,这时我们就需要自定义converter,示例:
package com.breeze.jpa.extension.converter;
import jakarta.persistence.AttributeConverter;
/**
* 用于软删除
* @author fan
* @date 2024/8/6
*/
public class TimestampBooleanConverter implements AttributeConverter<Boolean,Long> {
@Override
public Long convertToDatabaseColumn(Boolean aBoolean) {
return Boolean.TRUE.equals(aBoolean) ? System.currentTimeMillis() : 0L;
}
@Override
public Boolean convertToEntityAttribute(Long aLong) {
return aLong != null && aLong > 0L;
}
}
这样当执行查询操作时jpa会通过调用convertToDatabaseColumn方法获取未删除状态对应的数据库字段存储值,对应是0,添加过滤条件where f1_0.delete_at=0。删除时也调用convertToDatabaseColumn传入true返回当前时间戳 例如:
update foo set delete_at=1725809750120 where id=? and delete_at=0 and version=?