六,MyBatis-Plus 扩展功能(逻辑删除,通用枚举,字段类型处理,自动填充功能,防全表更新与删除插件,MybatisX快速开发插件)

news2024/12/23 4:04:19

六,MyBatis-Plus 扩展功能(逻辑删除,通用枚举,字段类型处理,自动填充功能,防全表更新与删除插件,MybatisX快速开发插件)

文章目录

  • 六,MyBatis-Plus 扩展功能(逻辑删除,通用枚举,字段类型处理,自动填充功能,防全表更新与删除插件,MybatisX快速开发插件)
  • 1. 逻辑删除
  • 2. 通用枚举
  • 3. 字段类型处理
  • 4. 自动填充功能
  • 5. 防全表更新与删除插件
  • 6. MybatisX快速开发插件
  • 7. 总结:
  • 8. 最后:


1. 逻辑删除

前面我们完成了基本的增删改查操作,但是对于删除操作来说。

我们思考一个问题,在实际开发中我们真的会将数据完全从数据库当中删除掉么?

当然不会的,这里我们举一个例子。

比如:在一个电商网站中,我们会上架很多商品,这些商品下架以后,我们如果将这些商品从数据库中删除,那么在年底统计商品数据信息的时候,这个商品要统计的,所以这个商品信息我们是不能删除的。

在这里插入图片描述

如果商城中的商品下架了,这时候,我们将商品从数据库删掉。

在这里插入图片描述

那到了年终总结的时候,我们要总结一下,这一年的销售额,发现少了 20000,这肯定不合理。所以我们是不能将数据真实删除的。

这里我们就采用逻辑删除的方案,逻辑删除的操作就是增加一个字段表示这个数据的状态,如果一条数据需要删除,我们通过改变这条数据的状态来实现,这样就既可以表示这条数据是删除的状态,又保留了数据以便以后统计,我们来实现一下这个效果。

首先:我们需要先在表中增加一列字段,表示是否删除的状态,这里我们使用的字段类型为 int 类型,通过 1 表示该条数据可用,0 表示该条数据不可用。

在这里插入图片描述
在这里插入图片描述

  1. 实体类添加一个字段为 Integer, 用于对应表中的字段。

在这里插入图片描述


import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.Version;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import com.rainbowsea.enums.GenderEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;
import java.util.Map;


@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName(autoResultMap = true)//查询时将json字符串封装为Map集合
public class User extends Model<User> {

    @TableId(type = IdType.ASSIGN_UUID)  // 全局唯一标识符,定义为一个字符串主键,注意是字符串,所以数据表的主键要为字符串类型才行
    // 对应的 Java bean 对象当中的属性值,也要为 字符串类型
    private String id;
    private String name;
    private Integer age;
    private String email;

    @TableLogic(value = "1", delval = "0")  // 标注删除状态
    private Integer status;


    
}

测试逻辑删除效果;这里我们测试删除 id 为 3 的一条记录

在这里插入图片描述

在这里插入图片描述

查看拼接的SQL语句,我们发现在执行删除操作的时候,语句变成了修改,是将这条数据的状态由1变为的0,表示这条数据为删除状态


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.rainbowsea.bean.User;
import com.rainbowsea.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.List;

@SpringBootTest
public class LogicTest {

    @Resource
    private UserMapper userMapper;

    @Test
    void logicDelete() {
        userMapper.deleteById("3");
    }

}

在这里插入图片描述

我们再测试查询这个,id 为 3 的记录试试。


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.rainbowsea.bean.User;
import com.rainbowsea.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.List;

@SpringBootTest
public class LogicTest {

    @Resource
    private UserMapper userMapper;

    @Test
    void selectById() {
        User user = new User();
        User selectUser = user.selectById("3");
        System.out.println(selectUser);
    }
}

在这里插入图片描述

我们可以看到查询的时候。SQL语句拼接上一个 status =1的条件。只有 status = 1 的记录才能被查出来,status =0 的表示删除了,不可以查询出来。

我们还可以通过全局配置来实现逻辑删除的效果。
需要在application.yaml 文件当中配置。

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

在这里插入图片描述

2. 通用枚举

首先我们先来回顾一下枚举,什么是枚举呢?

当我们想要表示一组信息,这组信息只能从一些固定的值中进行选择,不能随意写,在这种场景下,枚举就非常的合适。

例如:我们想要表示性别,性别只有两个值,要么是男性,要么是女性,那我们就可以使用枚举类描述性别。

  1. 我们先在表中添加一个字段,表示性别,这里我们一般使用 int 来描述,因为 int 类型可以通过 0和 1 这两个值来表示两个不同的性别。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

package com.rainbowsea.enums;

import com.baomidou.mybatisplus.annotation.EnumValue;

public enum GenderEnum {

    MAN(0,"男"),
    WOMAN(1,"女");

    @EnumValue
    private Integer gender;
    @EnumValue
    private String genderName;

    GenderEnum(Integer gender, String genderName) {
        this.gender = gender;
        this.genderName = genderName;
    }

    GenderEnum() {
    }
}

实体类添加相关字段

在这里插入图片描述


import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.Version;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import com.rainbowsea.enums.GenderEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;
import java.util.Map;


@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName(autoResultMap = true)//查询时将json字符串封装为Map集合
public class User extends Model<User> {

    @TableId(type = IdType.ASSIGN_UUID)  // 全局唯一标识符,定义为一个字符串主键,注意是字符串,所以数据表的主键要为字符串类型才行
    // 对应的 Java bean 对象当中的属性值,也要为 字符串类型
    private String id;
    private String name;
    private Integer age;
    private String email;

    @TableLogic(value = "1", delval = "0")  // 标注删除状态
    private Integer status;
    private GenderEnum gender;
}

添加数据:

在这里插入图片描述



import com.rainbowsea.enums.GenderEnum;
import com.rainbowsea.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import com.rainbowsea.bean.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;

@SpringBootTest
public class enumTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    void enumTest() {
        User user = new User();
        user.setName("LiHu2");
        user.setAge(18);
        user.setEmail("lihua@rainbowsea.com");
        user.setStatus(1);
        user.setGender(GenderEnum.WOMAN);
        System.out.println(GenderEnum.WOMAN);

        userMapper.insert(user);



    }

此时我们查看控制台,会发现添加失败了

在这里插入图片描述

原因是我们无法将一个枚举类型作为 int 数字插入到数据库中。不过,我们对于枚举类型都给了对应的 int 的值,所以这里我们只需要进行一个配置,就可以将枚举类型作为数字插入到数据库中,为属性 gender ,添加上 @EnumValue 注解。

在这里插入图片描述

再次运行,此时我们再次执行添加操作,发现可以成功添加数据,而枚举类型的值也作为数据被插入到数据库中。

在这里插入图片在这里插入图片描述
描述

在这里插入图片描述

3. 字段类型处理

在某些场景下,我们在实体类中是使用 Map集合作为属性接收前端传递过来的数据的,但是这些数据存储在数据库时,我们使用的是JSON 格式的数据进行存储,JSON本质就是一个字符串,就是 varchar 类型,那该怎么做到实体类的 Map 类型和数据库的 varchar类型的互相转换,这里就需要使用到字段类型处理器来完成了。

我们先在实体类中添加一个字段,Map类型

在这里插入图片描述


import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.Version;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import com.rainbowsea.enums.GenderEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;
import java.util.Map;


@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName(autoResultMap = true)//查询时将json字符串封装为Map集合
public class User extends Model<User> {

    @TableId(type = IdType.ASSIGN_UUID)  // 全局唯一标识符,定义为一个字符串主键,注意是字符串,所以数据表的主键要为字符串类型才行
    // 对应的 Java bean 对象当中的属性值,也要为 字符串类型
    private String id;
    private String name;
    private Integer age;
    private String email;

    @TableLogic(value = "1", delval = "0")  // 标注删除状态
    private Integer status;
    private GenderEnum gender;

    private Map<String, String> contact;  // 联系方式
}

在数据库中我们添加一个字段,为varchar类型

在这里插入图片描述

为实体类添加上对应的``注解,实现使用字段类型处理器进行不同类型数据转换

@TableName(autoResultMap = true)//查询时将json字符串封装为Map集合
  @TableField(typeHandler = FastjsonTypeHandler.class)//指定字段类型处理器

在这里插入图片描述


import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.Version;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import com.rainbowsea.enums.GenderEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;
import java.util.Map;


@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName(autoResultMap = true)//查询时将json字符串封装为Map集合
public class User extends Model<User> {

    @TableId(type = IdType.ASSIGN_UUID)  // 全局唯一标识符,定义为一个字符串主键,注意是字符串,所以数据表的主键要为字符串类型才行
    // 对应的 Java bean 对象当中的属性值,也要为 字符串类型
    private String id;
    private String name;
    private Integer age;
    private String email;

    @TableLogic(value = "1", delval = "0")  // 标注删除状态
    private Integer status;
    private GenderEnum gender;

    @TableField(typeHandler = FastjsonTypeHandler.class)//指定字段类型处理器
    private Map<String, String> contact;  // 联系方式



}

字段类型处理器依赖Fastjson这个Json处理器,所以我们需要引入对应的依赖 。

在这里插入图片描述

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.76</version>
</dependency>

完整的pom.xml 的配置:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.8</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.rainbowsea</groupId>
    <artifactId>mp04</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mp04</name>
    <description>mp04</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <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>
            <scope>test</scope>
        </dependency>

        <!--        spring boot web 依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--        mysql 驱动依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>

        <!--        lombok 的依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>


        <!--        druid-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>


        <!--        mybatis-plus 的依赖-->

        <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3</version>
        </dependency>


<!--        map 转为 json,json 转为 map-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.76</version>
        </dependency>

        <dependency>
            <groupId>p6spy</groupId>
            <artifactId>p6spy</artifactId>
            <version>3.9.1</version>
        </dependency>


    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </pluginRepository>
    </pluginRepositories>

</project>

测试添加操作

在这里插入图片描述


import com.rainbowsea.bean.User;
import com.rainbowsea.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.HashMap;
import java.util.List;

@SpringBootTest
public class TypeHandLerTest {
    @Autowired
    private UserMapper userMapper;

    @Test
    void typeHandler() {
        User user = new User();
        user.setName("zhang3");
        user.setAge(28);
        user.setEmail("zhang@powernode.com");
        user.setStatus(1);
        HashMap<String, String> contact = new HashMap<>();
        contact.put("phone","010-1234567");
        contact.put("tel","13388889999");
        user.setContact(contact);

        userMapper.insert(user);
    }

}

执行的SQL语句如下

在这里插入图片描述

通过观察SQL语句,我们发现当插入一个Map类型的字段的时候,该字段会转换为String类型。

查看数据库中的信息,发现添加成功

在这里插入图片描述

测试查询操作,通过结果发现,从数据库中查询出来的数据,已经被转到Map集合

在这里插入图片描述

4. 自动填充功能

在项目中有一些属性,如果我们不希望每次都填充的话,我们可以设置为自动填充,比如:常见的时间,创建时间和更新时间可以配置为自动填充。

  1. 我们需要在数据库表当中添加两个字段。注意:这里我们测试的“自动填充的功能是 时间类型的。”

在这里插入图片描述

注意只有设置了下划线和小驼峰映射,这种 mysql 的写法才能和实体类完成映射。 因为我们实际Java Bean实体当中的属性与数据表当中字段名是不一致的。

在这里插入图片描述

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  # 开启 Log 日志信息打印
    map-underscore-to-camel-case: true # 开启驼峰,下划线映射规则

在实体类中,添加对应字段,并为需要自动填充的属性指定填充时机

在这里插入图片描述


import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.Version;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import com.rainbowsea.enums.GenderEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;
import java.util.Map;


@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName(autoResultMap = true)//查询时将json字符串封装为Map集合
public class User extends Model<User> {
    @TableId(type = IdType.ASSIGN_UUID)  // 全局唯一标识符,定义为一个字符串主键,注意是字符串,所以数据表的主键要为字符串类型才行
    // 对应的 Java bean 对象当中的属性值,也要为 字符串类型
    private String id;
    private String name;
    private Integer age;
    private String email;
    @TableLogic(value = "1", delval = "0")  // 标注删除状态
    private Integer status;
    private GenderEnum gender;
    @TableField(typeHandler = FastjsonTypeHandler.class)//指定字段类型处理器
    private Map<String, String> contact;  // 联系方式


    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
}

编写自动填充处理器,指定填充策略

在这里插入图片描述

package com.rainbowsea.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;


@Component
public class MyMetaHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        setFieldValByName("createTime",new Date(),metaObject);
        setFieldValByName("updateTime",new Date(),metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {

        setFieldValByName("updateTime",new Date(),metaObject);

    }
}

这里在插入前先设置一下mysql 数据库的时区,因为我们中国是东八区,获取的时间会慢了8小时。所以我们需要改一下 MySQL数据库的时区,改为我们东八区的时间。

执行如下 SQL语句即可,添加 8 小时的时差。


set GLOBAL time_zone = '+8:00'
select NOW();

在这里插入图片描述

同时我们Java连接数据库当中的 URL 也需要配置一下时区。(再将配置文件的时区修改为serverTimezone=Asia/Shanghai)

在这里插入图片描述

spring:
  datasource:
#    driver-class-name: com.mysql.cj.
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    url: jdbc:mysql://localhost:3306/mybatisplus?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false
    username: root
    password: MySQL123

测试插入操作。


import com.rainbowsea.bean.User;
import com.rainbowsea.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class FillTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    void testFillInsert() {
        User user = new User();
        user.setName("LiHu666");
        user.setAge(18);
        user.setEmail("lihua@rainbowsea.com");
        user.setStatus(1);

        userMapper.insert(user);
    }
}

在这里插入图片描述

在这里插入图片描述

测试更新操作


import com.rainbowsea.bean.User;
import com.rainbowsea.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class FillTest {

    @Autowired
    private UserMapper userMapper;


    @Test
    void testFillUpdate() {
        //1837826196875464706
        User user = new User();
        user.setName("LiHu666");
        user.setId("1837826196875464706");
        user.setAge(18);
        user.setEmail("lihua@rainbowsea.com");
        user.setStatus(1);

        userMapper.updateById(user);

    }
}

在这里插入图片描述

在这里插入图片描述

5. 防全表更新与删除插件

在实际开发中,全表更新和删除是非常危险的操作,在MybatisPlus中,提供了插件和防止这种危险操作的发生。

先演示一下全表更新的场景

@Test
public void testUpdateAll(){
    User user = new User();
    user.setGender(GenderEnum.MAN);
    userService.saveOrUpdate(user,null);
}

在这里插入图片描述

这是很危险的

如何解决呢?

注入 MybatisPlusInterceptor类,并配置 BlockAttackInnerInterceptor拦截器

在这里插入图片描述

package com.rainbowsea.config;


import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MybatisPlusConfig {



    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();

        /*
        通过配置类来指定一个具体数据库的分页插件,因为不同的数据库的方言不同,具
        体涩会给你从的分页语句也会不同,这里我们指定数据库为 MySQL数据库
         */
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        mybatisPlusInterceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());  // 防全表更新与删除插件
        return mybatisPlusInterceptor;
    }

}

测试全表更新,会出现抛出异常,防止了全表更新。

@SpringBootTest
public class QueryTest {

    @Autowired
    private UserService userService;

@Test
void allUpdate(){
    User user = new User();
    user.setId(999L);
    user.setName("wang");
    user.setEmail("wang@powernode.com");
    userService.saveOrUpdate(user,null);
}
}

直接报异常,报错,不然,继续往下执行。

6. MybatisX快速开发插件

由于涉及到的篇幅过多,关于 Mybatisx 插件的详细安装使用的详细内容,大家可以移步至:✏️✏️✏️ 十八,Spring Boot 整合 MyBatis-Plus 的详细配置_mybatis-plus 配置-CS
DN博客

7. 总结:

  1. 逻辑删除的操作就是增加一个字段表示这个数据的状态,如果一条数据需要删除,我们通过改变这条数据的状态来实现,这样就既可以表示这条数据是删除的状态,又保留了数据以便以后统计。使用 @TableLogic(value = "1", delval = "0") 在Java Bean的属性上注解起来。标记没有删除是什么状态值是多少,删除后的状态值又是多少。

在这里插入图片描述

当使用了逻辑删除,那么在后面是所有执行的SQL语句都被加上一个 条件筛选,判断该状态是否删除了,是否可以被查询到。

在这里插入图片描述

  1. 注意:通用枚举类型上的处理:我们无法将一个枚举类型作为 int 数字插入到数据库中。不过,我们对于枚举类型都给了对应的 int 的值,所以这里我们只需要进行一个配置,就可以将枚举类型作为数字插入到数据库中,为属性 gender ,添加上 @EnumValue 注解。

在这里插入图片描述

  1. 字符类型处理:前端提交,获取到的数据,使用的是 JSON 格式的将数据存储在数据库的数据表当中。然后,后端读取数据表中JSON 格式的字符串数据,会被转换为 Map类型的数据,在后端显示使用。这里就需要使用到字段类型处理器来完成了。

  2. 自动填充功能:在项目中有一些属性,如果我们不希望每次都填充的话,我们可以设置为自动填充,比如:常见的时间,创建时间和更新时间可以配置为自动填充。注意如果是以时间上的自动填充,由于我们中国是在东八区,而数据库的时间是采用了欧洲那边的时间,所以我们存在着一个 8小时的时差。我们需要修改Java端的时间url时间,以及数据库的时间。

在这里插入图片描述
在这里插入图片描述

同时我们Java连接数据库当中的 URL 也需要配置一下时区。(再将配置文件的时区修改为serverTimezone=Asia/Shanghai)

在这里插入图片描述

spring:
  datasource:
#    driver-class-name: com.mysql.cj.
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    url: jdbc:mysql://localhost:3306/mybatisplus?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false
    username: root
    password: MySQL123
  1. 防全表更新与删除插件:全删表,更新表是一件十分危险的事情,所以我们需要设置,我们误操作更新数据表,没有添加筛选条件。

    ?注入 MybatisPlusInterceptor类,并配置 BlockAttackInnerInterceptor拦截器

    在这里插入图片描述

  2. MybatisX是一款IDEA提供的插件,目的是为了我们简化Mybatis以及MybatisPlus框架而生。

8. 最后:

“在这个最后的篇章中,我要表达我对每一位读者的感激之情。你们的关注和回复是我创作的动力源泉,我从你们身上吸取了无尽的灵感与勇气。我会将你们的鼓励留在心底,继续在其他的领域奋斗。感谢你们,我们总会在某个时刻再次相遇。”

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2182361.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

51单片机学习第六课---B站UP主江协科技

DS18B20 1、基本知识讲解 2、DS18B20读取温度值 main.c #include<regx52.h> #include"delay.h" #include"LCD1602.h" #include"key.h" #include"DS18B20.h"float T; void main () {LCD_Init();LCD_ShowString(1,1,"temp…

领域偏移:协变量移位下的域自适应

现在我们将焦点转移到一种叫做协变量转移的扰动上。我们在一个分类或回归设置中工作&#xff0c;我们希望从x预测y&#xff0c;并假设p≈(y | x)和p∗(y | x)是相同的(标记函数在训练和测试之间不会改变) 假设 (Covariate Shift)。对于列车分布p~和检验分布p∗&#xff0c;我们…

安达发|纺织行业APS系统中的物料替代解决方案

在纺织行业中&#xff0c;物料替代是应对原材料短缺、成本波动和供应链不确定性的一种重要策略。高级计划与排程系统&#xff08;APS&#xff09;通过集成物料替代功能&#xff0c;可以帮助企业在保持生产效率的同时&#xff0c;灵活应对市场变化。本文将探讨纺织行业在APS系统…

Leetcode Hot 100 | 543.二叉树的直径 | 递归+优化

写法一 自己一开始直接写的&#xff0c;没考虑时间复杂度… class Solution {/*递归思路&#xff1a;不准进递归&#xff08;除非之后用简单例子验证一下&#xff09;将方法按照自己想要返回的值来补充其他的代码细节&#xff1b;用最值来模拟返回结果补充代码细节&#xff0…

Win10鼠标总是频繁自动失去焦点-非常有效-重启之后立竿见影

针对Win10鼠标频繁自动失去焦点的问题&#xff0c;可以尝试以下解决方案&#xff1a; 一、修改注册表&#xff08;最有效的方法-重启之后立竿见影&#xff09; 打开注册表编辑器&#xff1a; 按下WindowsR组合键&#xff0c;打开运行窗口。在运行窗口中输入“regedit”&#x…

什么是reactor以及其三种版本

写在前面 本文来看下什么是reactor以及其三种版本。 1&#xff1a;什么是reactor以及其三种版本 为了更好的理解什么是reactor&#xff0c;我们结合现实生活中的例子来看下。 翠花是个貌美如花的姑娘&#xff0c;人称赛东施&#xff0c;她的梦想是嫁给王子&#xff0c;可是天…

【机器学习-无监督学习】降维与主成分分析

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈Python机器学习 ⌋ ⌋ ⌋ 机器学习是一门人工智能的分支学科&#xff0c;通过算法和模型让计算机从数据中学习&#xff0c;进行模型训练和优化&#xff0c;做出预测、分类和决策支持。Python成为机器学习的首选语言&#xff0c;…

揭秘帕金森病:多因素交织下的“沉默杀手”

在老年人群中&#xff0c;帕金森病如同一位“沉默的杀手”&#xff0c;悄然侵袭着无数人的生活。它以其独特的静止性震颤、运动迟缓、肌强直和姿势平衡障碍等症状&#xff0c;让患者的生活质量大打折扣。那么&#xff0c;帕金森病究竟是如何得的呢&#xff1f;本文将带您深入探…

基于Springboot+Vue的基于协同过滤算法的个性化音乐推荐系统 (含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统中…

Android 13.0 系统wifi列表显示已连接但无法访问网络问题解决

1.前言 在13.0的系统rom产品定制化开发中,在wifi模块也很重要,但是在某些情况下对于一些wifi连接成功后,确显示已连接成功,但是无法访问互联网 的情况,所以实际上这时可以正常上网的,就是显示的不正常,所以就需要分析连接流程然后解决问题 如图所示: 2.系统wifi列表显示…

【Spring Boot 入门三】Spring Boot与数据库集成 - 构建数据驱动的应用

一、引言 在之前的文章中&#xff0c;我们已经对Spring Boot有了初步的认识&#xff0c;了解了如何构建第一个Spring Boot应用&#xff0c;以及如何通过配置文件来掌控应用的设置。这些知识为我们进一步探索Spring Boot与数据库的集成奠定了坚实的基础。 数据库是现代应用的核…

QSqlDatabase在多线程中的使用

Qt中多线程使用数据库_qt数据库管理类支持多数据库,多线程-CSDN博客 1. 代码&#xff1a; #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPushButton> #include <QSqlDatabase> #include <QSqlQuery> #include <QSqlError>…

【原创】基于websocket的实时文本转语音功能

功能实现&#xff0c;将长文本分段实时转成音频流&#xff0c;达到边转换边播放的效果&#xff0c;减少等待效果&#xff0c;像豆包通义千问chatgpt差不多也是这样实现的&#xff0c; 下面的效果展示 20240930_084035_哔哩哔哩_bilibili【原创】基于websocket的实时文本转语音…

Java 每日一刊(第18期):集合

文章目录 前言1. Java 集合框架概述1.1 Java 集合框架的定义和意义1.2 Java 集合框架的历史演进1.3 集合框架的基本组成部分1.4 Java 集合的优势1.5 Java 集合与数组的区别与关系 2. Java 集合框架的核心接口2.1 Collection 接口2.2 List 接口2.3 Set 接口2.4 Queue 接口2.5 Ma…

无人机在科研与教育领域的应用!

一、无人机在科研领域的应用 地理测绘与遥感&#xff1a; 无人机可以搭载相机或激光雷达等传感器&#xff0c;进行高分辨率的航拍&#xff0c;用于制作数字地形模型、生态环境监测、土地利用规划等。 在地理信息获取、地质勘察等领域&#xff0c;无人机能够高效地完成测量任…

Java中正则表达式(完整详解,附有案例+代码)

文章目录 三十三.正则表达式33.1 概述33.2 Test 三十三.正则表达式 33.1 概述 字符类 [abc]a、b 或 c&#xff08;简单类&#xff09;[^abc]任何字符&#xff0c;除了 a、b 或 c&#xff08;否定&#xff09;[a-zA-Z]a 到 z 或 A 到 Z&#xff0c;两头的字母包括在内&#x…

MQTT--EMQX入门+MQTTX使用

目录 1、什么是EMQX&#xff1f;1.1 EMQX介绍1.2 EMQX特点1.3 与物联网之间的关系以及主要的产品主要的产品 2、安装启动2.1 基本命令2.2 目录结构 3、MQTTX客户端3.1 连接配置 总结PS: 1、什么是EMQX&#xff1f; 首先你得有MQTT的知识&#xff0c;不认识MQTT的小伙伴可以先看…

JMeter对jdbc request以及foreach和loop controller的使用

Jmeter中jdbc request和foreach控制器 1. 使用variable name实现对数据库查询结果的遍历 在foreach controller中&#xff0c;注意要做variable name的关联(correlation), 否则没法取回这里的jdbc request返回的结果。这里的input variable prefix一定要和jdbc request中的var…

十七、触发器

文章目录 0. 引入1. 触发器概述2. 触发器的创建2.1 触发器的创建2.2 代码举例 3. 查看、删除触发器3.1 查看触发器3.2 删除触发器 4. 触发器的优缺点4.1 优点4.2 缺点4.3 注意点 0. 引入 在实际开发中&#xff0c;我们经常会遇到这样的情况&#xff1a;有 2 个或者多个相互关联…

《蓝桥杯算法入门》(C/C++、Java、Python三个版本)24年10月出版

推荐&#xff1a;《算法竞赛》&#xff0c;算法竞赛大全书&#xff0c;网购&#xff1a;京东 天猫  当当 文章目录 《蓝桥杯算法入门》内容简介本书读者对象作者简介联系与交流《蓝桥杯算法入门 C/C》版目录 《蓝桥杯算法入门 Java》版目录 《蓝桥杯算法入门 Python》版目录 …