1. 程式人生 > 其它 >【MybatisPlus】再補充內容

【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("[email protected]");
        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, [email protected], null, null, null, 0
         * <==        Row: 3, Tom, 28, [email protected], null, null, null, 0
         * <==        Row: 4, Sandy, 21, [email protected], null, null, null, 0
         * <==        Row: 5, Billie, 24, [email protected], null, null, null, 0
         * <==        Row: 1417674045524021250, lucy, 20, [email protected], null, null, null, 0
         * <==        Row: 1417680764933292034, 王五AAA, 20, [email protected], 2021-07-21 11:00:08, 2021-07-21 11:01:07, 2, 0
         * <==      Total: 6
         */
        users.forEach(System.out::println);
    }