术语:逻辑删除,就是实际上不在物理上删除所操作的记录,只是在数据库的特定字段上修改为“被删除状态”。

逻辑删除适用于可以进行数据恢复有关联数据,不便删除的场景。所谓的逻辑删除,实际上就是假删除,将对应数据中代表是否被删除字段状态修改为"被删除状态",之后在数据库中仍能看到这条数据记录。

实现

一、建立 删除标记字段

如: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
         }
     }