术语:逻辑删除,就是实际上不在物理上删除所操作的记录,只是在数据库的特定字段上修改为“被删除状态”。
逻辑删除适用于可以进行数据恢复
或有关联数据,不便删除的场景
。所谓的逻辑删除,实际上就是假删除
,将对应数据中代表是否被删除字段状态修改为"被删除状态",之后在数据库中仍能看到这条数据记录。
实现:
一、建立 删除标记字段
如:deleted 默认为0, 0表示未逻辑删除,1表示逻辑删除
二、在实体类上标注
@TableLogic //逻辑删除标注字段 private Integer deleted;
@TableLogic
注解表示逻辑删除,如果在字段上加上这个注解再执行BaseMapper的删除方法时,删除方法会变成修改方法。除此之外,若再使用Mybatisplus自带的查询, 也会不查询那些已经被删除的数据。
三、修改yml配置文件,全局有效
# MyBatis-Plus的全局配置 mybatis-plus: global-config: db-config: # 那个字段是逻辑删除字段,也可以在字段上添加注解@TableLogic,在这里边配置是全局生效 logic-delete-field: deleted # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2) logic-delete-value: 1 # 逻辑已删除值(默认为 1) logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
四、测试
1、插入新记录
User user = new User(23L,"Tomas",18,"bj@163.com","187678"); int i=userMapper.insert(user);
其中,deleted列,不需要指定值,默认为 0
2、删除某记录
int i = userMapper.deleteById(23);
操作结果:数据库表中,deleted修改为1了。
实际,MP配置了逻辑删除后,执行delete相关方法后,会实际了执行update方法,将逻辑删除的字段进行更改。
23,Tomas,18,bj@163.com,187678,1
3、查询指定的逻辑删除的字段
User user = userMapper.selectById(23); System.out.println(user);
返回:null 。因为该记录已经被逻辑删除(空,不存在)
Q:能否直接更新该字段?
A:使用update相关方法将此逻辑字段进行更新则是不可以的
User user = new User(); user.setId(23L); user.setAge(29); user.setDeleted(0); userMapper.updateById(user); System.out.println(user);
实际执行:
==> Preparing: UPDATE testdb.user SET age=? WHERE id=? AND deleted=0
==> Parameters: 29(Integer), 23(Long)
<== Updates: 0
可见,被标注为逻辑删除的
数据库中,该记录的 deleted字段为1,所以找不到该字段,更谈不上deleted字段更新为0。
重要:
如何查询所有逻辑删除的数据?
如何将逻辑删除的数据恢复为未被删除?
因为MB只是一个增强插件,不影响原本的Mybatis。所以,自定义了Mapper方法。
@Repository
public interface UserMapper extends BaseMapper<User> {
List<User> selectAllDeleted();//查询is_deleted值为1的所有数据
int updaDeleted(Long id);//修改is-deleted的值为0
}
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace表示命名空间 -->
<mapper namespace="com.example.mybatisplusdemo.mapper.UserMapper">
<!-- 修改值为0-->
<update id="updaDeleted">
update user set is_deleted=0
<where>
id=#{id}
</where>
</update>
<!-- 查询is_deleted值为1的所有数据-->
<select id="selectAllDeleted" resultType="com.example.mybatisplusdemo.pojo.User">
select * from user
<where>
is_deleted = 1
</where>
</select>
</mapper>
自定义Mapper方法,进行修改,就避开了自带逻辑删除属性的问题!!!
测试方法如下:
@Test
public void t8(){
List<User> list = userMapper.selectAllDeleted();//获取逻辑删除属性为1的所有数据
User user = null;
for (int i = 0; i < list.size(); i++) { //遍历列表
user = list.get(i);
user.setIsDeleted(0); //设置逻辑删除的值为0,默认值就是0
userMapper.updaDeleted(user.getId()); //逐一修改逻辑删除属性的值,改为0
}
}