MyBatis-Plus實(shí)現(xiàn)公共字段自動填充功能詳解
1.問題分析
我們在開發(fā)中經(jīng)常遇到多個(gè)實(shí)體類有共同的屬性字段,例如在用戶注冊時(shí)需要設(shè)置創(chuàng)建時(shí)間、創(chuàng)建人、修改時(shí)間、修改人等字段,在用戶編輯信息時(shí)需要設(shè)置修改時(shí)間和修改人等字段。這些字段屬于公共字段,也就是很多表中都有這些字段,能不能對于這些公共字段在某個(gè)地方統(tǒng)一處理,來簡化開發(fā)呢?
答案就是我們可是使用Mybatis Plus提供的公共字段自動填充功能。
2.實(shí)現(xiàn)步驟
Mybatis Plus公共字段自動填充,也就是在插入或者更新的時(shí)候?yàn)橹付ㄗ侄钨x予指定的值,使用它的好處就是可以統(tǒng)一對這些字段進(jìn)行處理,避免了重復(fù)代碼。
實(shí)現(xiàn)步驟:
在實(shí)體類的屬性上加入@TableField注解,指定自動填充的策略
@TableField(fill = FieldFill.INSERT)//插入時(shí)填充字段 private LocalDateTime createTime; @TableField(fill = FieldFill.INSERT_UPDATE)//插入、更新時(shí)填充字段 private LocalDateTime updateTime; @TableField(fill = FieldFill.INSERT)//插入時(shí)填充字段 private Long createUser; @TableField(fill = FieldFill.INSERT_UPDATE)//插入、更新時(shí)填充字段 private Long updateUser;
按照框架要求編寫元數(shù)據(jù)對象處理器,在此類中統(tǒng)一為公共字段賦值,此類需要實(shí)現(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. 實(shí)現(xiàn)字段全局填充
這個(gè)時(shí)候我們嫌棄每個(gè)表都需要加對應(yīng)的注解,麻煩,這個(gè)時(shí)候我們就可以使用Mybatis Plus提供全局配置 sqlInjector 用于注入ISqlInjector接口的子類,實(shí)現(xiàn)自定義方法注入。
自定義自己的通用方法可以實(shí)現(xiàn)接口ISqlInjector也可以繼承抽象類 AbstractSqlInjector 注入通用方法 SQL 語句 然后繼承 BaseMapper 添加自定義方法,全局配置 sqlInjector 注入 MP 會自動將類所有方法注入到 mybatis 容器中。
首先我們需要增加一個(gè)配置類,將這個(gè)數(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 并且實(shí)現(xiàn)接口ISqlInjector來進(jìn)行SQL的攔截實(shí)現(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)建時(shí)間個(gè)更新時(shí)間加值] * @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)建時(shí)間 */ private static final String CREATE_TIME = "createTime"; /** * 更新時(shí)間 */ 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實(shí)現(xiàn)公共字段自動填充功能詳解的文章就介紹到這了,更多相關(guān)MyBatis-Plus字段自動填充內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MyBatisPlus實(shí)現(xiàn)自動填充字段的實(shí)踐
- MyBatis-Plus自動填充字段的詳細(xì)教程
- mybatis-plus調(diào)用update方法時(shí),自動填充字段不生效問題及解決
- MyBatis-Puls插入或修改時(shí)某些字段自動填充操作示例
- Mybatis-Plus實(shí)現(xiàn)公共字段自動填充的項(xiàng)目實(shí)踐
- MyBatis-Plus邏輯刪除和字段自動填充的實(shí)現(xiàn)
- Mybatis-Plus自動填充更新操作相關(guān)字段的實(shí)現(xiàn)
- MyBatis-Plus實(shí)現(xiàn)字段自動填充功能的示例
- Mybatis plus通用字段自動填充的示例
- Mybatis攔截器實(shí)現(xiàn)公共字段填充的示例代碼
相關(guān)文章
深入理解springMVC中的Model和Session屬性
這篇文章主要介紹了深入理解springMVC中的Model和Session屬性,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12java使用Jdom實(shí)現(xiàn)xml文件寫入操作實(shí)例
這篇文章主要介紹了java使用Jdom實(shí)現(xiàn)xml文件寫入操作的方法,以完整實(shí)例形式分析了Jdom針對XML文件寫入操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10SpringBoot3整合Nacos?V2.3.2的詳細(xì)過程
本文介紹了如何在?Spring?Boot?3.2.x?項(xiàng)目中整合?Nacos?2.3.2,包括依賴配置、Nacos?服務(wù)發(fā)現(xiàn)與動態(tài)配置的配置方法,通過整合?Nacos,Spring?Boot?應(yīng)用可以實(shí)現(xiàn)高效的服務(wù)發(fā)現(xiàn)、動態(tài)配置管理以及分布式系統(tǒng)中的靈活擴(kuò)展,感興趣的朋友跟隨小編一起看看吧2024-11-11SpringBoot如何根據(jù)目錄結(jié)構(gòu)生成API接口前綴
這篇文章主要介紹了SpringBoot如何根據(jù)目錄結(jié)構(gòu)生成API接口前綴,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02Java線程安全解決方案(synchronized,ReentrantLock,Atomic)
這篇文章主要介紹了Java線程安全解決方案(synchronized,ReentrantLock,Atomic),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Java處理字節(jié)類型數(shù)據(jù)的實(shí)現(xiàn)步驟
字節(jié)(Byte)是計(jì)算機(jī)信息技術(shù)用于計(jì)量存儲容量的一種基本單位,通常簡寫為B,在ASCII編碼中1Byte可以表示一個(gè)標(biāo)準(zhǔn)的英文字符,包括大寫字母、小寫字母、數(shù)字、標(biāo)點(diǎn)符號和控制字符等,本文給大家介紹了Java如何優(yōu)雅的處理字節(jié)類型數(shù)據(jù),需要的朋友可以參考下2024-07-07maven利用tomcat插件部署遠(yuǎn)程Linux服務(wù)器的步驟詳解
Maven已經(jīng)是Java的項(xiàng)目管理常用方式,下面這篇文章主要給大家介紹了關(guān)于maven利用tomcat插件部署遠(yuǎn)程Linux服務(wù)器的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11