Jpa 如何使用@EntityListeners 实现实体对象的自动赋值
程序员文章站
2022-06-25 10:00:31
1、简介1.1 @entitylisteners官方解释:可以使用生命周期注解指定实体中的方法,这些方法在指定的生命周期事件发生时执行相应的业务逻辑。简单来说,就是监听实体对象的增删改查操作,并对实体...
1、简介
1.1 @entitylisteners
官方解释:可以使用生命周期注解指定实体中的方法,这些方法在指定的生命周期事件发生时执行相应的业务逻辑。
简单来说,就是监听实体对象的增删改查操作,并对实体对象进行相应的处理。
1.2 生命周期对应注解
jpa一共提供了7种注解,分别是:
@postload
:实体对象查询之后
@prepersist
: 实体对象保存之前
@postpersist
:实体对象保存之后
@preupdate
:实体对象修改之前
@postupdate
:实体对象修改之后
@preremove
: 实体对象删除之前
@postremove
:实体对象删除之后
通常情况下,数据表中都会记录创建人、创建时间、修改人、修改时间等通用属性。如果每个实体对象都要对这些通用属性手动赋值,就会过于繁琐。
现在,使用这些生命周期注解,就可以实现对通用属性的自动赋值,或者记录相应操作日志。
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 { // 日志对象不需要再记录变更日志 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)) .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<userentity, long> { }
@repository public interface modifylogdao extends jparepository<modifylogentity, long> { }
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); }
测试结果
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。