在spring jpa audit 中,在字段或者方法上使用注解@CreatedDate、@CreatedBy、@LastModifiedDate、@LastModifiedBy,当进行实体插入或者更新可以自动赋值
@CreatedDate 创建时间
@CreatedBy 创建人
@LastModifiedDate 更新时间
@LastModifiedBy 更新人
使用:
1.定义实体类,并使用注解标注字段
/*
* Copyright 2019-2020 zds
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.dszhang.base;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import me.dszhang.utils.SecurityUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.domain.Auditable;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.sql.Timestamp;
/**
* 通用字段, is_del 根据需求自行添加
* @author zds
* @Date 2019年10月24日20:46:32
*/
@Getter
@Setter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
/*@JsonIgnoreProperties(value = {"createBy"},
allowGetters = false)*/
public class BaseAuditable implements Serializable {
@CreatedBy
@Column(name = "create_by", updatable = false)
@ApiModelProperty(value = "创建人", hidden = true)
private String createBy;
@LastModifiedBy
@Column(name = "update_by")
@ApiModelProperty(value = "更新人", hidden = true)
private String updatedBy;
@CreationTimestamp
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@Column(name = "create_time", updatable = false)
@ApiModelProperty(value = "创建时间", hidden = true)
private Timestamp createTime;
@UpdateTimestamp
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@Column(name = "update_time")
@ApiModelProperty(value = "更新时间", hidden = true)
private Timestamp updateTime;
/* 分组校验 */
public @interface Create {}
/* 分组校验 */
public @interface Update {}
@Override
public String toString() {
ToStringBuilder builder = new ToStringBuilder(this);
Field[] fields = this.getClass().getDeclaredFields();
try {
for (Field f : fields) {
f.setAccessible(true);
builder.append(f.getName(), f.get(this)).append("\n");
}
} catch (Exception e) {
builder.append("toString builder encounter an error");
}
return builder.toString();
}
}
使用springsecurity或者shiro,从请求token中获取当前登录用户,如:
/*
* Copyright 2019-2020 zds
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.dszhang.config;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.primitives.Bytes;
import me.dszhang.utils.SecurityUtils;
//import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.data.domain.AuditorAware;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Optional;
/**
* @description : 设置审计
* @author : dszhang
* @date : 2020/7/28
*/
@Component("auditorAware")
public class AuditorConfig implements AuditorAware<String> {
/**
* 返回操作员标志信息
*
* @return /
*/
@Override
public Optional<String> getCurrentAuditor() {
try {
// 这里应根据实际业务情况获取具体信息
return Optional.of(SecurityUtils.getCurrentUsername());
}catch (Exception ignored){
ignored.printStackTrace();
}
// 用户定时任务,或者无Token调用的情况
return Optional.of("System");
}
}
3、设置Auditor
package me.dszhang.base;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import me.dszhang.utils.StringUtils;
import org.springframework.data.domain.Auditable;
import org.springframework.lang.Nullable;
import javax.persistence.Column;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.Optional;
public class BaseEntity extends BaseAuditable
implements Auditable<String, Object,TemporalAccessor>
{
@Override
public Optional<String> getCreatedBy() {
String s = this.getCreateBy() == null?"":this.getCreateBy();
return Optional.of(s);
}
/**
*自定义 @CreatedBy
* @param s 传递过来的CreateBy(支持@RequestParam和@RequestBody)
*/
@Override
public void setCreatedBy(String s) {
String createUserId = !StringUtils.isEmpty(this.getCreateBy()) ? this.getCreateBy() : s;
this.setCreateBy(createUserId);
}
@Override
public Optional<TemporalAccessor> getCreatedDate() {
Timestamp timestamp = this.getCreateTime() ;
LocalDateTime time2 =LocalDateTime.ofEpochSecond(timestamp.getTime()/1000,0, ZoneOffset.ofHours(8));
return Optional.of(time2);
//return null ;
}
@Override
public void setCreatedDate(TemporalAccessor temporalAccessor) {
LocalDateTime localDateTime = (LocalDateTime)temporalAccessor;
Timestamp time = Timestamp.valueOf(localDateTime.now());
this.setCreateTime(time);
}
@Override
public Optional<String> getLastModifiedBy() {
String s = this.getUpdatedBy()== null?"":this.getUpdatedBy();
return Optional.of(s);
}
@Override
public void setLastModifiedBy(String s) {
String updatedBy = !StringUtils.isEmpty(getUpdatedBy()) ? getUpdatedBy() : s;
setUpdatedBy(updatedBy);
}
@Override
public Optional<TemporalAccessor> getLastModifiedDate() {
/* Timestamp timestamp = this.getUpdateTime() ;
LocalDateTime time2 =LocalDateTime.ofEpochSecond(timestamp.getTime()/1000,0, ZoneOffset.ofHours(8));
return Optional.of(time2);*/
return null;
}
@Override
public void setLastModifiedDate(TemporalAccessor temporalAccessor) {
LocalDateTime localDateTime = (LocalDateTime)temporalAccessor;
Timestamp time = Timestamp.valueOf(localDateTime.now());
super.setUpdateTime(time);
}
@Nullable
@Override
public Object getId() {return null; } ;
public void setId(Object id){ };
@Override
public boolean isNew() {
return false;
}
}
4、新建 User类,继承BaseEntity
/*
* Copyright 2019-2020 zds
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.dszhang.modules.system.domain;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import me.dszhang.base.BaseEntity;
import javax.persistence.*;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Date;
import java.util.Objects;
import java.util.Set;
/**
* @author zds
* @date 2018-11-22
*/
@Entity
@Getter
@Setter
@Table(name="sys_user")
@NoArgsConstructor
public class SysUser extends BaseEntity implements Serializable {
@Id
@Column(name = "user_id")
@NotNull(groups = Update.class)
@GeneratedValue(strategy = GenerationType.IDENTITY)
@ApiModelProperty(value = "ID", hidden = true)
private Long id;
@ManyToMany
@ApiModelProperty(value = "用户角色")
@JoinTable(name = "sys_users_roles",
joinColumns = {@JoinColumn(name = "user_id",referencedColumnName = "user_id")},
inverseJoinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "role_id")})
private Set<Role> roles;
@ManyToMany
@ApiModelProperty(value = "用户岗位")
@JoinTable(name = "sys_users_jobs",
joinColumns = {@JoinColumn(name = "user_id",referencedColumnName = "user_id")},
inverseJoinColumns = {@JoinColumn(name = "job_id",referencedColumnName = "job_id")})
private Set<Job> jobs;
@OneToOne
@JoinColumn(name = "dept_id")
@ApiModelProperty(value = "用户部门")
private Dept dept;
@NotBlank
@Column(unique = true)
@ApiModelProperty(value = "账号")
private String username;
@NotBlank
@ApiModelProperty(value = "姓名")
private String nickName;
@Email
@NotBlank
@ApiModelProperty(value = "邮箱")
private String email;
@NotBlank
@ApiModelProperty(value = "电话号码")
private String phone;
@ApiModelProperty(value = "用户性别")
private String gender;
@ApiModelProperty(value = "头像真实名称",hidden = true)
private String avatarName;
@ApiModelProperty(value = "头像存储的路径", hidden = true)
private String avatarPath;
@ApiModelProperty(value = "密码")
private String password;
@NotNull
@ApiModelProperty(value = "是否启用")
private Boolean enabled;
@NotNull
@ApiModelProperty(value = "用户类型")
private Integer type;
@ApiModelProperty(value = "是否为admin账号", hidden = true)
private Boolean isAdmin = false;
@Column(name = "pwd_reset_time")
@ApiModelProperty(value = "最后修改密码的时间", hidden = true)
private Date pwdResetTime;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
SysUser user = (SysUser) o;
return Objects.equals(id, user.id) &&
Objects.equals(username, user.username);
}
@Override
public int hashCode() {
return Objects.hash(id, username);
}
}