Hibernate中如何获取跨表关联实体列表?附医院科室关联场景
解决方案:医院与科室关联对象的获取方法实现
我来帮你搞定这两个方法的实现,结合你给出的数据库结构和现有POJO代码,下面是具体的方案:
先理清楚背景
数据库表结构
Hospital表:字段包括id,name,email,phoneDepartment表:字段包括id,name,email,phoneRelation中间表:通过主键relationId,以及Hospital_Id、Department_id关联医院和科室,实现一个医院对应多个科室的一对多关系
现有POJO结构
public class Hospital { ... @OneToMany @JoinColumn(name="Hospital_ID") private Set<Relation> relations; ... } public class Department{ ... @OneToMany @JoinColumn(name="Department_ID") private Set<Relation> relations; ... } public class Relation{ ... @Id @Column(name = "relationId") private int relationId; @Column(name = "Hospital_ID") private int hospitalId; @Column(name = "Department_ID") private int departmentId; ... }
需求1:在Hospital类中实现getDepartments()方法
要返回当前医院对应的所有科室集合,有两种常见实现方式,推荐第二种更简洁的JPA关联映射方式:
方式1:通过DAO/Repository手动查询
如果不想修改现有POJO的映射关系,可以注入DepartmentRepository来根据科室ID查询对象:
public class Hospital { ... @OneToMany @JoinColumn(name="Hospital_ID") private Set<Relation> relations; // 实际项目中可以通过Spring依赖注入、构造器传入或者其他方式获取Repository private DepartmentRepository departmentRepository; // 构造器注入示例 public Hospital(DepartmentRepository departmentRepository) { this.departmentRepository = departmentRepository; } public Set<Department> getDepartments() { Set<Department> departments = new HashSet<>(); // 先判断relations是否为空,避免空指针 if (relations != null && !relations.isEmpty()) { for (Relation relation : relations) { Department department = departmentRepository.findById(relation.getDepartmentId()); if (department != null) { departments.add(department); } } } return departments; } ... }
方式2:修改Relation类的JPA关联(推荐)
直接在Relation类中关联Department和Hospital对象,这样可以利用JPA的关联映射直接获取对象,代码更简洁:
public class Relation{ ... @Id @Column(name = "relationId") private int relationId; // 关联Hospital对象,insertable/updatable设为false,避免和hospitalId字段冲突 @ManyToOne @JoinColumn(name = "Hospital_ID", insertable = false, updatable = false) private Hospital hospital; // 关联Department对象,同理避免和departmentId字段冲突 @ManyToOne @JoinColumn(name = "Department_ID", insertable = false, updatable = false) private Department department; // getter和setter方法 public Department getDepartment() { return department; } ... }
修改后,Hospital类的getDepartments()可以简化成:
public Set<Department> getDepartments() { Set<Department> departments = new HashSet<>(); if (relations != null && !relations.isEmpty()) { for (Relation relation : relations) { departments.add(relation.getDepartment()); } } return departments; }
需求2:在Department类中实现获取对应Hospital对象的方法
同样有两种实现方式,推荐使用关联映射的方式:
方式1:通过DAO/Repository查询
注入HospitalRepository,通过中间表的hospitalId查询对应的医院:
public class Department{ ... @OneToMany @JoinColumn(name="Department_ID") private Set<Relation> relations; private HospitalRepository hospitalRepository; public Department(HospitalRepository hospitalRepository) { this.hospitalRepository = hospitalRepository; } public Hospital getHospital() { if (relations != null && !relations.isEmpty()) { // 一个科室只属于一个医院,取第一个关联记录即可 Relation firstRelation = relations.iterator().next(); return hospitalRepository.findById(firstRelation.getHospitalId()); } return null; } ... }
方式2:利用修改后的Relation关联(推荐)
如果已经在Relation中关联了Hospital对象,方法会非常简洁:
public Hospital getHospital() { if (relations != null && !relations.isEmpty()) { return relations.iterator().next().getHospital(); } return null; }
一些注意事项
- 使用JPA关联映射时,
insertable = false, updatable = false一定要加上,因为我们已经在Relation类中维护了hospitalId和departmentId字段,避免JPA重复处理外键导致冲突 - 实际项目中优先选择关联映射的方式,能利用JPA的懒加载、一级/二级缓存等特性,减少手动查询的冗余代码
- 一定要处理
relations为null或者空集合的情况,避免触发空指针异常
内容的提问来源于stack exchange,提问作者theprogrammer
相关产品推荐
相关产品推荐

