java - 使用 hql 表达式而不是条件的动态 HQL 查询?

标签 java hibernate hql

出于各种原因,我正在尝试编写一个部分动态的 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)

最佳答案

我的建议是将所有参数放在一个映射中并动态构建查询,在构建之后执行之前设置查询所需的所有参数从映射中获取值:

Map<String, Object> pars = new HashMap<String,Object>();
pars.put("statusCodes", statusCodes);
pars.put("orgIds", orgIds);

StringBuilder b = "SELECT customer FROM Customer as customer INNER JOIN customer.profile as profile where 1 = 1";
if (statusCodes != null) {
  b.append(" and profile.status in :statusCodes");
}
if (orgIds != null) {
  b.append(" and profile.orgId in :statusCodes");
}

...

Query q = session.createQuery(b.toString());

...

for (String p : q.getNamedParameters()) {
  q.setParameter(p, pars.get(p));
}

当然需要进行一些改进,例如在未设置参数时抛出异常,如果复杂性大于几个简单参数则使用类型化参数等。

关于java - 使用 hql 表达式而不是条件的动态 HQL 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10640736/

相关文章:

java - 哈希表数组搜索中的空指针异常

java - 为什么 (int)(14/13 - 0.001) 产生 0 而不是 1?

java - 制作三个轻度相关类的数组

java - 在@Transactional注释中设置默认事务管理器?

mysql - MySQL 中具有并集的相同 CASE 条件的多个 THEN

java - 三维数组以错误的顺序到达串行端口

java - hibernate - 从集合中删除项目

java - 如何使用 JPA - EntityGraph 只加载实体@Basic 属性的一个子集?

java - HQL diff 2 以天为单位的日期

java - hibernate 从子表中选择查询