Mysql 侦听数据库表更新/更改

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

我是冬眠新手。我正在用Java和Hibernate开发一个后端服务

我有一个
学生
实体,它与
实体有多对多关系。在数据库中,我有一个
学生
表和一个
表:

@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将实体写入数据库时执行代码。我已经更新了我的帖子以获得更详细的场景描述。我的意思是,在每个客户的请求中,我都需要检查该客户数据的数据库表是否有任何更改/更新。如果有,我需要将他/她的数据的最新最终结果作为回复发送回去。若并没有任何更改,我只是不向客户端发送任何内容。这是我想要实现的目标。