CriteriaBuilder 和/或条件未应用必需/正确的括号
Posted
技术标签:
【中文标题】CriteriaBuilder 和/或条件未应用必需/正确的括号【英文标题】:CriteriaBuilder and or condition is not applying required/proper parenthesis 【发布时间】:2019-12-30 13:28:04 【问题描述】:我是这个板的新手。我试图找到解决方案,但找不到解决方案。如果有的话,请分享给我。
CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
CriteriaQuery<DmdInventory> criteriaQuery = criteriaBuilder.createQuery(ItemInventory.class);
Root<ItemInventory> itemRoot = criteriaQuery.from(ItemInventory.class);
Predicate first = criteriaBuilder.equal(itemRoot.get("margin"), 1.0);
first = criteriaBuilder.and(first, criteriaBuilder.equal(itemRoot.get("costWithoutExpense"), 1.0));
first = criteriaBuilder.and(first, criteriaBuilder.equal(itemRoot.get("markup"), 1.0));
Predicate second = criteriaBuilder.and(criteriaBuilder.equal(itemRoot.get("lastImportCost"), 2.0));
second = criteriaBuilder.and(second, criteriaBuilder.equal(itemRoot.get("expenses"), 2.0));
second = criteriaBuilder.and(second, criteriaBuilder.equal(itemRoot.get("profit"), 2.0));
Predicate third = criteriaBuilder.and(criteriaBuilder.equal(itemRoot.get("totalCost"), 2.0));
third = criteriaBuilder.and(third, criteriaBuilder.equal(itemRoot.get("cost"), 2.0));
third = criteriaBuilder.and(third, criteriaBuilder.equal(itemRoot.get("quantity"), 2.0));
Predicate allPredicate[] = first, second, third ;
Predicate finalPredicate = criteriaBuilder.or(allPredicate);
criteriaQuery.where(finalPredicate);
List<ItemInventory> items = this.entityManager.createQuery(criteriaQuery).getResultList();
当前结果
select * from
item_nventory inven
where
inven.last_import_cost=2.0
and inven.expenses=2.0
and inven.profit=2.0
or inven.total_cost=2.0
and inven.cost=2.0
and inven.quantity=2
or inven.margin=1.0
and inven.cost_without_expense=1.0
and inven.markup=1.0
预期结果
select * from
item_nventory inven
where
inven.last_import_cost=2.0
and inven.expenses=2.0
and inven.profit=2.0
or (inven.total_cost=2.0
and inven.cost=2.0
and inven.quantity=2 )
or (inven.margin=1.0
and inven.cost_without_expense=1.0
and inven.markup=1.0)
我的最终要求如下所示
select * from
item_nventory inven
where
inven.last_import_cost=2.0
and inven.expenses=2.0
and inven.profit=2.0
or ((inven.total_cost=2.0
and inven.cost=2.0
and inven.quantity=2 ) or (inven.quantity_on_hand>0))
or (inven.margin=1.0
and inven.cost_without_expense=1.0
and inven.markup=1.0)
请帮帮我。
【问题讨论】:
能否提供您的错误的完整堆栈跟踪。 我没有收到任何错误。我由我的方法的代码提供,除了最后一行是返回语句。运行代码时生成的 SQL。同时我也提供了我想要的输出。 您的Expected result
中似乎有错字:在... and inven.profit=2.0 ( or (inven.total_cost=2.0 ...
下,您的意思是... and inven.profit=2.0 or (inven.total_cost=2.0 ...
?在final requirement
中也是如此?
@SternK 感谢您让我知道我的错字。我更正了 SQL。我希望现在要求清楚。
【参考方案1】:
我认为,问题在于谓词的逐步构建。试试下面的构造。
Predicate firstA = criteriaBuilder.equal(itemRoot.get("margin"), 1.0);
Predicate firstB = criteriaBuilder.equal(itemRoot.get("costWithoutExpense"), 1.0);
Predicate firstC = criteriaBuilder.equal(itemRoot.get("markup"), 1.0);
Predicate first = criteriaBuilder.and(firstA, firstB, firstC);
. . .
Predicate finalPredicate = criteriaBuilder.or(first, second, third);
或带有列表的替代解决方案 - 易于添加或删除另一个谓词(动态事件)
List<Predicate> allPredList = new LinkedList<>();
List<Predicate> firstPredList = new LinkedList<>();
firstPredList.add(criteriaBuilder.equal(itemRoot.get("margin"), 1.0));
firstPredList.add(criteriaBuilder.equal(itemRoot.get("costWithoutExpense"), 1.0));
firstPredList.add(criteriaBuilder.equal(itemRoot.get("markup"), 1.0));
allPredList.add(criteriaBuilder.and(firstPredList.toArray(new Predicate[0])));
. . .
Predicate finalPredicate = criteriaBuilder.or(allPredList.toArray(new Predicate[0]));
【讨论】:
以上是关于CriteriaBuilder 和/或条件未应用必需/正确的括号的主要内容,如果未能解决你的问题,请参考以下文章
如何使 CriteriaBuilder 加入自定义“开启”条件?
Hibernate CriteriaBuilder 加入多个表
JPA / Hibernate:CriteriaBuilder - 如何使用关系对象创建查询?
使用 CriteriaBuilder 的 JPA 计数(*)。如何使用 CriteriaBuilder 检索 count(*) 列