MyBatis-Plus實現(xiàn)公共字段自動填充功能詳解
1.問題分析
我們在開發(fā)中經(jīng)常遇到多個實體類有共同的屬性字段,例如在用戶注冊時需要設(shè)置創(chuàng)建時間、創(chuàng)建人、修改時間、修改人等字段,在用戶編輯信息時需要設(shè)置修改時間和修改人等字段。這些字段屬于公共字段,也就是很多表中都有這些字段,能不能對于這些公共字段在某個地方統(tǒng)一處理,來簡化開發(fā)呢?

答案就是我們可是使用Mybatis Plus提供的公共字段自動填充功能。
2.實現(xiàn)步驟
Mybatis Plus公共字段自動填充,也就是在插入或者更新的時候為指定字段賦予指定的值,使用它的好處就是可以統(tǒng)一對這些字段進(jìn)行處理,避免了重復(fù)代碼。
實現(xiàn)步驟:
在實體類的屬性上加入@TableField注解,指定自動填充的策略
@TableField(fill = FieldFill.INSERT)//插入時填充字段 private LocalDateTime createTime; @TableField(fill = FieldFill.INSERT_UPDATE)//插入、更新時填充字段 private LocalDateTime updateTime; @TableField(fill = FieldFill.INSERT)//插入時填充字段 private Long createUser; @TableField(fill = FieldFill.INSERT_UPDATE)//插入、更新時填充字段 private Long updateUser;
按照框架要求編寫元數(shù)據(jù)對象處理器,在此類中統(tǒng)一為公共字段賦值,此類需要實現(xiàn)MetaObjectHandler接口
package com.lyq.reggie.common;
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.time.LocalDateTime;
/**
* 自定義元數(shù)據(jù)對象處理器
*/
@Component
@Slf4j
public class MyMetaObjecthandler implements MetaObjectHandler {
/**
* 插入操作,自動填充
* @param metaObject
*/
@Override
public void insertFill(MetaObject metaObject) {
log.info("公共字段自動填充[insert]...");
log.info(metaObject.toString());
metaObject.setValue("createTime", LocalDateTime.now());
metaObject.setValue("updateTime",LocalDateTime.now());
metaObject.setValue("createUser", BaseContext.getCurrentId());
metaObject.setValue("updateUser",BaseContext.getCurrentId());
}
/**
* 更新操作,自動填充
* @param metaObject
*/
@Override
public void updateFill(MetaObject metaObject) {
log.info("公共字段自動填充[update]...");
log.info(metaObject.toString());
long id = Thread.currentThread().getId();
log.info("線程id為:{}",id);
metaObject.setValue("updateTime",LocalDateTime.now());
metaObject.setValue("updateUser",BaseContext.getCurrentId());
}
}
3. 實現(xiàn)字段全局填充
這個時候我們嫌棄每個表都需要加對應(yīng)的注解,麻煩,這個時候我們就可以使用Mybatis Plus提供全局配置 sqlInjector 用于注入ISqlInjector接口的子類,實現(xiàn)自定義方法注入。
自定義自己的通用方法可以實現(xiàn)接口ISqlInjector也可以繼承抽象類 AbstractSqlInjector 注入通用方法 SQL 語句 然后繼承 BaseMapper 添加自定義方法,全局配置 sqlInjector 注入 MP 會自動將類所有方法注入到 mybatis 容器中。
首先我們需要增加一個配置類,將這個數(shù)據(jù)過濾器注冊為bean
@Configuration
public class MybatisPlusConfig {
/*
* @version V1.0
* Title: updateInterceptor
* @author LiuYanQiang
* @description 插入數(shù)據(jù)過濾器
* @createTime 2022/1/13 14:30
* @param []
* @return com.tfjybj.intelligentArticleSystem.config.MybatisPlusConfig.UpdateInterceptor*/
@Bean
public UpdateInterceptor updateInterceptor() {
return new UpdateInterceptor();
}
}
再接著寫攔截方法繼承抽象類 AbstractSqlInjector 并且實現(xiàn)接口ISqlInjector來進(jìn)行SQL的攔截實現(xiàn)公共字段的全局填充
package com.lyq.jsoup.config.MybatisPlusConfig;
import com.baomidou.mybatisplus.extension.handlers.AbstractSqlParserHandler;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import java.lang.reflect.Field;
import java.sql.Timestamp;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
/**
* @author : [LiuYanQiang]
* @version : [v1.0]
* @className : UpdateInterceptor
* @description : [自動給創(chuàng)建時間個更新時間加值]
* @createTime : [2022/1/12 9:09]
* @updateUser : [LiuYanQiang]
* @updateTime : [2022/1/12 9:09]
* @updateRemark : [描述說明本次修改內(nèi)容]
*/
@Intercepts(value = {@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
public class UpdateInterceptor extends AbstractSqlParserHandler implements Interceptor {
/**
* 創(chuàng)建時間
*/
private static final String CREATE_TIME = "createTime";
/**
* 更新時間
*/
private static final String UPDATE_TIME = "updateTime";
@Override
public Object intercept(Invocation invocation) throws Throwable {
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
// SQL操作命令
SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
// 獲取新增或修改的對象參數(shù)
Object parameter = invocation.getArgs()[1];
// 獲取對象中所有的私有成員變量(對應(yīng)表字段)
Field[] declaredFields = parameter.getClass().getDeclaredFields();
if (parameter.getClass().getSuperclass() != null) {
Field[] superField = parameter.getClass().getSuperclass().getDeclaredFields();
declaredFields = ArrayUtils.addAll(declaredFields, superField);
}
// mybatis plus判斷
boolean plus= parameter.getClass().getDeclaredFields().length == 1 && parameter.getClass().getDeclaredFields()[0].getName().equals("serialVersionUID");
//兼容mybatis plus
if (plus) {
Map<String, Object> updateParam = (Map<String, Object>) parameter;
Class<?> updateParamType = updateParam.get(updateParam.keySet().iterator().next()).getClass();
declaredFields = updateParamType.getDeclaredFields();
if (updateParamType.getSuperclass() != null) {
Field[] superField = updateParamType.getSuperclass().getDeclaredFields();
declaredFields = ArrayUtils.addAll(declaredFields, superField);
}
}
String fieldName = null;
for (Field field : declaredFields) {
fieldName = field.getName();
if (Objects.equals(CREATE_TIME, fieldName)) {
if (SqlCommandType.INSERT.equals(sqlCommandType)) {
field.setAccessible(true);
field.set(parameter, new Timestamp(System.currentTimeMillis()));
}
}
if (Objects.equals(UPDATE_TIME, fieldName)) {
if (SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType)) {
field.setAccessible(true);
//兼容mybatis plus的update
if (plus) {
Map<String, Object> updateParam = (Map<String, Object>) parameter;
field.set(updateParam.get(updateParam.keySet().iterator().next()), new Timestamp(System.currentTimeMillis()));
} else {
field.set(parameter, new Timestamp(System.currentTimeMillis()));
}
}
}
}
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
if (target instanceof Executor) {
return Plugin.wrap(target, this);
}
return target;
}
@Override
public void setProperties(Properties properties) {
}
}
到此這篇關(guān)于MyBatis-Plus實現(xiàn)公共字段自動填充功能詳解的文章就介紹到這了,更多相關(guān)MyBatis-Plus字段自動填充內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MyBatisPlus實現(xiàn)自動填充字段的實踐
- MyBatis-Plus自動填充字段的詳細(xì)教程
- mybatis-plus調(diào)用update方法時,自動填充字段不生效問題及解決
- MyBatis-Puls插入或修改時某些字段自動填充操作示例
- Mybatis-Plus實現(xiàn)公共字段自動填充的項目實踐
- MyBatis-Plus邏輯刪除和字段自動填充的實現(xiàn)
- Mybatis-Plus自動填充更新操作相關(guān)字段的實現(xiàn)
- MyBatis-Plus實現(xiàn)字段自動填充功能的示例
- Mybatis plus通用字段自動填充的示例
- Mybatis攔截器實現(xiàn)公共字段填充的示例代碼
相關(guān)文章
深入理解springMVC中的Model和Session屬性
這篇文章主要介紹了深入理解springMVC中的Model和Session屬性,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12
SpringBoot3整合Nacos?V2.3.2的詳細(xì)過程
本文介紹了如何在?Spring?Boot?3.2.x?項目中整合?Nacos?2.3.2,包括依賴配置、Nacos?服務(wù)發(fā)現(xiàn)與動態(tài)配置的配置方法,通過整合?Nacos,Spring?Boot?應(yīng)用可以實現(xiàn)高效的服務(wù)發(fā)現(xiàn)、動態(tài)配置管理以及分布式系統(tǒng)中的靈活擴(kuò)展,感興趣的朋友跟隨小編一起看看吧2024-11-11
SpringBoot如何根據(jù)目錄結(jié)構(gòu)生成API接口前綴
這篇文章主要介紹了SpringBoot如何根據(jù)目錄結(jié)構(gòu)生成API接口前綴,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02
Java線程安全解決方案(synchronized,ReentrantLock,Atomic)
這篇文章主要介紹了Java線程安全解決方案(synchronized,ReentrantLock,Atomic),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
Java處理字節(jié)類型數(shù)據(jù)的實現(xiàn)步驟
字節(jié)(Byte)是計算機信息技術(shù)用于計量存儲容量的一種基本單位,通常簡寫為B,在ASCII編碼中1Byte可以表示一個標(biāo)準(zhǔn)的英文字符,包括大寫字母、小寫字母、數(shù)字、標(biāo)點符號和控制字符等,本文給大家介紹了Java如何優(yōu)雅的處理字節(jié)類型數(shù)據(jù),需要的朋友可以參考下2024-07-07
maven利用tomcat插件部署遠(yuǎn)程Linux服務(wù)器的步驟詳解
Maven已經(jīng)是Java的項目管理常用方式,下面這篇文章主要給大家介紹了關(guān)于maven利用tomcat插件部署遠(yuǎn)程Linux服務(wù)器的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11

