SpringBoot 集成 MyBatisPlus 系列
SpringBoot 版本:2.6.4
MybatisPlus 版本:3.5.1
- 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)
)
整合 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 支持的邏輯刪除功能,新增時需要對邏輯刪除標記字段填充一個默認值,也可以使用自動填充功能進行填充。