大数跨境
0
0

4 种方案!Spring Boot 自动填充公共字段,最后一种无需任何代码

4 种方案!Spring Boot 自动填充公共字段,最后一种无需任何代码 Spring全家桶实战案例
2025-11-21
0
导读:4 种方案!Spring Boot 自动填充公共字段,最后一种无需任何代码
Spring Boot 3实战案例锦集PDF电子书已更新至100篇!

🎉🎉《Spring Boot实战案例合集》目前已更新191个案例,我们将持续不断的更新。文末有电子书目录。

💪💪永久更新承诺

我们郑重承诺,所有订阅合集的粉丝都将享受永久免费的后续更新服务

💌💌如何获取
订阅我们的合集点我订阅,并通过私信联系我们,我们将第一时间将电子书发送给您。

→ 现在就订阅合集

环境:SpringBoot3.4.2



1. 简介

在软件开发中,为了更好地管理数据、追踪数据变更情况以及明确数据操作责任,许多数据表都会设置一些公共字段,例如记录数据创建者的“创建人”字段、标记数据创建时刻的“创建时间”字段,以及记录数据最后修改者和修改时间的“更新人”“更新时间”字段等。如下表结构,其中4个字段用来记录数据创建时间,修改时间,创建人,修改人:

这些公共字段对于数据管理、审计追踪等至关重要,但在常规开发模式下,每当进行数据的新增、修改等操作时,开发人员都需要在代码中手动为这些公共字段赋值。随着项目规模的不断扩大,业务逻辑日益复杂,涉及的数据操作场景也越来越多,这种手动设置公共字段的方式不仅效率低下,增加了开发人员的工作量,还极易因为人为疏忽而导致字段值设置错误或遗漏,进而影响数据的准确性和完整性。

本篇文章,我们将介绍4种实用的方案实现公共字段的填充。如下是第四种实现方案:

pack:  fill:    tables:      '[t_product]':        INSERT:        - field: create_time          name: timeValueFill        - field: created_by          name: userValueFill        UPDATE:        - field: update_time          name: timeValueFill        - field: updated_by          name: userValueFill

我们只需要配置哪些表中的哪些字段需要进行填充,以及具体使用哪个Bean提供的值进行填充。针对每一个字段,我们都可以进行自定义填充对象(声明为bean)。

2.实战案例

2.1 基于JPA实现

JPA的实现比较简单,我们只需要使用一些注解即可:

第一步:使用 @EntityListeners 注解

// 定义实体对象基类@MappedSuperclasspublic abstract class BaseEntity {  @CreatedDate  private LocalDateTime createTime;  @LastModifiedDate  private LocalDateTime updateTime;  @CreatedBy  private String createdBy;  @LastModifiedBy  private String updatedBy;}@Entity@Table(name = "t_product")@EntityListeners(AuditingEntityListener.class)public class Product extends BaseEntity {  // ...其它属性}
第二步:自定义 AuditorAware Bean
@Componentpublic class PackAuditorAware implements AuditorAware<String> {  @Override  public Optional<StringgetCurrentAuditor() {    return Optional.of("pack") ;  }}

该对象是用来提供当前的操作人信息。会自动应用到@CreatedBy 和 @LastModifiedBy 注解对应的字段所需要的值。

当我们对Product实体进行新增和修改的时候会自动的更新相应的字段。

到此,基于JPA的实现就完成了,是不是非常的简单?

2.2 基于MyBatis实现

在MyBatis中,我们可以通过自定义拦截器Interceptor来实现字段的填充,如下自定义拦截器:

@Intercepts({   @Signature(    type = Executor.class    method = "update"    args = { MappedStatement.classObject.class })   })@Componentpublic class AutoFillInterceptor implements Interceptor {  @Override  public Object intercept(Invocation invocation) throws Throwable {    MappedStatement ms = (MappedStatement) invocation.getArgs()[0];    Object parameter = invocation.getArgs()[1];    // 获取 SQL 命令类型    SqlCommandType sqlCommandType = ms.getSqlCommandType();    if (parameter instanceof BaseEntity entity) {      fillField(sqlCommandType, entity);    } else if (parameter instanceof Map param) {      Collection<Object> values = param.values() ;      values.forEach(value -> {        if (value instanceof BaseEntity entity) {          fillField(sqlCommandType, entity);        }      }) ;    }    return invocation.proceed();  }  private void fillField(SqlCommandType sqlCommandType, BaseEntity entity) {    LocalDateTime now = LocalDateTime.now() ;    String currentUser = getCurrentUser() ;    if (SqlCommandType.INSERT == sqlCommandType) {      entity.setCreateTime(now);      entity.setCreatedBy(currentUser);    }    if (SqlCommandType.INSERT == sqlCommandType || SqlCommandType.UPDATE == sqlCommandType) {      entity.setUpdateTime(now);      entity.setUpdatedBy(currentUser);    }  }  private String getCurrentUser() {    return "m-pack";  }  @Override  public Object plugin(Object target) {    return Plugin.wrap(target, this);  }  @Override  public void setProperties(Properties properties) {  }}

只需要定义如上的拦截器并注册为bean,即可实现公共字段的填充。

【声明】内容源于网络
0
0
Spring全家桶实战案例
Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
内容 832
粉丝 0
Spring全家桶实战案例 Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
总阅读38
粉丝0
内容832