jpa自动填充字段和忽略更新字段

作者:一夕十六川
希望本篇内容能对大家有所帮助

一、jpa自动填充字段

实体类
@Data
@Entity
@Table(name = "user")
public class User implements Serializable {

    private static final long serialVersionUID = -47539914963692882L;

    /**
     * 主键id
     */
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    /**
     * 姓名
     */
    @Column(name = "name")
    private String name;

    /**
     * 登录账号
     */
    @Column(name = "login_name")
    private String loginName;

    /**
     * 登录密码
     */
    @Column(name = "password")
    private String password;

    /**
     * 创建人id
     */
    private Integer createUserId;

    /**
     * 创建时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;

    /**
     * 更新人id
     */
    @Column(name = "update_user_id")
    private Integer updateUserId;

    /**
     * 更新时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;

}

以上实体中 创建人、创建时间、更新人、更新时间是我们想要自动填充的字段
我们可以使用监听器来填充上述四个字段

字段填充监听器
@Component
@Log4j2
public class DataBaseAuditListener {
    /**
     * 新增数据时,填充创建人和创建时间
     */
    @PrePersist
    public void prePersist(Object object)
            throws IllegalArgumentException, IllegalAccessException {
        // 如果填充字段被分装在一个父类中: Class<?> aClass = object.getClass().getSuperclass();
        Class<?> aClass = object.getClass();
        try {
            // 填充创建用户Id
            addUserId(object, aClass, "createUserId");
            // 填充创建时间
            addOperateTime(object, aClass, "createTime");
        } catch (NoSuchFieldException e) {
            log.error("反射获取属性异常:", e);
        }


    }

    /**
     * 更新数据时,填充更新人和更新时间
     */
    @PreUpdate
    public void preUpdate(Object object)
            throws IllegalArgumentException, IllegalAccessException {
        Class<?> aClass = object.getClass();
        try {
            // 填充更新用户Id
            addUserId(object, aClass, "updateUserId");
            // 填充更新时间
            addOperateTime(object, aClass, "updateTime");
        } catch (NoSuchFieldException e) {
            log.error("反射获取属性异常:", e);
        }
    }


    /**
     * 新增数据之后的操作
     */
    @PostPersist
    public void postPersist(Object object)
            throws IllegalArgumentException, IllegalAccessException {

    }

    /**
     * 更新数据之后的操作
     */
    @PostUpdate
    public void postUpdate(Object object)
            throws IllegalArgumentException, IllegalAccessException {
    }
    /**
     * 填充用户id
     *
     * @param object
     * @param aClass
     * @param propertyName 属性名(对应实体类中的属性)
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    protected void addUserId(Object object, Class<?> aClass, String propertyName) throws NoSuchFieldException, IllegalAccessException {
        Field userId = aClass.getDeclaredField(propertyName);
        userId.setAccessible(true);
        // 获取userId值
        Object userIdValue = userId.get(object);
        if (userIdValue == null) {
            // 在此处使用当前用户id或默认用户id
            Integer id = CommonData.userId;
            userId.set(object, id);
        }
    }
    /**
     * 填充操作时间
     *
     * @param object
     * @param aClass
     * @param propertyName 属性名(对应实体类中的属性)
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    protected void addOperateTime(Object object, Class<?> aClass, String propertyName) throws NoSuchFieldException, IllegalAccessException {
        Field time = aClass.getDeclaredField(propertyName);
        time.setAccessible(true);
        // 获取time值
        Object createdTimeValue = time.get(object);
        if(createdTimeValue == null) {
            // 使用当前时间进行填充
            time.set(object, new Date());
        }
    }

}
在想要自动填充属性的实体类上加注解@EntityListeners
@EntityListeners(DataBaseAuditListener.class)
public class User implements Serializable {
// 实体内容省略
...
服务类中的保存方法
@Override
public void save(User user) {
    userDao.save(user);
}

我们来测试一下:
创建成功:
创建成功
更新成功:
更新成功

至此,jpa字段填充完成
但是这时也出现了新的问题:
创建人和创建时间消失了
这是因为jpa在更新时将所有字段全部更新了,即使字段传了null值
这时就需要用到第二部分内容了

二、jpa忽略更新字段

为了避免创建人和创建时间被覆盖,我们需要改进一下实体类:

在@Column注解中使用updatable = false
    /**
     * 创建人id
     */
    @Column(name = "create_user_id", updatable = false)
    private Integer createUserId;

    /**
     * 创建时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Column(name = "create_time", updatable = false)
    private Date createTime;

这时再更新实体,就不会更新创建人和创建时间这两个属性了

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值