【黑马程序员2022新版SSM框架教程_Spring+SpringMVC+Maven高级+SpringBoot+MyBatisPlus企业实用开发技术】
【一个问题】
这是一个员工和其所签的合同表,关系是一个员工可以签多个合同,是一个一(员工)对多(合同)的表
员工ID为1的张业绩,总共签了三个合同,如果此时他离职了,需要将员工表中的数据进行删除,会执行delete操作
如果表在设计的时候有主外键关系,那么同时也得将合同表中的前三条数据也删除掉
后期要统计所签合同的总金额,就会发现对不上,原因是已经将员工1签的合同信息删除掉了
如果只删除员工不删除合同表数据,那么合同的员工编号对应的员工信息不存在,那么就会出现垃圾数据,就会出现无主合同,根本不知道有张业绩这个人的存在
所以经过分析,我们不应该将表中的数据删除掉,而是需要进行保留,但是又得把离职的人和在职的人进行区分,这样就解决了上述问题,如:
区分的方式,就是在员工表中添加一列数据deleted,如果为0说明在职员工,如果离职则将其改完1,(0和1所代表的含义是可以自定义的)
【对于删除操作业务的问题】
【MP 中实现逻辑删除】
① 修改数据库表添加deleted列
字段名可以任意,内容也可以自定义,比如0代表正常,1代表删除,可以在添加列的同时设置其默认值为0正常
查看数据表
② 实体类添加属性
1 添加与数据库表的列对应的一个属性名,名称可以任意,如果和数据表列名对不上,可以使用@TableField进行关系映射,如果一致,则会自动对应
2 标识新增的字段为逻辑删除字段,使用@TableLogic
value为正常数据的值,delval为删除数据的值
③ 运行删除方法
从测试结果来看,逻辑删除最后走的是update操作,会将指定的字段修改成删除状态对应的值。
查看数据库
这样看来,好像并没有真正删除数据,这样做对查询有影响吗?
【执行查询操作】
@Test
void testFind(){
System.out.println(userDao.selectList(null));
}
测试结果
可以看到已经查不出id 为 1L的数据了。而且查询语句自动多了一个条件判断。
MP的逻辑删除会将所有的查询都添加一个未被删除的条件,也就是已经被删除的数据是不应该被查询出来的。
【如果想把已经被逻辑删除的数据上查询出来】
package com.dingjiaxiong.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dingjiaxiong.domain.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* ClassName: UserDao
* date: 2022/9/24 14:02
*
* @author DingJiaxiong
*/
@Mapper
public interface UserDao extends BaseMapper<User> {
//查询所有数据【包含已经被逻辑删除了数据】
@Select("select * from tbl_user")
public List<User> selectAll();
}
自己在数据层定义接口方法。
测试
这样就“强行”被查出来了。
【优化】
如果每个表都要有逻辑删除,那么就需要在每个模型类的属性上添加@TableLogic注解,如何优化?
在配置文件中添加全局配置,如下:
db-config:
# 逻辑删除字段名
logic-delete-field: deleted
# 逻辑删除字面值:未删除为0
logic-not-delete-value: 0
# 逻辑删除字面值:删除为1
logic-delete-value: 1
【逻辑删除的本质】
逻辑删除的本质其实是修改操作。如果加了逻辑删除字段,查询数据时也会自动带上逻辑删除字段的条件。
执行的SQL语句为:
UPDATE tbl_user SET deleted=1 where id = ? AND deleted=0
【知识点1:@TableLogic】