或限制,包括子标准

时间:2013-07-12 07:50:44

标签: hibernate criteria hibernate-criteria

我正在尝试在项目中执行相当复杂的Criteria查询。

此特定示例包含2个数据库表:ORDER和PAYMENT。 ORDER表有一个字段(即一个名为“Money”的嵌入式Hibernate实体,包含属性“amount”和货币的枚举值),包含订单的总价。

PAYMENT表还有一个金额列,其中包含客户已支付的金额。 每个订单都包含订单总价和付款。订单无需付款,因此付款属性可以为空。 hibernate映射本身可以工作。

在我的DAO中,我有一个已经包含一些限制的Order对象的Criteria。我现在需要做的是查询总订单价格在2个值之间的所有订单。这看起来像是:

criteria.add(Restrictions.and(Restrictions.ge("orderTotalPrice.amount", amountFrom),
                    Restrictions.le("orderTotalPrice.amount", amountTo)));

此外,我需要让所有订单都包含付款金额介于相同两个值之间的付款。如果paymentAmount是Order实体的属性,我们可以这样:

criteria.add(Restrictions.or(
                    Restrictions.and(Restrictions.ge("orderTotalPrice.amount", amountTo),
                        Restrictions.le("orderTotalPrice.amount", amountFrom)),
                    Restrictions.and(Restrictions.ge("paymentAmount.amount", amountFrom),
                        Restrictions.le("paymentAmount.amount", amountTo))));

我的问题是,付款金额仅存在于订单实体内的付款对象内。 因此,要获得订单的付款金额,我需要类似“payment.paymentAmount.amount”的内容。这当然不起作用,所以通常我会创建一个这样的子标准:

 criteria.createCriteria("payment").add(
                    Restrictions.and(Restrictions.ge("paymentAmount.amount", amountFrom),
                        Restrictions.le("paymentAmount.amount", amountTo)));

将上述示例和第一个示例添加到条件中意味着订单价格和付款金额的金额必须相同。我需要的是这两个限制之间的“或”。

所以我的问题是: Criteria API是否支持将Criterion添加到条件对象以表示另一个Criterion和子标准之间的OR?

我希望很清楚我的问题是什么。如果有人需要更多信息,请随时添加评论!

提前致谢!

PS: 这些是(简化的)hibernate实体类:

@Entity
public class Order {

    @Embedded
    private Money orderTotalPrice;

    @OneToOne(optional = true)
    private Payment payment;

    // Getters & Setters
}


@Entity
public class Payment {

    @Embedded
    private Money paymentAmount;

    // Getters & Setters
}


@Embeddable
public class Money {
    @Column
    private BigDecimal amount;

    // Getters & Setters
}

1 个答案:

答案 0 :(得分:0)

我不确定我是否已完全理解您的需求,但使用别名通常比使用子标准更容易:

Criteria c = session.createCriteria(Order.class, "order");
// join with payment:
c.createAlias("order.payment", "p");
// now you can refer to properties of order.payment using the "p" alias
c.add(Restrictions.or(
    Restrictions.and(Restrictions.ge("p.paymentAmount.amount", amountFrom),
                     Restrictions.le("p.paymentAmount.amount", amountTo)),
    Restrictions.and(Restrictions.ge("order.orderTotalPrice.amount", amountTo),
                     Restrictions.le("order.orderTotalPrice.amount", amountFrom))));

这对我来说更自然,因为它几乎是以下HQL的直接翻译:

select order from Order order
join order.payment p
where (p.paymentAmount.amount >= :amountFrom and p.paymentAmount.amount <= :amountTo)
or (order.orderTotalPrice.amount >= amountFrom and order.orderTotalPrice.amount <= amountTo)

请参阅http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#querycriteria-associations