MybatisPlus的MetaObjectHandler與@TableLogic使用
1.MetaObjectHandler 實(shí)現(xiàn)公共字段自動(dòng)填充功能
1.1 日常開(kāi)發(fā)中的公共字段
在日常的開(kāi)發(fā)過(guò)程中, DAO層的數(shù)據(jù)庫(kù)實(shí)體類(Entity)中經(jīng)常會(huì)有一些公共字段如 create_by(創(chuàng)建人), create_time(創(chuàng)建時(shí)間) 等字段,與業(yè)務(wù)基本無(wú)關(guān)且屬于記錄本身的屬性字段。
這些字段通常會(huì)容易被大家忽視,每個(gè) Entity 都去處理一遍比較麻煩耗時(shí);如果忽略又會(huì)造成記錄本身屬性不完整,直到用到的時(shí)候才后悔莫及。
1.2 Mybatis Plus 中的解決方案
所以 Mybatis Plus 中的 MetaObjectHandler 就是針對(duì)這一問(wèn)題的良好解決方案。
MetaObjectHandler 中主要提供了兩個(gè)方法:
public interface MetaObjectHandler {
/**
* 插入元對(duì)象字段填充(用于插入時(shí)對(duì)公共字段的填充)
*
* @param metaObject 元對(duì)象
*/
void insertFill(MetaObject metaObject);
/**
* 更新元對(duì)象字段填充(用于更新時(shí)對(duì)公共字段的填充)
*
* @param metaObject 元對(duì)象
*/
void updateFill(MetaObject metaObject);
}
1.3 用法
1.3.1 定義公共字段超類,并在字段上添加注解
一般來(lái)說(shuō),這些公共字段我們都會(huì)封裝在一個(gè) Super Entity 類中,所以在這個(gè)類中,我們把所有更新和插入時(shí)需要做改動(dòng)的字段都加上 @TableField 注解,并且設(shè)置 fill 屬性。
舉例說(shuō)明:
@Data
public class BaseEntity implements Serializable {
/**
* 創(chuàng)建時(shí)間
*/
@TableField(value = "create_time", fill = FieldFill.INSERT)
private Date createTime;
/**
* 更新時(shí)間
*/
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
}
FieldFill 是一個(gè)枚舉類,其中定義了四種處理方法:
public enum FieldFill {
/**
* 默認(rèn)不處理
*/
DEFAULT,
/**
* 插入時(shí)填充字段
*/
INSERT,
/**
* 更新時(shí)填充字段
*/
UPDATE,
/**
* 插入和更新時(shí)填充字段
*/
INSERT_UPDATE
}
1.3.2 實(shí)現(xiàn) MetaObjectHandler 接口
定義一個(gè)類實(shí)現(xiàn) MetaObjectHandler 中的 insertFill 和 updateFill 抽象方法:
public class MetaHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
// getFieldValByName 方法是父接口中的默認(rèn)方法,用字段名字通過(guò)反射獲取待插入對(duì)象中指定名字字段的值
Object createTime = getFieldValByName("createTime", metaObject);
if (Objects.isNull(createTime)) {
//同理, setFieldValByName 方法也是父接口中的默認(rèn)方法,用字段名字通過(guò)反射設(shè)置待插入對(duì)象中指定名字字段的值
//插入時(shí), createTime 字段默認(rèn)為當(dāng)前時(shí)間
setFieldValByName("createTime", new Date(), metaObject);
}
Object updateTime = getFieldValByName(UPDATE_TIME_FIELD, metaObject);
if (Objects.isNull(updateTime)) {
setFieldValByName(UPDATE_TIME_FIELD, new Date(), metaObject);
}
}
@Override
public void updateFill(MetaObject metaObject) {
//更新時(shí)設(shè)置 updateTime 字段為當(dāng)前時(shí)間
setFieldValByName(UPDATE_TIME_FIELD, LocalDateTime.now(), metaObject);
}
}
2. Mybatis Plus 實(shí)現(xiàn)邏輯刪除
2.1 目前的邏輯刪除
日常開(kāi)發(fā)中,大多數(shù)場(chǎng)景下數(shù)據(jù)并不需要物理刪除,而是采用一個(gè)字段來(lái)表示這個(gè)字段是否刪除,也就是邏輯刪除。
通常情況下,我們需要在刪除的時(shí)候手動(dòng)將這個(gè)值更新為被刪除的枚舉值。
2.2 Mybatis Plus 提供的解決方案
在 Mybatis Plus 中,提供了一個(gè) @TableLogic 注解, 代碼如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface TableLogic {
/**
* 默認(rèn)邏輯未刪除值(該值可無(wú)、會(huì)自動(dòng)獲取全局配置)
*/
String value() default "";
/**
* 默認(rèn)邏輯刪除值(該值可無(wú)、會(huì)自動(dòng)獲取全局配置)
*/
String delval() default "";
}
所以當(dāng)我們需要用到邏輯刪除的字段時(shí),可以使用如下方式:
@TableLogic(delval = "1", value = "0")
private String delete;
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
使用JPA進(jìn)行CriteriaQuery進(jìn)行查詢的注意事項(xiàng)
這篇文章主要介紹了使用JPA進(jìn)行CriteriaQuery進(jìn)行查詢的注意事項(xiàng),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
SpringBoot使用Redis實(shí)現(xiàn)分布式鎖
這篇文章主要為大家詳細(xì)介紹了SpringBoot使用Redis實(shí)現(xiàn)分布式鎖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05
SpringBoot線程池和Java線程池的使用和實(shí)現(xiàn)原理解析
這篇文章主要介紹了SpringBoot線程池和Java線程池的用法和實(shí)現(xiàn)原理,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04
SpringBoot使用@Cacheable出現(xiàn)預(yù)覽工具亂碼的解決方法
直接使用注解進(jìn)行緩存數(shù)據(jù),我們?cè)偈褂霉ぞ呷ヮA(yù)覽存儲(chǔ)的數(shù)據(jù)時(shí)發(fā)現(xiàn)是亂碼,這是由于默認(rèn)序列化的問(wèn)題,所以接下來(lái)將給大家介紹一下SpringBoot使用@Cacheable出現(xiàn)預(yù)覽工具亂碼的解決方法,需要的朋友可以參考下2023-10-10
java常用Lambda表達(dá)式使用場(chǎng)景源碼示例
這篇文章主要為大家介紹了java常用Lambda表達(dá)式使用場(chǎng)景源碼示例及應(yīng)用解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03
基于Java Socket實(shí)現(xiàn)一個(gè)簡(jiǎn)易在線聊天功能(一)
這篇文章主要給大家介紹基于Java Socket實(shí)現(xiàn)一個(gè)簡(jiǎn)易在線聊天功能(一),分為客戶端和服務(wù)端兩段代碼,非常具有參考價(jià)值,感興趣的朋友一起學(xué)習(xí)吧2016-05-05
Java的String類中的startsWith方法和endsWith方法示例詳解
大家應(yīng)該都知道startsWith()方法用于檢測(cè)字符串是否以指定的前綴開(kāi)始,endsWith()方法用于測(cè)試字符串是否以指定的后綴結(jié)束,本文就Java的String類中的startsWith方法和endsWith方法給大家詳細(xì)講解,感興趣的朋友一起看看吧2023-11-11

