gom*_*n1d 5 java orm hibernate hql
这是我的实体:
@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
}
Run Code Online (Sandbox Code Playgroud)
如果我这样提出请求:
session.get(ProductStateEntity.class, 10);
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
到目前为止,一切顺利,使用INNER JOIN.
如果您以这种方式提出请求:
session.createQuery("from ProductStateEntity where id = :id")
.setParameter("id", 10)
.list()
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
在本例中,提出了 2 个请求。首先在product_states 中进行查询,然后在products 中进行查询。
这还不是全部,现在我们将发出这样一个请求,它一次接收 4 个 id 的 4 条记录:
session.createQuery("from ProductStateEntity where id in :ids")
.setParameter("ids", Arrays.asList(10, 11, 12, 13))
.list();
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
在本例中,提出了 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();
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
因此,只发出 1 个请求INNER JOIN,这就是我想要实现的目标。
所以问题是:
join fetch在 中明确指定createQuery?可以做出这种默认行为吗?毕竟,带有连接的单个查询比大量查询要好。join fetch,附加的选择查询不会与 组合成一个id in (...)?相反,Hibernate 一次选择一个。这个可以定制吗?n+1获取策略是 Hibernate 的默认策略 - 只是因为,如文档中所述
这些默认值对于大多数应用程序中的大多数关联都有意义
要在全局范围内更改此行为,您可以进行设置hibernate.default_batch_fetch_size,并且您会在互联网上找到一些有关如何设置正确值以及原因的主题
还有一件事 - 人们普遍认为fetch join每个问题都有解决方案,但事实并非如此。我们必须记住笛卡尔积问题。
获取策略取决于我们的应用程序如何工作、环境设置是什么(例如数据库连接中的延迟)、我们使用什么数据模型以及许多其他因素。没有一种好的解决方案适合每个人,这就是为什么我们在 Hibernate 中有许多获取策略
| 归档时间: |
|
| 查看次数: |
1093 次 |
| 最近记录: |