Mysql 侦听数据库表更新/更改
我是冬眠新手。我正在用Java和Hibernate开发一个后端服务 我有一个Mysql 侦听数据库表更新/更改,mysql,sql,database,hibernate,jakarta-ee,Mysql,Sql,Database,Hibernate,Jakarta Ee,我是冬眠新手。我正在用Java和Hibernate开发一个后端服务 我有一个学生实体,它与组实体有多对多关系。在数据库中,我有一个学生表和一个组表: @Entity @Table(name = "student") public class Student { private int student_id; //primary key @ManyToMany(mappedBy = "students") private Set<Group> groups = ne
学生
实体,它与组
实体有多对多关系。在数据库中,我有一个学生
表和一个组
表:
@Entity
@Table(name = "student")
public class Student {
private int student_id; //primary key
@ManyToMany(mappedBy = "students")
private Set<Group> groups = new HashSet<Group>();
@ManyToMany(cascade = {CascadeType.ALL})
@JoinTable(name="student_group",
joinColumns={@JoinColumn(name="student_id")},
inverseJoinColumns={@JoinColumn(name="group_id")})
public Set<Group> getGroups() {
return groups;
}
public void setGroups(Set<Group> groups) {
this.groups = groups;
}
//Setter & Getter for student_id
...
@实体
@表(name=“student”)
公立班学生{
private int student_id;//主键
@许多(mappedBy=“学生”)
私有集组=新HashSet();
@ManyToMany(cascade={CascadeType.ALL})
@JoinTable(name=“学生组”,
joinColumns={@JoinColumn(name=“student_id”)},
inverseJoinColumns={@JoinColumn(name=“group_id”)})
公共集getGroups(){
返回组;
}
公共void集合组(集合组){
这个组=组;
}
//学生id设置器和获取器
...
}
正如您在上面的hibernate注释中所看到的,数据库中有一个联接表student\u group
。我想实现的是,当客户端的请求到达我的后端服务(带有学生id)时,我想知道数据库中的学生组
联接表是否已为该学生更新,例如是否插入新行(新组)(分配给该学生)或者现有行是否已更新值。如果有此类更新/变更,我将通知客户
使用hibernate,如何实现这种侦听器来侦听数据库表中的更改/更新?您可以通过编写插入和更新触发器来实现这一点 可以在表级别创建触发器。它们与您使用的ORM框架无关。插入触发器可以配置为在插入之前触发。更新触发器可以配置为在更新之前或之后执行。以下链接提供了有关触发器的简要说明:
如果数据库操作是通过Hibernate进行的,那么您应该能够通过使用
Hibernate事件侦听器来解决问题
例如:
public class CreateListner extends DefaultSaveOrUpdateEventListener {
@Override
public void onSaveOrUpdate(SaveOrUpdateEvent event) {
//Do your capturing operation here
super.onSaveOrUpdate(event);
}
}
或者,您也可以查找Hibernate拦截器
拦截器接口提供从会话到
应用程序,允许应用程序检查和/或操作
保存、更新和删除持久对象之前的属性
或者是上膛了。一个可能的用途是跟踪审计信息
就个人而言,我不建议在这里使用侦听器。您的问题归结为向学生组
表中添加时间戳。已经有了这方面的代码。结果表明,您的联接表需要是一个@embedded
或两个独立的@OneToMany
关系
例如,您可以有:
@Entity
public class Student {
@Id @GeneratedValue
private Long id;
@OneToMany(mappedBy = "student", cascade = CascadeType.ALL)
private List<StudentGroup> groupRels;
}
public class StudentGroup {
@Id @GeneratedValue
private Long id;
@Version
private DateTime lastChanged;
@ManyToOne
private Student student;
@ManyToOne
private Group group;
}
@实体
公立班学生{
@Id@GeneratedValue
私人长id;
@OneToMany(mappedBy=“student”,cascade=CascadeType.ALL)
私有列表组;
}
公共班级学生小组{
@Id@GeneratedValue
私人长id;
@版本
上次更改的私有日期时间;
@许多酮
私立学生;
@许多酮
私人集团;
}
Hibernate将在每次更新实体时使用当前时间更新lastChanged
如果你有,你可以简单地查询StudentGroup
s,它的时间戳大于你的客户的最后一次访问(不管你如何记录),并且包含某个学生。如果有这样的事情,请返回完整的学生
记录,否则不返回任何内容
我不确定,但IIRC Hibernate会更新@Version
属性,即使映射属性的元素发生更改,因此您可以将@Version
添加到学生中,并保留@manytomy
。但我不是100%肯定这一点-在任何情况下,单独的映射都是安全的选择
侦听器方法的工作原理与Satheesh Cheveri的答案类似,只需将记录写入持久介质,并复制它们。您还将遇到过时条目的问题:如果您记录了一个新角色,删除和/或更新它,然后您的客户机又回来了怎么办?您是否向他们展示了您的更改日志?或者仅仅是最终结果?您能否提供更多信息,这对我来说太抽象了,你的插入/更新是由hibernate完成的吗?要清楚地说明这一点:你希望hibernate之外的其他服务写入数据库,还是在hibernate将实体写入数据库时,你在寻找执行代码的方法?@mabi,我指的是后一种情况。我想在hibernate将实体写入数据库时执行代码。我已经更新了我的帖子以获得更详细的场景描述。我的意思是,在每个客户的请求中,我都需要检查该客户数据的数据库表是否有任何更改/更新。如果有,我需要将他/她的数据的最新最终结果作为回复发送回去。若并没有任何更改,我只是不向客户端发送任何内容。这是我想要实现的目标。