假設我有以下物體類:
@Entity public class MyEntity {
@Id private String id;
@ManyToOne private MyOtherEntity myOtherEntity;
}
@Entity public class MyOtherEntity {
@Id private String id;
@Column private String name;
}
現在我想做一個查詢來獲取所有MyEntity鏈接到某個 s 的 s MyOtherEntity,我想知道以下 3 個謂詞之間的區別:
cb.equal(root.get(MyEntity_.myOtherEntity), myOtherEntity);
cb.equal(root.get(MyEntity_.myOtherEntity).get(MyOtherEntity_.id), myOtherEntity.getId());
cb.equal(root.get(MyEntity_.myOtherEntity).get(MyOtherEntity_.name), myOtherEntity.getName());
在每種情況下生成的 SQL 看起來如何?哪一種最有效?
uj5u.com熱心網友回復:
一開始,我建議在開發時不厭其煩地在 Hibernate 中啟用 SQL 日志記錄 - 請參閱此處。了解 Hibernate 為您的 JPA 查詢創建的確切陳述句是無價的,例如,您有機會發現 N 1 查詢問題、過度連接等。
話雖如此,在您的情況下,陳述句應如下所示:
cb.equal(root.get(MyEntity_.myOtherEntity), myOtherEntity)→SELECT ... FROM MyEntity WHERE MyEntity.myOtherEntity_id = ?。在這種情況下,Hibernate 通常知道優化和避免不必要的連接。cb.equal(root.get(MyEntity_.myOtherEntity).get(MyOtherEntity_.id), myOtherEntity.getId())→ 應該像上面那樣;再次 Hibernate 應該知道.get(MyOtherEntity_.id)已經在表中并避免不必要的連接。我已經看到 Hibernate 按照我為上述案例描述的方式作業。一定要啟用 SQL 日志來驗證,可能有您自己的用例的詳細資訊使其行為方式不同!
cb.equal(root.get(MyEntity_.myOtherEntity).get(MyOtherEntity_.name), myOtherEntity.getName())→ 肯定會創建一個連接,因為它myOtherEntity.name在MyEntity表中找不到:SELECT ... FROM MyEntity e JOIN MyOtherEntity oe ON ... WHERE oe.name = ?
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/383647.html
