【问题标题】:JPA Criteria DisjunctionJPA 标准析取
【发布时间】:2013-01-02 01:48:51
【问题描述】:

我正在努力学习和理解 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();

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

我在这里做错了什么?

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

【问题讨论】:

    标签: hibernate jpa criteria criteria-api


    【解决方案1】:

    在这种情况下,首先要做的是配置 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));
    

    【讨论】:

    • 谢谢。简洁美观。像魅力一样工作。
    猜你喜欢
    • 2017-04-18
    • 2018-07-13
    • 2011-10-17
    • 2018-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-11
    • 1970-01-01
    相关资源
    最近更新 更多