Jpa 如何使用@EntityListeners 实现实体对象的自动赋值

网友投稿 671 2022-12-22

Jpa 如何使用@EntityListeners 实现实体对象的自动赋值

Jpa 如何使用@EntityListeners 实现实体对象的自动赋值

1、简介

1.1 @EntityListeners

官方解释:可以使用生命周期注解指定实体中的方法,这些方法在指定的生命周期事件发生时执行相应的业务逻辑。

简单来说,就是监听实体对象的增删改查操作,并对实体对象进行相应的处理。

1.2 生命周期对应注解

JPA一共提供了7种注解,分别是:

@PostLoad :实体对象查询之后

@PrePersist : 实体对象保存之前

@PostPersist :实体对象保存之后

@PreUpdate :实体对象修改之前

@PostUpdate :实体对象修改之后

@PreRemove : 实体对象删除之前

@PostRemove :实体对象删除之后

通常情况下,数据表中都会记录创建人、创建时间、修改人、修改时间等通用属性。如果每个实体对象都要对这些通用属性手动赋值,就会过于繁琐。

现在,使用这些生命周期http://注解,就可以实现对通用属性的自动赋值,或者记录相应操作日志。

2、环境准备

数据库:mysql

项目搭建:演示项目通过Spring Boot 2.2.6构建,引入spring-boot-starter-data-jpa

2.1 数据表

-- 用户表

CREATE TABLE `acc_user` (

`id` bigint(20) NOT NULL AUTO_INCREMENT,

`username` varchar(40) NOT NULL DEFAULT '' COMMENT '用户名',

`password` varchar(40) NOT NULL DEFAULT '' COMMENT '密码',

`create_by` varchar(80) DEFAULT NULL,

`create_time` datetime DEFAULT CURRENT_TIMESTAMP,

`update_by` varchar(80) DEFAULT NULL,

`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 日志表

CREATE TABLE `modify_log` (

`id` bigint(20) NOT NULL AUTO_INCREMENT,

`action` varchar(20) NOT NULL DEFAULT '' COMMENT '操作',

`entity_name` varchar(40) NOT NULL DEFAULT '' COMMENT '实体类名',

`entity_key` varchar(20) DEFAULT NULL COMMENT '主键值',

`entity_value` varchar(400) DEFAULT NULL COMMENT '实体值',

`create_by` varchar(80) DEFAULT NULL,

`create_time` datetime DEFAULT CURRENT_TIMESTAMP,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

2.2 实体类

@MappedSuperclass

@Getter @Setter

@MappedSuperclass

// 指定对应监听类

@EntityListeners(CreateListener.class)

public abstract class IdMapped {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

private String createBy;

private Date createTime;

}

@Getter @Setter

@MappedSuperclass

// 指定对应监听类

@EntityListeners(EditListener.class)

public abstract class EditMapped extends IdMapped{

private String updateBy;

private Date updateTime;

}

用户类

@Entity

@Table(name = "acc_user")

@Getter @Setter

public class UserEntity extends EditMapped {

private String username;

private String password;

}

日志类

@Entity

@Table(name = "modify_log")

@Getter @Setter

public class ModifyLogEntity extends IdMapped{

private String action;

private String entityName;

private String entityKey;

private String entityValue;

}

2.3 监听类

public class CreateListener extends BasicListener {

// 保存之前,为创建时间和创建人赋值

@PrePersist

public void prePersist(IdMapped idMapped) {

if (Objects.isNull(idMapped.getCreateTime())) {

idMapped.setCreateTime(new Date());

}

if (StringUtils.isBlank(idMapped.getCreateBy())) {

// 根据鉴权系统实现获取当前操作用户,此处只做模拟

idMapped.setCreateBy("test_create");

}

}

// 保存之后,记录变更日志

@PostPersist

public void postPersist(IdMapped idMapped) throws jsonProcessingException {

recordLog(ACTION_INSERT, idMapped);

}

}

public class EditListener extends BasicListener {

// 修改之前,为修改人和修改时间赋值

@PreUpdate

public void preUpdate(EditMapped editMapped) {

if (Objects.isNull(editMapped.getUpdateTime())) {

editMapped.setCreateTime(new Date());

}

if (StringUtils.isBlank(editMapped.getUpdateBy())) {

// 根据鉴权系统实现获取当前操作用户,此处只做模拟

editMapped.setUpdateBy("test_update");

}

}

// 修改之后,记录变更日志

@PostUpdate

public void postUpdate(EditMapped editMapped) throws JsonProcessingException {

recordLog(ACTION_UPDATE, editMapped);

}

// 删除之前,记录变更日志

@PreRemove

public void preRemove(EditMapped editMapped) throws JsonProcessingException {

recordLog(ACTION_DELETE, editMapped);

}

}

public class BasicListener implements ApplicationContextAware {

private ApplicationContext applicationContext;

protected static final String ACTION_INSERT = "insert";

protected static final String ACTION_UPDATE = "update";

protected static final String ACTION_DELETE = "delete";

// 记录变更日志

protected void recordLog(String action, IdMapped object) throws JsonProcessingException {

// http://日志对象不需要再记录变更日志

if (object instanceof ModifyLogEntity) {

return;

}

ModifyLogEntity modifyLogEntity = new ModifyLogEntity();

modifyLogEntity.setAction(action);

modifyLogEntity.setEntityKey(String.valueOf(object.getId()));

modifyLogEntity.setEntityName(object.getClass().getSimpleName());

// 对象转json字符串存储

modifyLogEntity.setEntityValue(new ObjectMapper().writeValueAsString(object));

Optional.ofNullable(applicationContext.getBean(ModifyLogDao.class))QHkFgVnzHy

.ifPresent(modifyLogDao -> modifyLogDao.save(modifyLogEntity));

}

@Override

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

this.applicationContext = applicationContext;

}

}

3、测试

3.1 Dao

@Repository

public interface UserDao extends JpaRepository {

}

@Repository

public interface ModifyLogDao extends JpaRepository {

}

3.2 Service

模拟用户的创建、修改和删除操作

@Service

public class UserServiceImpl implements UserService {

@Autowired

private UserDao userDao;

@Override

@Transactional

public void add(String userName, String password) {

UserEntity userEntity = new UserEntity();

userEntity.setUsername(userName);

userEntity.setPassword(password);

userDao.save(userEntity);

}

@Override

@Transactional

public void update(Long id, String password) {

UserEntity userEntity = userDao.findById(id).orElseThrow(() -> new RuntimeException("用户不存在"));

userEntity.setPassword(password);

userDao.save(userEntity);

}

@Override

@Transactional

public void delete(Long id) {

UserEntity userEntity = userDao.findById(id).orElseThrow(() -> new RuntimeException("用户不存在"));

userDao.delete(userEntity);

}

}

3.3 测试

3.3.1 创建用户

@SpringBootTest

public class SchoolApplicationTests {

@Autowired

private UserService userService;

@Test

public void testAdd() {

userService.add("test1", "123456");

}

}

测试结果

3.3.2 修改用户

@Test

public void testUpdate() {

userService.update(1L, "654321");

}

测试结果

3.3.3 删除用户

@Test

public void testRemove() {

userService.delete(1L);

}

测试结果

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:音视频开发linux(音视频开发工程师)
下一篇:泰州车载物联网卡销售价格(泰州车载物联网卡销售价格查询)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~