我正在努力学习和理解JPA标准。 到目前为止,我在SQL方面非常有能力,并且在Hibernate Criteria和HQL方面非常有能力。
我正在尝试使用OR语句进行相当简单的选择。
在普通SQL中,我的选择如下所示:
SELECT * FROM CHANGED_LOG
WHERE key1 = 52540 AND objectCode = 'Order'
OR key1 = 48398 AND objectCode = 'Package'
这给了我keyone = 52540和objectCode等于Order的每一行 以及key = 48398和objectCode等于Package的每一行。 这正是我想要的。
因此尝试使用JPA标准(这看起来格外复杂......),到目前为止,我最好的猜测是:
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<ChangedLogBean> query = builder.createQuery(ChangedLogBean.class);
Root<ChangedLogBean> from = query.from(ChangedLogBean.class);
CriteriaQuery<ChangedLogBean> select = query.select(from);
Predicate orderChangedLogBeans = builder.conjunction();
builder.and(orderChangedLogBeans, builder.equal(from.get("key1"), orderId));
builder.and(orderChangedLogBeans, builder.equal(from.get("objectCode"), ChangedLogBean.ObjectType.OrderBean));
Predicate packageChangedLogBeans = builder.conjunction();
builder.and(packageChangedLogBeans, builder.equal(from.get("key1"), packageId));
builder.and(packageChangedLogBeans, builder.equal(from.get("objectCode"), ChangedLogBean.ObjectType.PackageBean));
Predicate orderOrPackage = builder.disjunction();
orderOrPackage.getExpressions().add(orderChangedLogBeans);
orderOrPackage.getExpressions().add(packageChangedLogBeans);
query.where(orderOrPackage);
return entityManager.createQuery(select).getResultList();
哇。一个简单查询的很多行...但是,这仍然从数据库向我回到了每一行。
我在这里做错了什么?
感谢您提供的所有有用答案:)
答案 0 :(得分:6)
在这种情况下要做的第一件事是配置JPA提供程序以记录生成的查询。有关示例,请参阅this q/a。
要回答你的问题,我不确定getExpressions()
的用法,所以我建议采用以下粗鲁的方法:
Predicate p1 = builder.equal(...);
Predicate p2 = builder.equal(...);
Predicate p3 = builder.equal(...);
Predicate p4 = builder.equal(...);
Predicate p5 = builder.and(p1, p2);
Predicate p6 = builder.and(p3, p4);
query.where(builder.or(p5, p6));
你的错误是这样的一行:
builder.and(orderChangedLogBeans, builder.equal(from.get("key1"), orderId));
不会就地orderChangedLogBeans
进行修改。你必须得到CriteriaBuilder#and()返回的谓词:
orderChangedLogBeans = builder.and(orderChangedLogBeans, builder.equal(from.get("key1"), orderId));