![](/img/trans.png)
[英]Why does Hibernate execute multiple SELECT queries instead of one when using @Fetch(FetchMode.JOIN)
[英]Why does Hibernate @OneToOne execute multiple select queries instead of one?
這是我的實體:
@Entity
public class ProductStateEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Integer id;
@OneToOne
@JoinColumn(name = "product_id", nullable = false)
private ProductEntity product;
// other fields
}
@Entity
public class ProductEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Integer id;
// other fields
}
如果我以這種方式提出要求:
session.get(ProductStateEntity.class, 10);
SQL是這樣形成的:
SELECT product_states.id, product_states.product_id, products.id, -- other columns
FROM product_states
INNER JOIN products ON product_states.product_id=products.id
WHERE product_states.id=10
到目前為止,使用INNER JOIN
效果很好。
如果您以這種方式發出請求:
session.createQuery("from ProductStateEntity where id = :id")
.setParameter("id", 10)
.list()
SQL是這樣形成的:
SELECT product_states.id, product_states.product_id, -- other columns
FROM product_states
WHERE product_states.id=10;
SELECT products.id, -- other columns
FROM products
WHERE products.id=10
在這種情況下,將發出2個請求。 首先在product_states中進行查詢,然后在product中進行查詢。
不僅如此,現在我們將發出這樣的請求,該請求一次接收4條ID為4的記錄:
session.createQuery("from ProductStateEntity where id in :ids")
.setParameter("ids", Arrays.asList(10, 11, 12, 13))
.list();
SQL是這樣形成的:
SELECT product_states.id, product_states.product_id, -- other columns
FROM product_states
WHERE product_states.id IN (10, 11, 12, 13);
SELECT products.id, -- other columns
FROM products
WHERE products.id=10;
SELECT products.id, -- other columns
FROM products
WHERE products.id=11;
SELECT products.id, -- other columns
FROM products
WHERE products.id=12;
SELECT products.id, -- other columns
FROM products
WHERE products.id=13;
在這種情況下,發出了5個請求。 首先,在product_states中發出一個請求,獲取所有產品的ID,然后根據1個請求進行處理,以接收4個產品中的每一個。
將join fetch
添加到上一個查詢:
session.createQuery("from ProductStateEntity p join fetch p.product where p.id in :ids")
.setParameter("ids", Arrays.asList(10, 11, 12, 13))
.list();
SQL是這樣形成的:
SELECT product_states.id, products.id, product_states.product_id, -- other columns
FROM product_states
INNER JOIN products ON product_states.product_id=products.id
WHERE product_states.id IN (10, 11, 12, 13)
因此,使用INNER JOIN
只會發出1個請求,這是我想要實現的。
因此,問題是:
createQuery
顯式指定createQuery
join fetch
? 可以做出這種默認行為嗎? 畢竟,使用join進行單個查詢要好得多。 join fetch
,其他選擇查詢未id in (...)
合並為id in (...)
為id in (...)
查詢? 相反,Hibernate一次只能選擇一個。 可以定制嗎? n+1
提取策略是Hibernate的默認策略-正因為如文檔所述
這些默認值對於大多數應用程序中的大多數關聯有意義
要全局更改此行為,可以設置hibernate.default_batch_fetch_size
,您將在Internet上找到一些有關如何設置適當值以及原因的主題。
還有另一件事-普遍認為fetch join
是解決每個問題的解決方案,但事實並非如此 。 我們必須記住笛卡爾積問題 。
提取策略取決於我們的應用程序如何工作,環境設置是什么(例如,數據庫連接中的延遲),我們使用什么數據模型以及許多其他事情。 沒有一種適合所有人的好的解決方案,這就是為什么我們在Hibernate中有許多獲取策略的原因
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.