在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);
}


