关于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出错了,求帮忙解决,如下