mybatis-plus之邏輯刪除&自動填充&樂觀鎖


1.背景

mybatis-plus除了常規的一些CRUD還有其他的的功能如下

2.邏輯刪除

2.1.實現配置

步驟一、數據庫准備一個邏輯刪除字段,一般是deleted

步驟二、配置文件中添加入下配置

 步驟三、java實體上加標簽如下:

2.2.實際案例演示

package com.ldp.demo01;

import com.ldp.entity.SysUser;
import com.ldp.mapper.SysUserMapper;
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;

/**
 * @author 姿勢帝-博客園
 * @address https://www.cnblogs.com/newAndHui/
 * @WeChat 851298348
 * @create 12/14 7:13
 * @description <p>
 * 邏輯刪除測試
 * </p>
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class Test11LogicDeleted {
    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 邏輯刪除測試
     * <p>
     * ==>  Preparing: UPDATE sys_user SET deleted=1 WHERE id=? AND deleted=0
     * ==> Parameters: 26(Integer)
     * <==    Updates: 1
     * <p>
     * 注意觀察:雖然我執行的是刪除,但是因為配置了邏輯刪除,使用最后執行的本質sql是更新,
     * 而且在更新的sql語句中還加入了deleted=0這個條件
     * 那么試想一想,如果是查詢、修改會加入deleted=0這個條件么?
     */
    @Test
    public void test01() {
        int row = sysUserMapper.deleteById(25);
        System.out.println("受影響行數:" + row);
    }

    /**
     * 測試邏輯刪除下的查詢
     * <p>
     * ==>  Preparing: SELECT id,version,age,gender,name,parent_id,position,account,we_chat,password,status,type,create_time,update_time,deleted
     * FROM sys_user WHERE id=? AND deleted=0
     * ==> Parameters: 25(Integer)
     * <p>
     * 注意邏輯刪除下的查詢是加了  AND deleted=0 作為查條件的
     */
    @Test
    public void test02() {
        SysUser sysUser = sysUserMapper.selectById(25);
        System.out.println("sysUser=" + sysUser);
    }

    /**
     * 邏輯刪除下的更新
     * <p>
     * ==>  Preparing: UPDATE sys_user SET name=? WHERE id=? AND deleted=0
     * ==> Parameters: 邏輯刪除測試(String), 25(Integer)
     * <p>
     * 注意從sql語句上看也是添加了deleted=0的
     */
    @Test
    public void test03() {
        int row = sysUserMapper.updateById(new SysUser().setId(25).setName("邏輯刪除測試"));
        System.out.println("受影響行數=" + row);
    }

    /**
     * 邏輯刪除下的新增
     * ==>  Preparing: INSERT INTO sys_user ( age, name ) VALUES ( ?, ? )
     * ==> Parameters: 18(Integer), 新增測試(String)
     * <==    Updates: 1
     * 注意從sql語句來看,在添加的時候並沒有幫我們自動添加deleted=0字段的值,
     * 所有在實際生產中最佳的作法是在數據庫設置默認值為0
     */
    @Test
    public void test04() {
        int row = sysUserMapper.insert(new SysUser().setName("新增測試").setAge(18));
        System.out.println("受影響行數=" + row);
    }
}
View Code

3.自動填充

第一步:注解填充字段 @TableField(.. fill = FieldFill.INSERT) 生成器策略部分也可以配置!

  /**
     * 表示創建時自動填充
     */
    @TableField(value = "create_time",fill = FieldFill.INSERT)
    private Date createTime;
    /**
     * 表示更新時自動填充
     */
    @TableField(fill = FieldFill.UPDATE)
    private Date updateTime;

第二步:自定義實現類 MyMetaObjectHandler

package com.ldp.config;

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

import java.util.Date;

/**
 * @author 姿勢帝-博客園
 * @address https://www.cnblogs.com/newAndHui/
 * @WeChat 851298348
 * @create 12/14 8:03
 * @description
 */
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ....");
        this.strictInsertFill(metaObject, "createTime", () -> new Date(), Date.class); // 起始版本 3.3.3(推薦)
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ....");
        this.strictUpdateFill(metaObject, "updateTime", () -> new Date(), Date.class); // 起始版本 3.3.3(推薦)
    }
}
View Code

第三步:測試

package com.ldp.demo01;

import com.ldp.entity.SysUser;
import com.ldp.mapper.SysUserMapper;
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;

/**
 * @author 姿勢帝-博客園
 * @address https://www.cnblogs.com/newAndHui/
 * @WeChat 851298348
 * @create 12/14 8:10
 * @description <p>
 * 自動填充
 * </p>
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class Test12FieldFill {
    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 新增時自動填充
     * <p>
     * ==>  Preparing: INSERT INTO sys_user ( age, name, create_time ) VALUES ( ?, ?, ? )
     * ==> Parameters: 18(Integer), 自動填充(String), 2020-12-14 19:55:36.065(Timestamp)
     * <==    Updates: 1
     */
    @Test
    public void test01() {
        int row = sysUserMapper.insert(new SysUser().setName("自動填充").setAge(18));
        System.out.println("受影響行數=" + row);
    }


    /**
     * 更新時自動填充
     * <p>
     * ==>  Preparing: UPDATE sys_user SET name=?, update_time=? WHERE id=? AND deleted=0
     * ==> Parameters: 更新自動填充(String), 2020-12-14 19:56:16.539(Timestamp), 25(Integer)
     * <==    Updates: 1
     */
    @Test
    public void test02() {
        int row = sysUserMapper.updateById(new SysUser().setId(25).setName("更新自動填充"));
        System.out.println("受影響行數=" + row);
    }
}
View Code

4.樂觀鎖

實現原理:

取出記錄時,獲取當前version
更新時,帶上這個version
執行更新時, set version = newVersion where version = oldVersion
如果version不對,就更新失敗

 

具體實現

第一步:數據庫和java實體添加字段version,並在實體上添加注解@Version

    /**
     * 樂觀鎖
     */
    @Version
    private Integer version;

第二步:注冊樂觀鎖插件

package com.ldp.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author 姿勢帝-博客園
 * @address https://www.cnblogs.com/newAndHui/
 * @WeChat 851298348
 * @create 12/06 4:45
 * @description
 */
@Configuration
public class MybatisPlusConfig {
    /**
     * 樂觀鎖配置
     *
     * @return
     */
    @Bean
    public MybatisPlusInterceptor optimisticLockerInnerInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }

    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 設置請求的頁面大於最大頁后操作, true調回到首頁,false 繼續請求  默認false
        // paginationInterceptor.setOverflow(false);
        // 設置最大單頁限制數量,默認 500 條,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 開啟 count 的 join 優化,只針對部分 left join
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }
}
View Code

第三步:測試

package com.ldp.demo01;

import com.ldp.entity.SysUser;
import com.ldp.mapper.SysUserMapper;
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;

/**
 * @author 姿勢帝-博客園
 * @address https://www.cnblogs.com/newAndHui/
 * @WeChat 851298348
 * @create 12/14 9:40
 * @description
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class Test13Version {
    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 樂觀鎖測試
     * ==>  Preparing: UPDATE sys_user SET version=?, name=?, update_time=? WHERE id=? AND version=? AND deleted=0
     * ==> Parameters: 8(Integer), 樂觀鎖測試(String), 2020-12-14 22:04:15.04(Timestamp), 12(Integer), 7(Integer)
     * <==    Updates: 1
     * 注意觀察sql,查詢出來的version=7,在更新的時候將session版本設置為8
     */
    @Test
    public void test01() {
        SysUser sysUser = sysUserMapper.selectById(12);

        int row = sysUserMapper.updateById(
                new SysUser()
                        .setId(sysUser.getId())
                        .setName("樂觀鎖測試")
                        .setVersion(sysUser.getVersion())
        );
        System.out.println("受影響行數=" + row);
    }
}
View Code

mybatis-plus系統化學習教程:https://www.cnblogs.com/newAndHui/p/14141950.html

完美!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM