MyBatis-Plus 之逻辑删除

2022-08-31 10:00:42 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

推荐:MyBatis Plus汇总

MyBatis-Plus 之逻辑删除

概念

  • 逻辑删除:文件没有被真正的删除,通常这种删除操作是可逆的,就是说用适当的工具或软件可以把删除的文件恢复出来。
  • 物理删除:指文件存储所用到的存储区域被真正的擦除或清零,这样删除的文件是不可以恢复的,物理删除是计算机处理数据时的一个概念。

逻辑删除就是对要被删除的数据打上一个删除标记,在逻辑上,数据是被删除了,但数据本身依然存在!而物理删除则是把数据从介质上彻底删除掉。

正文

首先创建一个数据库表,如下图所示:

然后创建一个Spring Boot项目。

pom.xml如下:

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.kaven</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

application.yml如下:

代码语言:javascript复制
spring:
  application:
    name: mybatis-plus
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: ITkaven@123
    url: jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf-8&useSSL=false

server:
  port: 8085

logging:
  level:
    root: warn
    com.kaven.mybatisplus.dao: trace
  pattern:
    console: '%p%m%n'

mybatis-plus:
  global-config:
    db-config:
      logic-delete-value: 1
      logic-not-delete-value: 0

实体类User:

代码语言:javascript复制
package com.kaven.mybatisplus.entity;

import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;

@TableName("user")
@Data
public class User{ 
   

    @TableId
    private String id;

    @TableField(value = "username")
    private String username;

    @TableField(value = "password")
    private String password;

    @TableField(value = "age")
    private Integer age;
    
// @TableLogic(delval = "1" , value = "0") 每个实体类中可以定义逻辑删除配置
    @TableLogic
    @TableField(value = "deleted")
    private Integer deleted;

    /** * 使用 @TableField(exist = false) ,表示该字段在数据库中不存在 ,所以不会插入数据库中 * 使用 transient 、 static 修饰属性也不会插入数据库中 */
    @TableField(exist = false)
    private String phone;
}

Mapper接口UserMapper:

代码语言:javascript复制
package com.kaven.mybatisplus.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.kaven.mybatisplus.entity.User;
import org.springframework.stereotype.Component;


@Component
public interface UserMapper extends BaseMapper<User> { 
   }

启动类:

代码语言:javascript复制
package com.kaven.mybatisplus;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan(basePackages = "com.kaven.mybatisplus.dao")
public class AppRun { 
   
    public static void main(String[] args) { 
   
        SpringApplication.run(AppRun.class , args);
    }
}

@MapperScan(basePackages = "com.kaven.mybatisplus.dao")这个一定要加上。

我们先在数据库中添加几行数据,方便演示。

来演示一下逻辑删除。

代码语言:javascript复制
package com.kaven.mybatisplus.dao;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.kaven.mybatisplus.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class LogicalDeleteTest { 
   

    @Autowired
    private UserMapper userMapper;

    @Test
    public void deleteById(){ 
   
        int rows = userMapper.deleteById("10");
        System.out.println("影响行数: " rows);
    }
}

结果如下:

逻辑删除不是真正的删除,它只是更新了逻辑删除标识,从上面的sql语句也能看出来,并且只能删除逻辑存在的数据,因为有AND deleted=0这个条件,很显然,上面的结果是正确的。

再来演示逻辑删除了的数据通过selectList()是否还可以查询出来。

代码语言:javascript复制
package com.kaven.mybatisplus.dao;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.kaven.mybatisplus.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class LogicalDeleteTest { 
   

    @Autowired
    private UserMapper userMapper;
    
    @Test
    public void selectList(){ 
   
        List<User> userList = userMapper.selectList(null);
        userList.forEach(System.out::println);
    }
}

结果如下:

很显然是查询不出来的,因为有限制条件WHERE deleted=0,但这只是MyBatis-Plus帮我们加上去的,如果你自定义sql语句来查询,还是可以查询出来,因为你可以设置对deleted字段没有限制。

再来演示逻辑删除了的数据通过updateById()是否还可以更新。

代码语言:javascript复制
package com.kaven.mybatisplus.dao;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.kaven.mybatisplus.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class LogicalDeleteTest { 
   

    @Autowired
    private UserMapper userMapper;

    @Test
    public void updateById(){ 
   
        User user = new User();
        user.setId("10");
        user.setUsername("kaven");
        user.setAge(22);

        int rows = userMapper.updateById(user);
        System.out.println("影响行数: " rows);
    }
}

结果如下:

可以看到,这个更新方法即使没有更新到数据,也不会报错,也可以知道,被逻辑删除了的数据是不能更新的(通过MyBatis-Plus),自己定义sql语句来实现更新就另说。

从上面这些演示,可以知道逻辑删除了的数据通过MyBatis-Plus是不能被查询、更新以及删除,那通过我们自定义的sql语句呢?我们来测试一下。

修改UserMapper:

代码语言:javascript复制
package com.kaven.mybatisplus.dao;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.kaven.mybatisplus.entity.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public interface UserMapper extends BaseMapper<User> { 
   

    @Select("select * from user ${ew.customSqlSegment}")
    List<User> mySelectList(@Param(Constants.WRAPPER) Wrapper<User> userWrapper);
}

通过注解@Select("select * from user ${ew.customSqlSegment}")来自定义sql语句,在之前的博客有介绍过:MyBatis-Plus 之自定义sql

测试代码:

代码语言:javascript复制
package com.kaven.mybatisplus.dao;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.kaven.mybatisplus.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class LogicalDeleteTest { 
   

    @Autowired
    private UserMapper userMapper;
    
      @Test
    public void mySelectList(){ 
   
        List<User> userList = userMapper.mySelectList(Wrappers.<User>lambdaQuery().gt(User::getAge , 25));
        userList.forEach(System.out::println);
    }
}

结果如下:

很显然,我们自定义的sql语句,MyBatis-Plus是不会帮我们加限制条件的,逻辑删除了的数据也给我们查询出来了,所以如果要自定义sql语句来操作,就要自己来加限制条件。

比如:

代码语言:javascript复制
package com.kaven.mybatisplus.dao;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.kaven.mybatisplus.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class LogicalDeleteTest { 
   

    @Autowired
    private UserMapper userMapper;

    @Test
    public void mySelectList(){ 
   
        List<User> userList = userMapper.mySelectList(Wrappers.<User>lambdaQuery()
                .gt(User::getAge , 25).eq(User::getDeleted , 0));
        userList.forEach(System.out::println);
    }
}

结果如下:

这样就没有逻辑删除了的数据被查询出来了。

逻辑删除标识就是一个普通的字段,只是我们用注解告诉了MyBatis-Plus,这是逻辑删除标识,这样MyBatis-Plus才能在我们进行CRUD时,给我们加限制条件,如果想要自定义sql语句来CRUD,就必须自己加上限制条件。

MyBatis-Plus的逻辑删除实现就介绍到这里。

写博客是博主记录自己的学习过程,如果有错误,请指正,谢谢!

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/143832.html原文链接:https://javaforall.cn

0 人点赞