Hibernate OneToMany List 或 Iterator 不同?

Hibernate OneToMany List or Iterator different?

@Entity
@Table(name = "STUDENT")
public class Student {

    private long studentId;
    private String studentName;
    private List<Phone> studentPhoneNumbers;

    ....

    @OneToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "STUDENT_PHONE", joinColumns = { @JoinColumn(name = "STUDENT_ID") }, inverseJoinColumns = { @JoinColumn(name = "PHONE_ID") })
    public List<Phone> getStudentPhoneNumbers() {
        return this.studentPhoneNumbers;
    }

    public void setStudentPhoneNumbers(List<Phone> studentPhoneNumbers) {
        this.studentPhoneNumbers = studentPhoneNumbers;
    }
}

1)

Student student = session.loadStudent(123); // pseudocode
List phoneList = student.getStudentPhoneNumbers();
for (Phone p : phoneList) {
    ...
}

2)

Student student = session.loadStudent(123); // pseudocode
List phoneList = student.getStudentPhoneNumbers();
Iterator itr = phoneList.iterator();   
while(itr.hasNext()) {
    ...
}

我从这里阅读了答案:difference between query.list and query.iterate

显然 list()iterator() 之间存在差异(在 Query 中)。如果我在 OneToMany 列表中使用它会怎样?像上面的例子,性能方面有区别吗?内存?

与Hibernate无关

当Java编译器遇到

for (Phone p : phoneList) {
    ....
}

它会自动生成相当于

的代码
for (Iterator<Phone> itr = phoneList.iterator(); itr.hasNext();) {
    Phone p = itr.next();
    ....
}

所以你展示的两个例子本质上是一样的。

我阅读了这个Hibernate chapter,其中详细解释了代理性能。

默认情况下实体的映射 FetchTypelazy,hibernate 将围绕该属性创建一个代理。

调用 list.size()(等)后,hibernate 将开始加载所有子对象。

如果我们不想全部加载,我们可以使用名为 extra lazy 的新功能。它只会对特定的记录发出select语句,例如list.get(3) select只在第四行。

如果我们用eager注释该属性,那么hibernate会在它加载父对象时加载所有的子对象(使用外部连接,这将有重复的问题)。在这种情况下,属性周围没有代理。它不会有性能差异,无论我们将它用作 listiterator.