【MybatisPlus】再补充内容

2021年7月21日 14点05分

看尚硅谷新讲的尚医通,这个MP的文档多了新东西:

 

依赖版本:

springBoot版本  2.2.1.RELEASE

<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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>

<!--mysql依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--lombok用来简化实体类-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>

但是拉下来Spring报错,死活找不到版本

我这里干脆换版本了:

<?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.3.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.atguigu</groupId>
    <artifactId>mybatis_plus</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mybatis_plus</name>
    <description>Demo project for Spring Boot</description>
    <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>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.1</version>
        </dependency>

        <!--mysql依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--lombok用来简化实体类-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>


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

</project>

 

一、自动填充

package com.atguigu.mybatis_plus.entity;

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

import java.util.Date;

@Data
public class User {

    @TableId(type = IdType.ASSIGN_ID) // 默认雪花算法的主键策略 @TableId(type = IdType.AUTO) 自增策略
    private Long id;
    private String name;
    private Integer age;
    private String email;

    // 自动填充注解? 需要实现 元对象处理器接口,自定义实现方法
    @TableField(value = "createTime", fill = FieldFill.INSERT)
    private Date createTime;  //create_time

    @TableField(value = "updateTime", fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

}

元对象处理器接口实现:

package com.atguigu.mybatis_plus.handler;

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

import java.util.Date;

/**
 * 自动填充
 * 需求描述:
 * 项目中经常会遇到一些数据,每次都使用相同的方式填充,例如记录的创建时间,更新时间等。
 * 我们可以使用MyBatis Plus的自动填充功能,完成这些字段的赋值工作
 * 1.1数据库修改
 * 在User表中添加datetime类型的新的字段 create_time、update_time
 *
 *
 */
@Component
public class CustomMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);

        this.setFieldValByName("recordVersion", 1, metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }

}

 

二、乐观锁

项目里面的持久层框架时ActiveJdbc,有这样的应用场景,但是框架这块没提供相关的封装

实现是人肉代码完成,程序逻辑有一点点封装

MP这里就配置一下就行了

package com.atguigu.mybatis_plus.entity;

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

import java.util.Date;

@Data
public class User {

    @TableId(type = IdType.ASSIGN_ID) // 默认雪花算法的主键策略 @TableId(type = IdType.AUTO) 自增策略
    private Long id;
    private String name;
    private Integer age;
    private String email;

    // 自动填充注解? 需要实现 元对象处理器接口,自定义实现方法
    @TableField(value = "createTime", fill = FieldFill.INSERT)
    private Date createTime;  //create_time

    @TableField(value = "updateTime", fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
    /**
     * 乐观锁
     * 场景
     * 主要适用场景:当要更新一条记录的时候,希望这条记录没有被别人更新,也就是说实现线程安全的数据更新
     * 乐观锁实现方式:
     * 取出记录时,获取当前version
     * 更新时,带上这个version
     * 执行更新时, set version = newVersion where version = oldVersion
     * 如果version不对,就更新失败
     * 接下来介绍如何在Mybatis-Plus项目中,使用乐观锁:
     */
    @Version
    @TableField(value = "recordVersion", fill = FieldFill.INSERT) // 设置默认值
    private Integer recordVersion;

    @TableLogic
    private Integer deleted; // ALTER TABLE `user` ADD COLUMN `deleted` boolean DEFAULT false


}

编写配置类:

package com.atguigu.mybatis_plus.config;


import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan("com.atguigu.mybatis_plus.mapper")
public class MybatisPlusConfiguration {
    /**
     * 乐观锁插件 已过时对象写法
     */
//    @Bean
//    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
//        return new OptimisticLockerInterceptor();
//    }

    /**
     * 分页插件
     * 已过时?
     */
//    @Bean
//    public PaginationInterceptor paginationInterceptor() {
//        return new PaginationInterceptor();
//    }


    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        // mp插件接口
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

        // 添加乐观锁插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());

        // 添加分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());

        return interceptor;
    }

}

乐观锁测试:

    // 乐观锁案例
    @Test
    void testingForOptimisticLocker() {
        // 首先插入一条记录,检查是否自动插入RecordVersion
        User user = new User();
        user.setAge(24);
        user.setName("小红");
        user.setEmail("21312qasdq@qq.com");
        int insert = userMapper.insert(user);

        // 然后使用ID查询, 更改这条记录, 检查版本会不会更改为2
        User user1 = userMapper.selectById(user.getId()); // 不确定这样能否有效获取ID, 建议从库里拿数据写死
        user1.setName("新小红");
        userMapper.updateById(user1);
    }

 

三、支持逻辑删除

package com.atguigu.mybatis_plus.entity;

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

import java.util.Date;

@Data
public class User {

    @TableId(type = IdType.ASSIGN_ID) // 默认雪花算法的主键策略 @TableId(type = IdType.AUTO) 自增策略
    private Long id;
    private String name;
    private Integer age;
    private String email;

    // 自动填充注解? 需要实现 元对象处理器接口,自定义实现方法
    @TableField(value = "createTime", fill = FieldFill.INSERT)
    private Date createTime;  //create_time

    @TableField(value = "updateTime", fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
    /**
     * 乐观锁
     * 场景
     * 主要适用场景:当要更新一条记录的时候,希望这条记录没有被别人更新,也就是说实现线程安全的数据更新
     * 乐观锁实现方式:
     * 取出记录时,获取当前version
     * 更新时,带上这个version
     * 执行更新时, set version = newVersion where version = oldVersion
     * 如果version不对,就更新失败
     * 接下来介绍如何在Mybatis-Plus项目中,使用乐观锁:
     */
    @Version
    @TableField(value = "recordVersion", fill = FieldFill.INSERT) // 设置默认值
    private Integer recordVersion;

    @TableLogic
    private Integer deleted; // ALTER TABLE `user` ADD COLUMN `deleted` boolean DEFAULT false


}

配置文件相关定义:

spring:
  datasource:
    url: jdbc:mysql://localhost:3308/atguigu-syt?serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456

#mybatis日志
mybatis-plus:
  global-config:
    db-config:
      id-type: auto #全局设置主键生成策略

      # 设置逻辑删除值标准 (默认值)
      logic-delete-value: 1
      logic-not-delete-value: 0

  configuration: # 日志输出标准
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

测试类的单元方法:

    /**
     * 2、逻辑删除
     * 2.1物理删除和逻辑删除
     * 物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除数据
     * 逻辑删除:假删除,将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录
     *
     * 逻辑删除的使用场景:
     * 可以进行数据恢复
     * 有关联数据,不便删除
     *
     * 2.2 逻辑删除实现流程
     * 2.2.1数据库修改
     * 添加 deleted字段
     * ALTERTABLE `user` ADD COLUMN `deleted` boolean DEFAULT false
     *
     * 2.2.2实体类修改
     * 添加deleted 字段,并加上 @TableLogic 注解
     * @TableLogic
     * private Integer deleted;
     *
     * 2.2.3配置(可选)
     * application.properties 加入以下配置,此为默认值,如果你的默认值和mp默认的一样,该配置可无
     * mybatis-plus.global-config.db-config.logic-delete-value=1
     * mybatis-plus.global-config.db-config.logic-not-delete-value=0
     *
     * 2.2.4 测试
     * 测试后发现,数据并没有被删除,deleted字段的值由0变成了1
     * 测试后分析打印的sql语句,是一条update
     * 注意:被删除前,数据的deleted 字段的值必须是 0,才能被选取出来执行逻辑删除的操作
     * @Test
     * public void testLogicDelete() {
     *     int result = userMapper.deleteById(1L);
     * system.out.println(result);
     * }
     *
     * 2.2.5测试逻辑删除后的查询
     * MyBatis Plus中查询操作也会自动添加逻辑删除字段的判断
     * @Test
     * public void testLogicDeleteSelect() {
     * List<User> users = userMapper.selectList(null);
     * users.forEach(System.out::println);
     * }
     *
     *
     */
    @Test
    public void testingForLogicDelete() {
        userMapper.deleteById(1);
        /**
         * ==>  Preparing: UPDATE user SET deleted=1 WHERE id=? AND deleted=0
         * ==> Parameters: 1(Integer)
         * <==    Updates: 1
         */

        List<User> users = userMapper.selectList(null);
        /**
         * ==>  Preparing: SELECT id,name,age,email,createTime,updateTime,recordVersion,deleted FROM user WHERE deleted=0
         * ==> Parameters:
         * <==    Columns: id, name, age, email, createTime, updateTime, recordVersion, deleted
         * <==        Row: 2, Jack, 20, test2@baomidou.com, null, null, null, 0
         * <==        Row: 3, Tom, 28, test3@baomidou.com, null, null, null, 0
         * <==        Row: 4, Sandy, 21, test4@baomidou.com, null, null, null, 0
         * <==        Row: 5, Billie, 24, test5@baomidou.com, null, null, null, 0
         * <==        Row: 1417674045524021250, lucy, 20, 1243@qq.com, null, null, null, 0
         * <==        Row: 1417680764933292034, 王五AAA, 20, 1243@qq.com, 2021-07-21 11:00:08, 2021-07-21 11:01:07, 2, 0
         * <==      Total: 6
         */
        users.forEach(System.out::println);
    }

 

上一篇:Leetcode刷题笔记——剑指 Offer 28. 对称的二叉树(简单)


下一篇:【福利】BAT架构师分享最全Java架构师学习技能图谱:包含Java编程+网络+设计模式+数据库+分布式等