4

我试图学习和理解 JPA 标准。到目前为止,我在 SQL 方面非常有能力,并且在 Hibernate Criteria 和 HQL 方面相当有能力。

我正在尝试使用 OR 语句进行相当简单的选择。

在纯 SQL 中,我的选择如下所示:

SELECT * FROM CHANGED_LOG
WHERE key1 = 52540 AND objectCode = 'Order'
OR key1 = 48398 AND objectCode = 'Package'

这给了我 key1 = 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();

哇。一个简单的查询有很多行......但是,这仍然会从数据库中返回给我每一行。

我在这里做错了什么?

感谢您所有有用的答案:)

4

1 回答 1

6

在这种情况下,首先要做的是配置 JPA 提供程序以记录生成的查询。有关示例,请参阅此 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));
于 2013-01-18T11:23:13.027 回答