SpringBoot基于MyBatisPlus實現(xiàn)公共字段自動填充
問題背景
在增加或修改記錄時,常常需要對一些公共字段進行設(shè)置,如創(chuàng)建時間(createTime)、創(chuàng)建人(createUser)、修改時間(updateTime)、修改人(updateUser),這些信息一般不來自于網(wǎng)頁請求。實際項目中可能有很多種Entity(實體類),對每一個Entity對應(yīng)的業(yè)務(wù)代碼中都要寫這些針對公共字段的操作,造成了代碼的大量重復(fù)。
因此,可以創(chuàng)建一個用于公共字段自動填充的類,使得公共字段實現(xiàn)自動填充。
實現(xiàn)方式
主要分為兩大部分:
- 1. MetaObjectHandler實現(xiàn)類創(chuàng)建
- 2. 實體類中公共字段添加注解
1. MetaObjectHandler實現(xiàn)類創(chuàng)建
首先,建立一個MetaObjectHandler接口的實現(xiàn)類(MetaObjectHandler是MyBatisPlus提供的接口)
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
之后,重寫相關(guān)方法 (insertFill(MetaObject metaObject) 和 updateFill(MetaObject metaObject) )
@Override
public void insertFill(MetaObject metaObject) {
log.info("公共字段自動填充[insert]...");
log.info("線程id:{}", Thread.currentThread().getId());
metaObject.setValue("createTime", LocalDateTime.now());
metaObject.setValue("updateTime", LocalDateTime.now());
metaObject.setValue("createUser", threadLocal.get()); // 動態(tài)填充 填充當前登錄的用戶的 ID
metaObject.setValue("updateUser", threadLocal.get()); // 動態(tài)填充 填充當前登錄的用戶的 ID
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("公共字段自動填充[update]...");
log.info("線程id:{}", Thread.currentThread().getId());
metaObject.setValue("updateTime", LocalDateTime.now());
metaObject.setValue("updateUser", threadLocal.get());
}
注意:在對createUser和updateUser進行設(shè)置時(通常是設(shè)置id),無法拿到session,因此不能通過session的方式獲取id。這里使用的是ThreadLocal。
需要知道的是,頁面向服務(wù)器發(fā)送的每一個請求,在服務(wù)器端都會有一個獨立的線程根據(jù)該請求進行一系列操作。例如,頁面發(fā)來一個修改用戶的請求,到了服務(wù)器端,攔截器的preHandle方法、controller層的update方法,以及公共字段填充類的updateFill方法都是由同一個線程執(zhí)行的。

因此,可以在攔截器執(zhí)行preHandle方法時,將session中的id數(shù)據(jù)保存到ThreadLocal對象中,在進行公共字段填充時,再將id從ThreadLocal對象中取出即可。
我將ThreadLocal配置成了一個Bean來管理(也可以用一個工具類來封裝ThreadLocal,定義一個類變量)
ThreadLocal的Bean配置:
@Configuration
public class ThreadLocalConfig {
@Bean
public ThreadLocal<Long> threadLocal(){
ThreadLocal<Long> threadLocal = new ThreadLocal<>();
return threadLocal;
}
}
攔截器注入ThreadLocal,并將id存入ThreadLocal:
public class MyInterceptor implements HandlerInterceptor {
@Autowired
ThreadLocal<Long> threadLocal;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("線程id:{}", Thread.currentThread().getId());
threadLocal.set((Long) request.getSession().getAttribute("employeeId"));
...
對session進行判斷的代碼
...
}
}
之后,在MetaObjectHandler實現(xiàn)類中也對ThreadLocal的Bean進行注入
2. 實體類中公共字段添加注解
@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;
如此,便實現(xiàn)了公共字段的自動填充
到此這篇關(guān)于SpringBoot基于MyBatisPlus實現(xiàn)公共字段自動填充的文章就介紹到這了,更多相關(guān)SpringBoot MyBatisPlus公共字段自動填充內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot如何對LocalDateTime進行格式化并解析
這篇文章主要介紹了SpringBoot如何對LocalDateTime進行格式化方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07
解決IDEA報錯Failed?to?start?bean‘documentationPluginsBootstra
springboot創(chuàng)建監(jiān)聽和處理事件的操作方法

