关于自动填充或更新实体中的 CreateDate、CreatedBy 等在之前有一篇 jeecg 默认为空的字段值是如何被填充的? 有提到通过拦截器的方式实现,但是今天带大家了解一下如果使用 JPA 的审计功能是如何简单实现该操作的。
JPA Audit 说明
在 Spring JPA 中,支持在字段或者方法上进行注解 @CreateDate、@CreatedBy、@LastModifiedDate、@LastModifiedBy
@CreateDate
表示该字段为创建时间时间字段,在这个实体被 insert 的时候,会设置默认值
@CreatedBy
表示该字段为创建人,在这个实体被insert的时候,会设置值。
@LastModifiedDate、@LastModifiedBy同理。
附一张项目中的使用图:
如何使用审计?
难道就像上方图片显示的,只需要加上注解就可以了吗?
显然是否定的。
-
实体类上添加 @EntityListeners(AuditingEntityListener.class)
-
在需要的字段上加上 @CreatedDate、@CreatedBy、@LastModifiedDate、@LastModifiedBy 等注解。
-
在Xxx Application 启动类上添加 @EnableJpaAuditing
-
实现 AuditorAware 接口来返回你需要插入的值。重点!
如下是一个基类的代码,实现了 1、2 步:
@Data
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@ApiModelProperty(value = "唯一标识")
private String id;
@CreatedBy
private String createBy;
@CreatedDate
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建时间")
private Date createTime;
@ApiModelProperty(value = "更新者")
@LastModifiedBy
private String updateBy;
@LastModifiedDate
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新时间")
private Date updateTime;
}
第3步,启动类上增加注释:
@SpringBootApplication
@EnableJpaAuditing
public class TmaxApplication {
public static void main(String[] args) {
SpringApplication.run(TmaxApplication.class, args);
}
/**
* 测试中如果无法自动识别,可能是包路径的问题,采用手动声明bean的方式
* @return
*/
@Bean
public UserAuditor setUserAuditorAware(){
return new UserAuditor();
}
}
经过测试如果你的实体类上面的多个字段使用了 @CreatedBy 这样的注解,只会有一个生效,也就是说在一次请求中,只会被调用一次
来看第4步,也是最重要的一步:
@Configuration
@Slf4j
public class UserAuditor implements AuditorAware<String> {
/**
* 获取当前创建或修改的用户
* @return
*/
@Override
public Optional<String> getCurrentAuditor() {
UserDetails user;
try {
user = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
return Optional.ofNullable(user.getUsername());
}catch (Exception e){
return Optional.empty();
}
}
}
关于方法 getCurrentAuditor 中获取用户名的操作可根据自己实际情况书写,比如上方我用到的是 Spring Secirity 的一种写法。
如果文章有错的地方欢迎指正,大家互相留言交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:niceyoo