逻辑删除对应的是物理删除,分别介绍一下这两个概念:
- 物理删除 :指的是真正的删除,即:当执行删除操作时,将数据表中的数据进行删除,之后将无法再查询到该数据
- 逻辑删除 :并不是真正意义上的删除,只是对于用户不可见了,它仍然存在与数据表中
在这个数据为王的时代,数据就是财富,所以一般并不会有哪个系统在删除某些重要数据时真正删掉了数据,通常都是在数据库中建立一个状态列,让其默认为 0,当为 0 时,用户可见;当执行了删除操作,就将状态列改为 1,此时用户不可见,但数据还是在表中的。
按照《阿里巴巴Java开发手册》第 5 章 MySQL 数据库相关的建议,我们来为数据表新增一个is_deleted 字段:
ALTER TABLE tbl_employee ADD COLUMN is_deleted TINYINT NOT NULL DEFAULT 0;
在实体类中也要添加这一属性:
@Data
@TableName("tbl_employee")
public class Employee {
@TableId(type = IdType.AUTO)
private Long id;
private String lastName;
private String email;
private Integer age;
@TableField(fill = FieldFill.INSERT)
private LocalDateTime gmtCreate;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime gmtModified;
/**
* 逻辑删除属性
*/
@TableLogic
@TableField("is_deleted")
private Boolean deleted;
}
还是参照《阿里巴巴Java开发手册》第 5 章 MySQL 数据库相关的建议,对于布尔类型变量,不能加 is 前缀,所以我们的属性被命名为 deleted,但此时就无法与数据表的字段进行对应了,所以我们需要使用 @TableField 注解来声明一下数据表的字段名,而 @TableLogin 注解用于设置逻辑删除属性;此时我们执行删除操作:
@Test
void contextLoads() {
employeeService.removeById(2);
}
查询数据表执行结果:
可以看到数据并没有被删除,只是 is_deleted 字段的属性值被更新成了 1,此时我们再来执行查询操作:
@Test
void contextLoads() {
List<Employee> list = employeeService.list();
list.forEach(System.out::println);
}
执行结果:
会发现id为2的数据并没有被查询出来,可以输出 MyBatisPlus 生成的 SQL 来分析一下,在配置文件中进行配置:
logging:
level:
com.example.demo.mapper: debug
再次运行查看结果:
原来在查询时携带了一个条件: is_deleted=0 ,这也说明了 MyBatisPlus 默认 0 为不删除,1 为删除。 若是想修改这个规定,比如设置-1 为删除,1 为不删除,也可以进行配置:
mybatis-plus:
global-config:
db-config:
logic-delete-field: deleted # 逻辑删除属性名
logic-delete-value: -1 # 删除值
logic-not-delete-value: 1 # 不删除值
但建议使用默认的配置,阿里巴巴开发手册也规定 1 表示删除,0 表示未删除。