jpa Auditor 自动赋值与自定义 @CreatedBy @LastModifiedBy @CreatedDate @LastModifiedDate
在spring jpa audit 中,在字段或者方法上使用注解@CreatedDate
、@CreatedBy
、@LastModifiedDate
、@LastModifiedBy
,当进行实体插入或者更新可以自动赋值
-
@CreatedDate 创建时间
-
@CreatedBy 创建人
-
@LastModifiedDate 更新时间
-
@LastModifiedBy 更新人
使用:
1.定义实体类,并使用注解标注字段
import lombok.Data; import org.springframework.data.annotation.*; import org.springframework.data.mongodb.core.mapping.Field; import java.time.LocalDateTime; @Data public class BaseEntity { @Id private String id; @Field @CreatedBy private String createUserId; @Field @LastModifiedBy private String updateUserId; @Field @CreatedDate private LocalDateTime createTime; // 创建时间 @Field @LastModifiedDate private LocalDateTime updateTime; // 修改时间 }
2.添加 AuditorAware配置,设置默认用户
@Configuration @EnableMongoAuditing(auditorAwareRef = "jpaAuditorAware")//使用mongo,也可以使用其他,如jpa(mysql) public class JpaAuditorAware implements AuditorAware<String> { @Override public String getCurrentAuditor() { return "system"; } }
这里是直接设置了一个默认值,正常来说,应该使用springsecurity或者shiro,从请求token中获取当前登录用户,如:
public final class SecurityUtils { private SecurityUtils() {} /** * 根据 Authorization 获取当前登录的用户 * * @return 返回用户id */ public static String getCurrentUserId() { SecurityContext securityContext = SecurityContextHolder.getContext(); Authentication authentication = securityContext.getAuthentication(); String userId = null; if (authentication != null) { if (authentication.getPrincipal() instanceof UserDetails) { UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal(); userId = springSecurityUser.getUsername(); } else if (authentication.getPrincipal() instanceof String) { userId = (String) authentication.getPrincipal(); } } return userId; } } //设置Auditor @Component public class SpringSecurityAuditorAware implements AuditorAware<String> { @Override public String getCurrentAuditor() { String userId= SecurityUtils.getCurrentUserId(); return userId; } }
3.新建 User类,继承BaseEntity
@Data @Document(collection = "stu") public class Stu extends BaseEntity
{ String name; String clazz; }
4.UserRepository 继承MongoRepository,连接mongo数据库
测试:
@RequestMapping("/user") public User saveUser(String name) { User user = new User(); user.setName(name); return userRepo.save(user); }
发现4个字段都自动赋值了。
但是有个问题,有些场景是这样的:
User user = new User(); user.setName(name); user.setCreateUserId("hahaha");//手动设置userId
等执行完数据库插入后,发现createUserId的值不是hahaha,还是上面默认的system
解决方法:实现Auditable接口,通过重载来自定义这些方法
@Data public class Base extends BaseEntity implements Auditable<String, String> { @Override public String getCreatedBy() { return this.getCreateUserId(); } @Override public void setCreatedBy(String s) { //如果已经设置了createUserId,则取当前设置的;否则,使用当前登录的用户id(即参数s) 下同。 String createUserId = !StringUtils.isEmpty(getCreateUserId()) ? getCreateUserId() : s; setCreateUserId(createUserId); } @Override public DateTime getCreatedDate() { return new DateTime( this.getCreateTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); } @Override public void setCreatedDate(DateTime dateTime) { setCreateTime( Instant.ofEpochMilli(dateTime.getMillis()) .atZone(ZoneId.systemDefault()) .toLocalDateTime()); } @Override public String getLastModifiedBy() { return this.getUpdateUserId(); } @Override public void setLastModifiedBy(String s) { String createUserId = !StringUtils.isEmpty(getUpdateUserId()) ? getUpdateUserId() : s; setUpdateUserId(createUserId); } @Override public DateTime getLastModifiedDate() { return new DateTime( this.getUpdateTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); } @Override public void setLastModifiedDate(DateTime dateTime) { setUpdateTime( Instant.ofEpochMilli(dateTime.getMillis()) .atZone(ZoneId.systemDefault()) .toLocalDateTime()); } @Override public boolean isNew() { return this.getId() == null; } }
测试:新建实体类stu,继承Base
@Data @Document(collection = "stu") public class Stu extends Base { String name; String clazz; }
web rest类:
@RequestMapping("/stu") public String saveStu(String name) throws JsonProcessingException { Stu stu = new Stu(); stu.setName(name); stu.setClazz(random.nextInt() + ""); stu.setCreateUserId(name);//自定义createUserId stu = stuRepo.save(stu); return om.writeValueAsString(stu); }
逃避不一定躲得过,面对不一定最难过