关于Hibernate查询的一组问题

Posted

技术标签:

【中文标题】关于Hibernate查询的一组问题【英文标题】:A set of questions on Hibernate quering 【发布时间】:2012-02-17 16:06:45 【问题描述】:

请帮助我解决这些 Hibernate 查询问题。

考虑以下结构:

@Entity
class Manager 
    @OneToMany
    List<Project> projects;

0) 在 HQL 中有 2 种可能的动态获取方式:

select m from Manager m join m.projects 从经理 m 加入 fetch m.projects

在我的设置中,第二个总是返回列表中对象数量错误的笛卡尔积的结果,而第一个总是返回列表中正确数量的实体。但是 sql 查询看起来是一样的。这是否意味着“select”子句会从内存列表中删除冗余对象?在这种情况下,在书中看到使用 select distinct ... 删除冗余实体​​的建议很奇怪,而“select”可以完成这项工作。如果这是一个错误的假设,那么为什么这两个查询会返回不同的结果?

    如果我通过上述 2 种方法之一使用动态提取,我会在我的休眠 SQL 日志中看到经典的 n+1 选择问题输出。实际上,FetchMode 注释(子选择或连接)在动态获取时没有能力。在这种特殊情况下,我真的无法解决 n+1 问题吗?

    看起来 Hibernate Criteria API 不支持泛型。我对吗?看来我必须改用 JPA Criteria API?

    是否可以编写带有实体名称参数的 HQL 查询?例如 "from :myEntityParam p where p.id=1" 并在此之后调用 setParameter("myEntityParam", MyClass.class)。实际上我想要的是通用 HQL 查询,用一个通用的替换多个非通用 dao。

【问题讨论】:

【参考方案1】:

0) 我总是使用 select 子句,因为它允许告诉您要选择什么,并且无论如何在 JPQL 中都是强制性的。如果您想选择经理及其项目,请使用

select distinct m from Manager m left join fetch m.projects

如果不使用 distinct 关键字,列表将包含每个经理的 n 个实例(n 是经理的项目数):Hibernate 返回与结果集中的行数一样多的元素。

1) 如果要避免 n+1 问题,请在同一查询中获取其他关联:

select distinct m from Manager m 
left join fetch m.projects 
left join fetch m.boss

您还可以配置批量获取以在访问第一个 Boss 时一次加载 10 个 Boss(例如)。在参考文档中搜索“batch fetching”。

2) 整个 Hibernate API 没有被通用化。它是在泛型之前的 JDK 1.4 上制作的。这并不意味着它没有用。

3) 否。HQL 查询参数最终是准备好的语句参数。您必须使用字符串连接来执行此操作。

【讨论】:

以上是关于关于Hibernate查询的一组问题的主要内容,如果未能解决你的问题,请参考以下文章

在 Hibernate 3.2.2 的本机 sql 查询中使用 IN 子句

求教第一个hibernae程序的配置文件hibernate.cfg.xml出错了,求帮忙解决,如下

关于hibernate 是否选择关联查询(full,out,inner)时判断的一点体会

hibernate缓存技术

Hibernae

Hibernaate 详解