MybatisPlus字段自動填充&樂觀鎖的方法實現(xiàn)
MyBatis-Plus 提供了一個便捷的自動填充功能,用于在插入或更新數(shù)據(jù)時自動填充某些字段,如創(chuàng)建時間、更新時間等。
自動填充功能通過實現(xiàn) com.baomidou.mybatisplus.core.handlers.MetaObjectHandler 接口來實現(xiàn)。
1.使用步驟
1.定義實體類
@TableField(fill = FieldFill.INSERT):表示該字段在執(zhí)行 insert 操作時進行填充。
@TableField(fill = FieldFill.INSERT_UPDATE):表示該字段在執(zhí)行 insert 和 update 操作時進行填充。
LocalDateTime:這里使用 LocalDateTime 作為時間類型,也可以使用 Date 或 Instant 等
@Data
public class User {
private Long id;
private String name;
@TableField(value = "pwd",select = false)
private String password;
private Integer age;
private String tel;
@TableField(exist = false)
private String online;
private Integer deleted;
// 只在插入時自動填充字段
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
// 在插入和更新時填充字
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
private String updateUser;
}2.編寫填充處理器
創(chuàng)建一個類來實現(xiàn) MetaObjectHandler 接口,并重寫 insertFill 和 updateFill 方法。
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("開始插入填充...");
// 創(chuàng)建時間字段只需要在創(chuàng)建這條記錄的時候填充當(dāng)前時間
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
// 更新數(shù)據(jù)的人,在插入一條記錄的時候要把這個人記錄到數(shù)據(jù)庫
this.strictInsertFill(metaObject, "updateUser", String.class, "admin");
// 更新時間,在插入一條記錄的時候要把當(dāng)前時間記錄到數(shù)據(jù)庫
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("開始更新填充...");
// 更新某條記錄的時候,把該記錄的更新的人記錄
// this.strictUpdateFill(metaObject, "updateUser",String.class, "zhangsan");
// 更新時間字段,在更新一條記錄的時候要把當(dāng)前時間記錄到數(shù)據(jù)庫
// this.strictUpdateFill(metaObject, "updateTime",LocalDateTime.class, LocalDateTime.now());
// this.strictUpdateFill(metaObject, "updateTime",LocalDateTime.class, LocalDateTime.now());
this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
this.setFieldValByName("updateUser", "zhangsan", metaObject);
}
}3.ID生成策略
- id生成策略問題在實際工作中具備很強的現(xiàn)實意義。我們現(xiàn)在實驗過程中數(shù)據(jù)庫的id直接用 數(shù)字1、2、3來寫,是非常危險的,很容易被人“拖庫”,因此需要保證數(shù)據(jù)庫中的數(shù)據(jù)記錄 具備“無序性”。MP給我們提供了多種ID生成策略,可以在配置文件中配置這種策略。
- “拖庫” 指的是攻擊者通過漏洞或非法手段獲取整個數(shù)據(jù)庫的完整備份(即“拖走數(shù)據(jù)庫”)。如果數(shù)據(jù)庫中的主鍵 ID 是連續(xù)的數(shù)字(如 1、2、3),攻擊者可以輕松遍歷所有記錄,批量爬取敏感數(shù)據(jù),甚至進一步發(fā)起注入攻擊。因此,使用無序、非連續(xù)的 ID 生成策略是提升數(shù)據(jù)庫安全性的重要手段。
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
# 主鍵自增
id-type: auto
# 表前綴
table-prefix: tbl_
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 04.測試代碼
1.testInsert():測試插入操作
功能:向數(shù)據(jù)庫插入一條新的用戶記錄。
關(guān)鍵點:
使用
userMapper.insert(user)方法,直接傳入實體對象。MyBatis-Plus 會自動生成主鍵(如配置了
@TableId或全局主鍵策略)。
2.testUpdate():基于條件更新
功能:根據(jù)條件更新指定字段。
分析:
使用
UpdateWrapper動態(tài)構(gòu)建更新條件。userUpdateWrapper.set("name", "更887"):直接指定更新的字段名和值。userUpdateWrapper.eq("id", "1916126238607409154"):通過eq方法設(shè)置 WHERE 條件。調(diào)用
userMapper.update(userUpdateWrapper)執(zhí)行更新。
3.testUpdate1():基于實體主鍵更新
功能:先查詢后更新,通過實體主鍵更新記錄。
分析:
- 通過
userMapper.selectById("1916131310603149314")查詢用戶。 - 修改實體屬性后,調(diào)用
userMapper.updateById(user)更新。 - MyBatis-Plus 會根據(jù)實體中的
@TableId自動生成 WHERE 條件(如WHERE id = ?)。 - 支持自動填充(如
updateTime字段)。
@Test
public void testInsert() {
User user = new User();
user.setName("張99");
user.setAge(19);
user.setTel("123456789");
user.setPassword("123456");
int insert = userMapper.insert(user);
System.out.println("insert:"+insert);
}
@Test
public void testUpdate() {
UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
userUpdateWrapper.set("name", "更887");
userUpdateWrapper.eq("id", "1916126238607409154");
userMapper.update(userUpdateWrapper);
}
@Test
public void testUpdate1() {
User user = userMapper.selectById("1916131310603149314");
// 假設(shè)ID為1的用戶存在
user.setName("updatedUser");
int result = userMapper.updateById(user);
System.out.println("影響行數(shù):" + result);
System.out.println("更新后的用戶更新時間:" + user.getUpdateTime());
}2.注意事項
- 自動填充是直接給實體類的屬性設(shè)置值。
- 如果屬性沒有值,入庫時會是
null。 MetaObjectHandler提供的默認方法策略是:如果屬性有值則不覆蓋,如果填充值為null則不填充。- 字段必須聲明
@TableField注解,并設(shè)置fill屬性來選擇填充策略。 - 填充處理器需要在 Spring Boot 中聲明為
@Component或@Bean。 - 使用
strictInsertFill或strictUpdateFill方法可以根據(jù)注解FieldFill.xxx、字段名和字段類型來區(qū)分填充邏輯。 - 如果不需區(qū)分,可以使用
fillStrategy方法。 - 在
update(T entity, Wrapper<T> updateWrapper)時,entity不能為空,否則自動填充失效。 - 在
update(Wrapper<T> updateWrapper)時不會自動填充,需要手動賦值字段條件。
到此這篇關(guān)于MybatisPlus字段自動填充&樂觀鎖的方法實現(xiàn)的文章就介紹到這了,更多相關(guān)MybatisPlus字段自動填充&樂觀鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springbootAOP定義切點獲取/修改請求參數(shù)方式
這篇文章主要介紹了springbootAOP定義切點獲取/修改請求參數(shù)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08
通過JDK源碼學(xué)習(xí)InputStream詳解
InputStream抽象類是所有字節(jié)輸入流的類的超類。這篇文章主要給大家介紹了關(guān)于通過JDK源碼學(xué)習(xí)InputStream的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11
springboot中如何通過main方法調(diào)用service或dao
這篇文章主要介紹了springboot中如何通過main方法調(diào)用service或dao,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02

