天天看點

SpringBoot整合MybatisPlus資料自動填充

作者:死牛胖子

SpringBoot 內建 MybatisPlus 系列

SpringBoot 版本:2.6.4

MybatisPlus 版本:3.5.1

  • SpringBoot整合MybatisPlus
  • SpringBoot整合MybatisPlus資料自動填充
  • SpringBoot整合MybatisPlus實作邏輯删除
  • SpringBoot整合MybatisPlus實作分頁查詢
  • SpringBoot整合MybatisPlus支援枚舉類型
  • 未完待續…
SpringBoot整合MybatisPlus資料自動填充

在真實的項目裡,表結構中一般會存在一些公司内部約定的公共字段,比如:建立時間,建立人,修改時間,修改人等,記錄這些資料一方面可以出現問題時進行溯源,也可以提供給大資料收集。

不管怎樣,這是目前大部分公司選擇的方案。

通常公司的架構會有一個上下文對象,存儲了目前登入人資訊,每次新增或者修改資料庫記錄,可以從上下文中擷取目前登入人資訊,填充建立時間,建立人這些資訊。但如果每次都需要手動去寫這些業務無關的内容,重複且繁瑣,而且還容易出錯。

需求分析

假設增加 createTime、createUser、updateTime、updateUser 四個字段用來記錄建立時間,建立人,修改時間,修改人資訊。

  • 新增記錄時,四個字段都進行填充
  • 修改記錄時,隻填充 updateTime、updateUser 兩個字段,createTime、createUser 則保持不變

準備工作

使用 MySql 資料庫,設計一張 user 表。

資料庫腳本

CREATE TABLE user (
    `id` BIGINT(20) NOT NULL COMMENT '主鍵',
    `name` VARCHAR(32) NOT NULL COMMENT '姓名',
    `age` SMALLINT(4) NOT NULL DEFAULT '0' COMMENT '年齡',
    `email` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '郵箱',
    `create_time` DATETIME NOT NULL COMMENT '建立時間',
    `create_user` VARCHAR(32) NOT NULL COMMENT '建立人',
    `update_time` DATETIME NOT NULL COMMENT '最近更新時間',
    `update_user` VARCHAR(32) NOT NULL COMMENT '最近更新人',
    PRIMARY KEY (id)
)           
SpringBoot整合MybatisPlus資料自動填充

整合 MybatisPlus 實作自動填充

第一步:設定 @TableField 注解的 FieldFill 屬性

其實每個字段都預設設定了一個 @TableField,是以 MybatisPlus 實體類中的字段都必須與資料庫表中的字段對應,可以少,但不能多,多出來的字段必須設定 @TableField(exist = false)。

@TableField 注解中還有一個屬性 fill,就是用于支援自動填充功能,可選擇的值有四個

  • DEFAULT:預設值,不自動填充
  • INSERT:插入時自動填充
  • UPDATE:更新時自動填充
  • INSERT_UPDATE:插入及更新時自動填充

根據本次的需求,為 createTime、createUser、updateTime、updateUser 四個字段分别添加自動填充政策

@Data
public class User {
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    private String name;
    private Integer age;
    private String email;
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @TableField(fill = FieldFill.INSERT)
    private String createUser;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private String updateUser;
}           

第二步:實作 MetaObjectHandler 接口

通過第一步,設定好的填充的時機,但具體該填充什麼值,則需要實作 MetaObjectHandler 接口(為了簡化,這裡處理人姓名寫死了,正常可以通過上下文進行擷取)。

這個類需要注冊到 Spring 容器中
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    // 新增時填充
    @Override
    public void insertFill(MetaObject metaObject) {
        LocalDateTime now = LocalDateTime.now();
        this.strictInsertFill(metaObject, "createTime", () -> now, LocalDateTime.class);
        this.strictInsertFill(metaObject, "createUser", () -> "haha", String.class);
        this.strictInsertFill(metaObject, "updateTime", () -> now, LocalDateTime.class);
        this.strictInsertFill(metaObject, "updateUser", () -> "haha", String.class);
    }
    // 修改時填充
    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);
        this.strictUpdateFill(metaObject, "updateUser", () -> "haha", String.class);
    }
}           
MetaObjectHandler 中聲明填充的字段,如果實體類中有,則會進行填充,如果沒有,也可以正常運作,填充動作被忽略

測試

編寫測試用例

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class MybatisPlusTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testInsert() {
        User user = new User();
        user.setId(10);
        user.setUsername("test");
        userMapper.insert(user);
    }
}           

檢視日志輸出如下,deleted 查詢條件已自動加上

==>  Preparing: INSERT INTO user (id, name, create_time, create_user, update_time, update_user) VALUES ( ?, ?, ?, ?, ?, ? )
==>  Parameters: 10(Long), test(String), 2022-03-11T20:32:31.532(LocalDateTime), haha(String), 2022-03-11T20:32:31.532(LocalDateTime), haha(String)
<==  Updates: 1           
修改的測試用例請自行編寫

總結

自動填充主要用途還是将一些與業務無關的字段,使用公共代碼進行填充,減少業務處理時還要兼顧非業務字段,讓業務代碼更純粹。

MybatisPlus 支援的邏輯删除功能,新增時需要對邏輯删除标記字段填充一個預設值,也可以使用自動填充功能進行填充。

最後關注一下,共同學習

SpringBoot整合MybatisPlus資料自動填充