当前位置: 首页 > 面试题库 >

使用hql表达式而不是Criteria进行动态HQL查询?

巢烨
2023-03-14
问题内容

由于各种原因,我试图编写部分动态的HQL查询而不使用Criteria
API。我想知道是否有一种简单的方法可以使用HQL表达式来短路where限制。例如,这是正常工作的原始查询:

SELECT customer 
FROM Customer as customer 
INNER JOIN customer.profile as profile 
WHERE profile.status IN :statusCodes
AND   profile.orgId IN :orgIds

StatusCodes是字符串列表,而orgIds是整数列表。但是,任一个都是可选的,并且不应限制是否传递null而不是传递集合。我试图做到这一点是这样的:

SELECT customer 
FROM Customer as customer 
INNER JOIN customer.profile as profile 
WHERE (:statusCodes IS NULL OR profile.status IN :statusCodes)
AND   (:orgIds IS NULL OR profile.orgId IN :orgIds)

不幸的是,这行不通,但是还有其他方法可以行得通吗,要么使用不同的表达式,要么传入默认值?

编辑:为了清楚起见,我正在寻找一种使用NamedQuery的方法,而不是以任何方式动态构建查询。

解决方案:我使用了额外的查询参数来完成它。我创建了两个辅助方法:

private void setRequiredParameter(TypedQuery<?> query, String name, Object value) {
    query.setParameter(name, value);
}

private void setOptionalParameter(TypedQuery<?> query, String name, Object value) {
    query.setParameter(name, value);
    query.setParameter(name + "Optional", value == null ? 1 : 0);
}

像这样的查询:

SELECT customer 
        FROM Customer as customer 
        INNER JOIN  customer.profile as profile 
        WHERE (:statusCodesOptional = 1 OR profile.status IN :statusCodes)
        AND (:orgIdsOptional = 1 OR profile.orgId  IN :orgIds)

问题答案:

如果绝对必须避免动态查询,则可以以另外两个参数为代价:

SELECT customer 
  FROM Customer AS customer 
  JOIN customer.profile AS profile 
 WHERE (profile.status IN :statusCodes OR :statusCodeCount = 0)
   AND (profile.orgId IN :orgIds OR :orgIdCount = 0)

然后,在Java代码中,您将执行以下操作:

session.getNamedQuery("your.query.name")
       .setParameterList("statusCodes", statusCodes)
       .setParameter("statusCodeCount", statusCodes.length)
       .setParameterList("orgIds", orgIds)
       .setParameter("orgIdCount", orgIds.length);

您需要确保数组的长度为零,而不是null检查处理null方案时提供其他长度。

综上所述,HQL实际上更适合定义明确(例如静态)的查询。您可以解决动态参数,而不能解决动态排序。



 类似资料:
  • 问题内容: 我对HQL查询和hibernate有疑问。 我有一个用户类和一个角色类。用户可以具有许多角色。所以我有一个像这样的ManyToMany关系: 在用户类别中: 在角色类中: 此映射创建了存储关系的第三个表(PORTAIL_USERROLE)。像这样一切正常。当我有一个用户时,我将检索角色。 但是,我的问题是:在HQL查询中,如何获得具有特定角色的所有用户?任何类都代表PORTAIL_US

  • persistence.xml文件 http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd“>org.hibernate.ejb.hibernatePersistence

  • 问题内容: 设置以下映射 通知ID是一个整数。现在我需要使用like运算符进行此HQL查询 ATT:它 就像 运算符NOT = (等于运算符) 然后我用 但是不起作用,因为Hibernate抱怨在调用User.id的getter时发生了IllegalArgumentException 即使我使用 这没用 我应该使用什么来传递查询? 问题答案: 根据Hibernate参考: str()用于将数字或时

  • 问题内容: 我想编写一个方法,该方法返回按字段“ serviceId”分组的最后添加的对象的列表。 以下HQL可以使用,但我想使用Criteria API编写: 像这样: 提前致谢。 编辑: 现在,我需要使用eclipselink API = /的类似查询, 基本上,我需要最后N行(最大日期),该状态是下面所述的五行之一,按serviceId列分组。 由于我的经验不足,这是我所能做到的最好的: 缺

  • 我正在使用hibernate为一个项目连接到我的数据库。 我想有一个查询,从我的数据库中获得产品与特定语言的描述和名称。我拥有的参数是该语言的简称,因此首先我必须获得该语言的id,然后获得所需语言的文本。 我尝试了下面的hql查询,没有成功。

  • 问题内容: 在这里看到讨论之后:Python-产生时差,我很好奇。我最初还以为生成器比列表快,但是当涉及sorted()时我不知道。将生成器表达式发送到sorted()而不是列表有什么好处吗?生成器表达式最终是否仍要在sorted()内放入列表中? 编辑:我只能接受一个答案让我感到悲伤,因为我感到很多答复都有助于澄清这个问题。再次感谢大家。 问题答案: 首先要做的是将数据转换为列表。基本上,实现的