【问题标题】:Joining three tables into one using hibernate使用休眠将三个表合并为一个
【发布时间】:2020-04-24 13:51:41
【问题描述】:

假设我有 3 个由 Java 类表示的表:

ClassRoom {
int id;
int student_id;
int teacher_id;
String name;
}

Student{ 
int id;
String name;
}

Teacher{
int id
String name;
}

在我的代码中,我需要使用学生姓名和教师姓名,但目前我只有他们的 ID,使用休眠我希望最终获得如下实体:

ClassRoom {
int id 
String name;
String studentName;
String teacherName;
}

我应该创建一个这样的类吗?或者我可以通过它的一些方法使用休眠逻辑来做所有事情来获取这些对象的列表?我认为这个任务是一个常见的任务,但我是 hibernate 新手,我真的找不到一个好的搜索词来在网络上找到一些好的例子。

【问题讨论】:

    标签: java hibernate jpa join


    【解决方案1】:

    使用外键。

    ClassRoom {
     int id;
    
     @ManyToOne
     @JoinColumn(name = "student_id", foreignKey = @ForeignKey(name = "fk_student"))
     Student student_id;
    
     @OneToMany
     @JoinColumn(name = "teacher_id", foreignKey = @ForeignKey(name = "fk_teacher"))
     Teacher teacher_id;
    
     String name;
    }
    

    您可以将它用作类,例如 .getName() 或其他东西。 it's不错的教程

    【讨论】:

    • 有没有办法只通过一个查询来获取教师姓名和学生姓名?假设我正在调用 classRoomRepo.findAll(),我只会得到带有 ID 而不是名称的常规 ClassRoom 实体,对吧?我应该怎么做才能获取名称而不是 Id?
    • 第一个选项:.getTeacher().getName(),或者,你可以在通信器中做:使用ClassRoom cr=(ClassRoom) session.createQuery("SQL") 这里可以写一个sql JOIN 和 NAME 列
    【解决方案2】:

    因此,在浏览了几个教程以及应用 DrHelmholtz 建议后,我最终为我的教室设置了以下设置:

    @Getter
    @Setter
    @EqualsAndHashCode(of = {"className"})
    @ToString(of = {"id", "className", "student", "teacher"})
    @NoArgsConstructor
    @Entity(name = "Classroom")
    public class ClassRoom {
        @Id
        @SequenceGenerator(name = "hibernateSeq", sequenceName = "HIBERNATE_SEQUENCE", allocationSize = 1)
        @GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "hibernateSeq")
        private Long id;
        @Column(name = "class_name")
        private String className;
    
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "student_id", foreignKey = @ForeignKey(name="fk_student"))
        private Student student;
    
    
        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "teacher_id", foreignKey = @ForeignKey(name="fk_teacher"))
        private Teacher teacher;
    
        public ClassRoom(final String className) {
            this.className = className;
        }
    }
    

    我想指出几个很好的提示:

    1. 我已经放弃使用 Lombok @Data,因为它使用每个字段创建 hasCode,这在大多数情况下是多余的。
    2. 性能明智的 GenerationType.SEQUENCE 是最好的,因为它分批创建 id(默认 = 50),不确定我的是否那么好,因为我使用 postgres,由于某种原因不适用于默认值,我有将 allocationSize 设置为 1。
    3. 为了避免 N+1 问题,应该默认使用延迟获取

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-06
      • 2020-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-03
      相关资源
      最近更新 更多