Mybatis/MybatisPlus公共字段填充與配置邏輯刪除
在開發(fā)過程中,很多時候需要處理一些公共字段,例如:創(chuàng)建時間、修改時間、狀態(tài)字段等。這些字段通常會在插入或更新數(shù)據(jù)時進(jìn)行填充,以便記錄數(shù)據(jù)的變化和狀態(tài)。同時,邏輯刪除也是常見的業(yè)務(wù)需求,比如刪除記錄并不是從數(shù)據(jù)庫中物理刪除,而是通過更新某個字段(如 is_deleted
)來標(biāo)記數(shù)據(jù)已被刪除。
MyBatis 和 MyBatis-Plus 都提供了相應(yīng)的機制來處理這些公共字段的填充和邏輯刪除。下面我們將分別介紹如何在 MyBatis 和 MyBatis-Plus 中實現(xiàn)公共字段填充與邏輯刪除。
1.公共字段填充
mybatis:
在 MyBatis 中,公共字段填充可以通過 TypeHandler
或者使用攔截器(Interceptor)來實現(xiàn)。但更為常見且方便的方式是通過 插件
(例如 MyBatis Plus
)來進(jìn)行全局配置。下面我們講解一種使用攔截器的方式來實現(xiàn)公共字段填充。
MyBatis 支持通過攔截器(Interceptor)來修改執(zhí)行的 SQL,或者在執(zhí)行時進(jìn)行公共字段的填充。你可以定義一個 Interceptor
,在插入或更新操作前對公共字段進(jìn)行填充:
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}) }) @Component public class MybatisInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { // 獲取當(dāng)前執(zhí)行的 SQL StatementHandler statementHandler = (StatementHandler) invocation.getTarget(); MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; BoundSql boundSql = statementHandler.getBoundSql(); // 獲取 SQL 類型(插入或更新) String sql = boundSql.getSql(); if (sql.trim().toUpperCase().startsWith("INSERT")) { // 如果是插入操作,填充公共字段 sql = addCommonFieldsForInsert(sql); } else if (sql.trim().toUpperCase().startsWith("UPDATE")) { // 如果是更新操作,填充公共字段 sql = addCommonFieldsForUpdate(sql); } // 更新 SQL boundSql.setSql(sql); return invocation.proceed(); } private String addCommonFieldsForInsert(String sql) { // 獲取當(dāng)前用戶信息(例如從 ThreadLocal 中獲取當(dāng)前用戶) String currentUser = getCurrentUser(); // 添加創(chuàng)建時間、更新時間、創(chuàng)建人、更新人等字段 sql = sql.replace("(", "(create_time, update_time, create_by, update_by, "); sql = sql.replace("values", "values(now(), now(), '" + currentUser + "', '" + currentUser + "', "); return sql; } private String addCommonFieldsForUpdate(String sql) { // 獲取當(dāng)前用戶信息(例如從 ThreadLocal 中獲取當(dāng)前用戶) String currentUser = getCurrentUser(); // 替換 SQL,設(shè)置更新時間、更新人 if (sql.contains("set")) { sql = sql.replaceFirst("set", "set update_time = now(), update_by = '" + currentUser + "', "); } return sql; } private String getCurrentUser() { // 模擬獲取當(dāng)前用戶,實際情況可以通過 ThreadLocal 或 SecurityContext 獲取 return "admin"; // 假設(shè)當(dāng)前用戶是 admin }
記得要把攔截器注冊
mybatis-plus:
通過實現(xiàn)MetaObjectHandler
接口簡化處理。
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component; import java.util.Date; @Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { // 獲取當(dāng)前登錄用戶,假設(shè)是通過 ThreadLocal 獲取當(dāng)前用戶 String currentUser = getCurrentUser(); this.strictInsertFill(metaObject, "createBy", String.class, currentUser); this.strictInsertFill(metaObject, "createTime", Date.class, new Date()); this.strictInsertFill(metaObject, "updateBy", String.class, currentUser); this.strictInsertFill(metaObject, "updateTime", Date.class, new Date()); } @Override public void updateFill(MetaObject metaObject) { // 獲取當(dāng)前登錄用戶,假設(shè)是通過 ThreadLocal 獲取當(dāng)前用戶 String currentUser = getCurrentUser(); this.strictUpdateFill(metaObject, "updateBy", String.class, currentUser); this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date()); } private String getCurrentUser() { // 假設(shè)當(dāng)前用戶信息存儲在 ThreadLocal 中 return "admin"; // 或者從上下文中獲取 } }
2.邏輯刪除:
1. MyBatis實現(xiàn)方式
需手動修改所有SQL語句或在攔截器中添加條件。
XML映射文件示例
<select id="selectById" resultType="User"> SELECT * FROM user WHERE id = #{id} AND is_deleted = 0 </select> <update id="deleteById"> UPDATE user SET is_deleted = 1 WHERE id = #{id} </update>
運行 HTML
2. MyBatis-Plus實現(xiàn)方式
提供全局配置和注解兩種方式。
方式1:全局配置(application.yml)
mybatis-plus: global-config: db-config: logic-delete-field: isDeleted # 邏輯刪除字段名 logic-delete-value: 1 # 刪除標(biāo)記值 logic-not-delete-value: 0 # 未刪除標(biāo)記值
方式2:注解標(biāo)記
public class User { @TableLogic private Integer isDeleted; }
方式3:Java配置類
@Configuration public class MyBatisPlusConfig { @Bean public GlobalConfig globalConfig() { GlobalConfig config = new GlobalConfig(); GlobalConfig.DbConfig dbConfig = new GlobalConfig.DbConfig(); dbConfig.setLogicDeleteField("isDeleted"); dbConfig.setLogicDeleteValue("1"); dbConfig.setLogicNotDeleteValue("0"); config.setDbConfig(dbConfig); return config; } }
到此這篇關(guān)于Mybatis/MybatisPlus公共字段填充與配置邏輯刪除的文章就介紹到這了,更多相關(guān)MybatisPlus公共字段填充與邏輯刪除內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
idea自動加載html、js而無需重啟進(jìn)程的操作
這篇文章主要介紹了idea自動加載html、js而無需重啟進(jìn)程的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08Java 的 FileFilter文件過濾與readline讀行操作實例代碼
這篇文章介紹了Java 的 FileFilter文件過濾與readline讀行操作實例代碼,有需要的朋友可以參考一下2013-09-09mybatis返回map結(jié)果集@MapKey使用的場景分析
這篇文章主要介紹了mybatis返回map結(jié)果集@MapKey使用的場景分析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01Springboot中使用Filter實現(xiàn)Header認(rèn)證詳解
這篇文章主要介紹了Springboot中使用Filter實現(xiàn)Header認(rèn)證詳解,當(dāng)在?web.xml?注冊了一個?Filter?來對某個?Servlet?程序進(jìn)行攔截處理時,它可以決定是否將請求繼續(xù)傳遞給?Servlet?程序,以及對請求和響應(yīng)消息是否進(jìn)行修改,需要的朋友可以參考下2023-08-08springboot配置多數(shù)據(jù)源(靜態(tài)和動態(tài)數(shù)據(jù)源)
在開發(fā)過程中,很多時候都會有垮數(shù)據(jù)庫操作數(shù)據(jù)的情況,需要同時配置多套數(shù)據(jù)源,本文主要介紹了springboot配置多數(shù)據(jù)源(靜態(tài)和動態(tài)數(shù)據(jù)源),感興趣的可以了解一下2023-09-09