欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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");
    }    
}

测试结果

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

3.3.2 修改用户

    @test
    public void testupdate() {
        userservice.update(1l, "654321");
    }

测试结果

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

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

3.3.3 删除用户

	@test
    public void testremove() {
        userservice.delete(1l);
    }

测试结果

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

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。