当前位置: 首页 > 工具软件 > Auditor > 使用案例 >

jpa Auditor 自动赋值与自定义 @CreatedBy @LastModifiedBy @CreatedDate @LastModifiedDate

阴高寒
2023-12-01

在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);
    }
}
 类似资料: