Spring @Audited 审计——‘createdBy’,‘createdDate’,‘lastModifiedBy’和‘lastModifiedDate’

原创性声明:本文完全为笔者原创,请尊重笔者劳动力。转载务必注明原文地址。

这是一个很常见的需求 :

例如。简书数据库中,文章表(articles)中的某条记录是被那个账号创建的(@CreateBy),最后的一次更新是哪个账号干的(@LastModifiedBy),以及创建的时间是什么(@CreateDate),最后更新的时间又是什么(@LastModifiedDate)?

这既可以作为用户所需要的字段信息,在一定程度上也是一种操作记录的体现。当然,这样的功能,完全可以自己在CRUD操作的时候去实现,但是秉持着程序的精简性和可靠性,用Spring 的@Audited自然是一种更好的方法了。

Spring审计功能简单易用(我的项目建立在Spring boot之上)。

假设我们的domain包下,有一个抽象的审计超类——AbstractAuditingEntity,其他的实体类都继承它。


@MappedSuperclass
@Audited
@EntityListeners(AuditingEntityListener.class)
public abstract class AbstractAuditingEntity {

      @CreatedBy
      @Column(name = "created_by", nullable = false, length = 50, updatable = false)
      @JsonIgnore
      private String createdBy;

      @CreatedDate
      @Column(name = "created_date", nullable = false, updatable = false)
      @JsonIgnore
      private LocalDateTime createdDate = LocalDateTime.now();

      @LastModifiedBy
      @Column(name = "last_modified_by", length = 50)
      @JsonIgnore
      private String lastModifiedBy;

      @LastModifiedDate
      @Column(name = "last_modified_date")
      @JsonIgnore
      private LocalDateTime lastModifiedDate = LocalDateTime.now();

      // 省略对应的 set/get 方法......
}

简单讲一下类上三个注解的作用。

@MappedSuperclass API文档是这么写的: 指定一个类,其映射信息应用于从其继承的实体。 映射的超类没有为它定义的单独的表。使用MappedSuperclass注释指定的类可以以与实体相同的方式进行映射,除了映射将仅应用于其子类,因为映射的超类本身没有表。(谷歌翻译)翻译的虽然不是非常顺口,但大致还是能看懂的。意思就是说,应用这个注解的类(比如上面例子的AbstractAuditingEntity)在数据库里是没有表与它对应的,但是它的属性(这里的四个属性),将会被继承的子类所继承,并映射到子类在数据库中对应的这四个字段。那么显而易见,这个注解可以把众多实体类的公共属性提取出来,这也是此处的作用。
@Audited API文档是这么写的: 当应用于类时,表示其所有属性都应该被审计。 当应用于一个字段时,表示该字段应该被审计。没什么好解释的,谷歌这个翻译,很6。
@EntityListeners(AuditingEntityListener.class) 指定要用于实体或映射超类的回调侦听器类。 此注释可以应用于实体类或映射超类。相当于给当前的超类注册一个监听器,注册给谁呢,就是Spring提供的AuditingEntityListener这个类,从名字上看就大概揣测一二这个监听器的作用,监听一个实体创建或更新时的审计用的。

显然这三个注解都是必不可少的,当然如果不把公共实体抽取出来,而是在某个具体的类上(如Article)使用这些注解和声明定义这四个属性,那么@MappedSuperclass就没有必要了。

至于@CreatedBy@CreatedDate@LastModifiedBy@LastModifiedDate,那就对号入座了。

@JsonIgnore : 忽略改字段的序列化和反序列化。这么做,客户端将不会获得该字段。

这么做还是不够的,如果我们没有在JPA操作中启用审计功能的话。启用的方法很简单,只需要在主类上加上启用的注解即可:

@SpringBootApplication
@EnableJpaAuditing //在JPA操作中启用审计功能
public class Application 
{
    public static void main( String[] args )
    {
        SpringApplication.run(Application.class, args);
    }
}

跑起来我们会发现。createBylastModifiedBy的值并不会被相应地自动填上。因此我们还少了一个步骤——实现AuditorAware接口,并实现getCurrentAuditor方法,不然程序不知道创建者和最后修改者怎么给值。

@Component
public class SpringSecurityAuditorAware implements AuditorAware<String> {

  @Override
  public String getCurrentAuditor() {
    // TODO 返回当前session会话中的账户名即可
  }
}

getCurrentAuditor方法中也体现了记录createdBylastModifiedBy的策略(包括是保存操作者用户名,还是电话号码或其他信息),一般情况下,当然是返回session中的账户信息(通常是账户名),因为肯定是这个账户修改的对应数据。

如此一来,在对普通实体类的CRUD操作时,便不用操心某条记录是谁创建的、啥时候创建的,又是谁最后一次更新的,最后一次更新是啥时候这样的破事儿了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,314评论 19 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 47,040评论 6 342
  • 此篇翻译的是Spring Boot官方指南 Part III. 使用 Spring Boot (Using Spr...
    K天道酬勤阅读 11,752评论 0 21
  • 风的那边埋葬着两个诗人一个热爱生活 向往幸福用诗篇记录岁月一个怀疑世界 倾心死亡用诗篇遗忘过去然而没有...
    子健阅读 4,155评论 1 7
  • 1.描述 The count-and-say sequence is the sequence of intege...
    YellowLayne阅读 1,878评论 0 0