hibernate - AND/OR 使用 Hibernate 中的条件谓词对 WHERE 条件进行分组
问题描述
我在对 WHERE 条件进行分组时遇到问题。最终,我的目标是拥有一组 AND 条件,每个条件都是 OR。例如:
SELECT *
WHERE ( foo = 1 AND bar = 2)
OR (foo = 3 AND bar = 4)
OR (foo = 5 AND bar = 6)
下面是我用来完成此操作的代码。如您所见,我正在创建 2 个“相等”谓词,然后创建一个嵌套它们的谓词。
List<Waybill> getWaybillsByCriteriaOrderItemList(List< OrderItem > orderItems ) {
CriteriaBuilder cb = em.getCriteriaBuilder()
CriteriaQuery<Waybill> q = cb.createQuery( Waybill )
Root<Waybill> waybillRoot = q.from(Waybill)
q.select( waybillRoot )
List<Predicate> predicates = []
orderItems.each { OrderItem item ->
Predicate carInit = cb.equal( cb.trim(waybillRoot.get('carInit')), item.carInit)
Predicate carNumb = cb.equal( cb.trim(waybillRoot.get('carNumb')), item.carNum )
Predicate thisCar = cb.or (
cb.and( carInit ),
cb.and( carNumb )
)
predicates << thisCar
}
q.where(predicates.toArray(new Predicate[predicates.size()]))
TypedQuery<Waybill> tq = em.createQuery(q)
List<Waybill> result = tq.getResultList()
result
}
不幸的是,AND/OR 分组与我的预期完全相反。这是生成的 HQL
select generatedAlias0 from Waybill as generatedAlias0 where
( ( trim(BOTH from generatedAlias0.carInit)=:param0 ) or ( trim(BOTH from generatedAlias0.carNumb)=:param1 ) )
and
( ( trim(BOTH from generatedAlias0.carInit)=:param2 ) or ( trim(BOTH from generatedAlias0.carNumb)=:param3 ) )
and
( ( trim(BOTH from generatedAlias0.carInit)=:param4 ) or ( trim(BOTH from generatedAlias0.carNumb)=:param5 ) )
简单地颠倒那些 and() 和 or() 方法也没有解决我的问题。它导致一切都像这样:
Predicate thisCar = cb.and (
cb.or( carInit ),
cb.or( carNumb )
)
~~~~
select generatedAlias0 from Waybill as generatedAlias0 where
( ( trim(BOTH from generatedAlias0.carInit)=:param0 ) and ( trim(BOTH from generatedAlias0.carNumb)=:param1 ) )
and
( ( trim(BOTH from generatedAlias0.carInit)=:param2 ) and ( trim(BOTH from generatedAlias0.carNumb)=:param3 ) )
and
( ( trim(BOTH from generatedAlias0.carInit)=:param4 ) and ( trim(BOTH from generatedAlias0.carNumb)=:param5 ) )
我已经尝试了所有我能想到的组合。谁能指出我做错了什么?
解决方案
尝试改变:
Predicate thisCar = cb.or (
cb.and( carInit ),
cb.and( carNumb )
);
到:
Predicate thisCar = cb.and( carInit , carNumb );
在循环之后,将or
语句添加到谓词数组中:
q.where(cb.or(predicates.toArray(new Predicate[] {})));
推荐阅读
- vba - 在不会更改的临时变量中捕获表值
- sql - 如何优化 SQL Server 中的选择查询?
- java - Gson: 预期 begin_array 但 STRING 如何控制它
- c# - C# - 网络设备列表
- sql - 如何在 redshift 中创建一个表,其中包含与 2 个或 3 个其他表的内连接相关的数据?
- javascript - 将表格中的表单元素作为ajax请求提交?
- sql - 如何在 BigQuery SQL 语法中正确地“作为”应用了“LOWER”函数的列,以便在包装“SELECT”中引用它?
- postgresql - 按字母顺序排序数组元素 PostgreSQL
- mongodb - 如何仅更新 MongoDB 文档中的一个字段
- javascript - 将文字值转换为可观察值的便捷方法