不加入子表的 JPA (@OneToMany) 查询
Posted
技术标签:
【中文标题】不加入子表的 JPA (@OneToMany) 查询【英文标题】:JPA (@OneToMany) query without joining child table 【发布时间】:2017-11-16 01:02:07 【问题描述】:我正在使用 JPA 和 Postgres db 编写服务。我有一个名为 Student 的班级:
public class Student
@id
private String id;
private String firstName;
private String lastName;
@OneToMany(targetEntity = Phone.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "student_id", referencedColumnName = "id")
private Set<Phone> phones;
// Setter and Getter
还有一个电话类:
public class Phone
@id
private String id;
private String number;
// Setter and Getter
现在我的数据库中将有两个表,以下是其中的列:
学生:id、first_name、last_name
电话:id、号码、student_id (由@JoinColumn 生成)
现在每次查询学生时,JPA 都会将电话表加入学生表,学生结果包含该学生的电话信息。这正是我想要的。
但现在我遇到了一个问题。当我查询学生列表时,电话信息在这种情况下没有用,只有 id、firstName 和 lastName 是必需的。但是 JPA 也为我做了同样的“加入”操作。我知道这会耗费大量时间。在这种情况下,我怎么能只返回学生表中的信息?不加入电话桌?
我在存储库中尝试了一些类似
@Query(SELECT s.id, s.firstName, s.lastName FROM student s)
public List<Student> findAllStudentWithoutPhone();
但它返回值列表,但未转换为 Student 对象。我怎样才能实现这个功能?
【问题讨论】:
【参考方案1】:@Sahil 给出的答案是绝对正确的,但要补充一点。
@聪 您不需要添加 FetchType.LAZY,因为默认情况下它已经 LAZY。 并注意电话缺少变量名称的 Student 类属性。
【讨论】:
谢谢@mAc,变量已添加。【参考方案2】:在一对多映射中(请参阅下文),您已将获取类型设置为惰性 fetch = FetchType.LAZY 因此休眠不会获取与学生对应的电话集,直到您通过 getter 方法访问该组电话,因此无需担心。
@OneToMany(targetEntity = Phone.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "student_id", referencedColumnName = "id")
private Set<Phone>;
但是,如果您需要验证一切是否正常,您可以将属性 show_sql 设置为 true 并检查通过 hibernate 生成的 sql。
【讨论】:
【参考方案3】:fetch = FetchType.LAZY
为您提供了在第一次调用代码之前不要查询Phone
表的可能性。请看:http://docs.oracle.com/javaee/7/api/javax/persistence/FetchType.html#LAZY
如果您想检索没有手机的学生列表,查询应该是:
@Query(SELECT * FROM student s where phones IS NULL)
要自动将结果转换为学生对象,请不要在查询中使用s.id, s.firstName, s.lastName
。
【讨论】:
以上是关于不加入子表的 JPA (@OneToMany) 查询的主要内容,如果未能解决你的问题,请参考以下文章