对于一些比较重要的数据,我们往往会采用逻辑删除的方案,即:
-
在表中添加一个字段标记数据是否被删除
-
当删除数据时把标记置为true
-
查询时过滤掉标记为true的数据
一旦采用了逻辑删除,所有的查询和删除逻辑都要跟着变化,非常麻烦。
为了解决这个问题,MybatisPlus就添加了对逻辑删除的支持。
注意,只有MybatisPlus生成的SQL语句才支持自动的逻辑删除,自定义SQL需要自己手动处理逻辑删除。
例如,我们给address
表添加一个逻辑删除字段:
alter table address add deleted bit default b'0' null comment '逻辑删除';
然后给Address
实体添加deleted
字段:
接下来,我们要在application.yml
中配置逻辑删除字段:
mybatis-plus:
global-config:
db-config:
logic-delete-field: deleted # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
测试:
首先,我们执行一个删除操作:
@Test
void testDeleteByLogic() {
// 删除方法与以前没有区别
addressService.removeById(59L);
}
方法与普通删除一模一样,但是底层的SQL逻辑变了:
查询一下试试:
@Test
void testQuery() {
List<Address> list = addressService.list();
list.forEach(System.out::println);
}
会发现id为59的确实没有查询出来,而且SQL中也对逻辑删除字段做了判断:
综上, 开启了逻辑删除功能以后,我们就可以像普通删除一样做CRUD,基本不用考虑代码逻辑问题。还是非常方便的。
注意: 逻辑删除本身也有自己的问题,比如:
-
会导致数据库表垃圾数据越来越多,从而影响查询效率
-
SQL中全都需要对逻辑删除字段做判断,影响查询效率
因此,我不太推荐采用逻辑删除功能,如果数据不能删除,可以采用把数据迁移到其它表的办法。