傻傻分不清楚的 @CreationTimestamp、@UpdateTimestamp、@CreatedDate、@LastModifiedDate、@CreatedBy、@LastModifiedBy;相信在对于我们想要实现JPA自动更新赋值实体类的创建时间和更新时间的场景中,对于这些注解大家并不陌生;但是在使用的时候却不止从何入手,今天我门就来聊一聊这些注解的正确使用方法
操作数据库映射实体类时,通常需要记录createTime和updateTime,如果每个对象新增或修改去都去手工操作创建时间、更新时间,会显得比较繁琐。
1. @CreationTimestamp、@UpdateTimestamp
Hibernate 提供了类似上述时间注解的功能实现,这种方法
只需要在实体类上配置
@Data
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity {
/**
* 自增主键
*/
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Integer id;
/**
* 更新时间
*/
@CreationTimestamp
@Column(updatable = false, nullable = false)
private Long createTime;
/**
* 创建时间
*/
@UpdateTimestamp
@Column(nullable = false)
private Long updateTime;
}
注意:使用@UpdateTimestamp
和 @CreationTimestam
的属性类型只能为Date、LocalDateTime,不能为Long,意味着不能直接生成时间戳。
2. @CreatedDate、@LastModifiedDate
Springboot JPA 也提供了自动填充这两个字段的功能,简单配置一下即可。
@CreatedDate、@LastModifiedDate
使用@CreatedDate
和@LastModifiedDate
的属性类型可以为Date、Long、Timestamp、LocalDateTime ,意味着不能直接生成时间戳。
首先,我们的很多实体类都是需要创建时间和更新时间的,我们不想在每个实体类里都去定义这两个字段,那么我们把它抽取到基类中,让实体类去继承它。
package com.tianyalei.testautotime.entity;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
/**
* Created by wuwf on 17/4/21.
*/
@Data
@MappedSuperclass
// 不加此注解的话@CreatedDate,@LastModifiedDate不起作用, 表示监听这个类 AuditingEntityListener.class是自带的默认监听类
@EntityListeners(AuditingEntityListener.class)
// @DynamicInsert,@DynamicUpdate只插入更新已更改字段
@DynamicInsert
@DynamicUpdate
public abstract class BaseEntity {
/**
* 自增主键
*/
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Integer id;
/**
* 更新时间
*/
@CreatedDate
@Column(updatable = false, nullable = false)
private Long createTime;
/**
* 创建时间
*/
@LastModifiedDate
@Column(nullable = false)
private Long updateTime;
}
然后,在Application启动类中添加注解 @EnableJpaAuditing
@EnableJpaAuditing
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
3. @CreatedBy、@LastModifiedBy
此外,Spring Data JPA 还提供 @CreatedBy 和 @LastModifiedBy 注解,用于保存和更新当前操作用户的信息(如id、name)。如果有这方面的需求,可以参考下面的配置实现:
package com.tianyalei.testautotime.entity;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
/**
* Created by wuwf on 17/4/21.
*/
@Data
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity {
/**
* 自增主键
*/
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Integer id;
/**
* 更新时间
*/
@CreatedDate
@Column(updatable = false, nullable = false)
private Long createTime;
/**
* 创建时间
*/
@LastModifiedDate
@Column(nullable = false)
private Long updateTime;
/**
* 创建人
*/
@CreatedBy
private Integer createBy;
/**
* 最后修改人
*/
@LastModifiedBy
private Integer lastModifiedBy;
}
需要实现org.springframework.data.domain.AuditorAware这个类,根据你需要返回的类型修改这个T,比如我需要返回的是数值,就是Integer。需要注意的是,类需要加上@Component以便spring扫描到,否则不起作用。
配置实现AuditorAware接口,以获取字段需要插入的信息:
@Component
@Slf4j
public class SpringSecurityAuditorAware implements AuditorAware<Integer> {
/**
* 返回操作员标志信息
*
* @return
*/
@Override
public Optional<Integer> getCurrentAuditor() {
// 这里应根据实际业务情况获取具体信息
return Optional.of(new Random().nextInt(1000));
}
}
如果有多个实现,则会报错找到两个实现类
No qualifying bean of type ‘org.springframework.data.domain.AuditorAware<?>’ available: expected single matching bean but found 2: springSecurityAuditorAware,springSecurityAuditorAwareTest
这时,只需要在EnableJpaAuditing注解后增加参数说明需要使用哪个就可以
@SpringBootApplication
@EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}