Mybatis/MybatisPlus公共字段填充与配置逻辑删除

 更新时间:2025年05月16日 10:13:18   作者:sjsjsbbsbsn  
MyBatis 和 MyBatis-Plus 都提供了相应的机制来处理这些公共字段的填充和逻辑删除,下面就来介绍一下,感兴趣的可以了解一下

在开发过程中,很多时候需要处理一些公共字段,例如:创建时间、修改时间、状态字段等。这些字段通常会在插入或更新数据时进行填充,以便记录数据的变化和状态。同时,逻辑删除也是常见的业务需求,比如删除记录并不是从数据库中物理删除,而是通过更新某个字段(如 is_deleted)来标记数据已被删除。

MyBatis 和 MyBatis-Plus 都提供了相应的机制来处理这些公共字段的填充和逻辑删除。下面我们将分别介绍如何在 MyBatis 和 MyBatis-Plus 中实现公共字段填充与逻辑删除。

1.公共字段填充

mybatis:

在 MyBatis 中,公共字段填充可以通过 TypeHandler 或者使用拦截器(Interceptor)来实现。但更为常见且方便的方式是通过 插件(例如 MyBatis Plus)来进行全局配置。下面我们讲解一种使用拦截器的方式来实现公共字段填充。

MyBatis 支持通过拦截器(Interceptor)来修改执行的 SQL,或者在执行时进行公共字段的填充。你可以定义一个 Interceptor,在插入或更新操作前对公共字段进行填充:

@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 {
        // 获取当前执行的 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) {
        // 获取当前用户信息(例如从 ThreadLocal 中获取当前用户)
        String currentUser = getCurrentUser();
        
        // 添加创建时间、更新时间、创建人、更新人等字段
        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) {
        // 获取当前用户信息(例如从 ThreadLocal 中获取当前用户)
        String currentUser = getCurrentUser();
        
        // 替换 SQL,设置更新时间、更新人
        if (sql.contains("set")) {
            sql = sql.replaceFirst("set", "set update_time = now(), update_by = '" + currentUser + "', ");
        }
        return sql;
    }
    
    private String getCurrentUser() {
        // 模拟获取当前用户,实际情况可以通过 ThreadLocal 或 SecurityContext 获取
        return "admin";  // 假设当前用户是 admin
    }

记得要把拦截器注册

mybatis-plus:

通过实现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) {
        // 获取当前登录用户,假设是通过 ThreadLocal 获取当前用户
        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) {
        // 获取当前登录用户,假设是通过 ThreadLocal 获取当前用户
        String currentUser = getCurrentUser();

        this.strictUpdateFill(metaObject, "updateBy", String.class, currentUser);
        this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
    }

    private String getCurrentUser() {
        // 假设当前用户信息存储在 ThreadLocal 中
        return "admin";  // 或者从上下文中获取
    }
}

2.逻辑删除:

1. MyBatis实现方式

需手动修改所有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实现方式

提供全局配置和注解两种方式。

方式1:全局配置(application.yml)

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: isDeleted   # 逻辑删除字段名
      logic-delete-value: 1           # 删除标记值
      logic-not-delete-value: 0       # 未删除标记值

方式2:注解标记

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;
    }
}

到此这篇关于Mybatis/MybatisPlus公共字段填充与配置逻辑删除的文章就介绍到这了,更多相关MybatisPlus公共字段填充与逻辑删除内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • Java中的record使用详解

    Java中的record使用详解

    record 是 Java 14 引入的一种新语法(在 Java 16 中成为正式功能),用于定义不可变的数据类,这篇文章给大家介绍Java中的record相关知识,感兴趣的朋友一起看看吧
    2025-06-06
  • spring mybatis环境常量与枚举转换示例详解

    spring mybatis环境常量与枚举转换示例详解

    这篇文章主要为大家介绍了spring mybatis环境常量与枚举转换示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • java实现小猫钓鱼游戏

    java实现小猫钓鱼游戏

    这篇文章主要为大家详细介绍了java实现小猫钓鱼游戏,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • SpringBoot之那些注入不了的Spring占位符(${}表达式)问题

    SpringBoot之那些注入不了的Spring占位符(${}表达式)问题

    这篇文章主要介绍了SpringBoot之那些注入不了的Spring占位符(${}表达式)问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • JAVA记住密码功能的实现代码

    JAVA记住密码功能的实现代码

    这篇文章主要介绍了JAVA记住密码功能的实现代码,代码简单易懂,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-01-01
  • 详解Maven optional关键字透彻图解

    详解Maven optional关键字透彻图解

    这篇文章主要介绍了详解Maven optional关键字透彻图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • idea git设置Local Changes窗口过程(代码/文件变更显示)

    idea git设置Local Changes窗口过程(代码/文件变更显示)

    本文介绍了在IDEA中,当代码有变更但未显示LocalChanges窗口时,可以通过设置取消勾选“Usenon-modalcommitinterface”选项来解决该问题
    2026-04-04
  • 解析SpringSecurity+JWT认证流程实现

    解析SpringSecurity+JWT认证流程实现

    这篇文章主要介绍了解析SpringSecurity+JWT认证流程实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • JAVA中String类的使用方法示例讲解

    JAVA中String类的使用方法示例讲解

    在Java开发中,String类作为操作字符串的核心工具,其功能强大且应用广泛,这篇文章主要介绍了JAVA中String类使用方法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2026-05-05
  • java多线程编程之InheritableThreadLocal

    java多线程编程之InheritableThreadLocal

    这篇文章主要为大家详细介绍了java多线程编程之InheritableThreadLocal,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10

最新评论