【问题标题】:How can I left join a subquery in hibernate with criteria?如何在休眠状态下加入带有条件的子查询?
【发布时间】:2017-02-19 21:47:46
【问题描述】:

我希望能够在休眠状态下使用条件左连接子查询。

这里是示例查询:

Select * From Order o
Left Join (Select * From Product p Where p.accountId = 3) p
On p.id = o.productId
Where (p.category is not null and p.category = 'clothes') or 
(p.category is null and o.category = 'clothes')

请注意,这是一个示例查询,我的查询更复杂,我需要能够左连接子查询。

如何使用休眠条件语法生成此查询?

我想做类似的事情:

Session session = sessionFactory.getCurrentSession();
Criteria criteria = session.createCriteria(Order.class);

DetachedCriteria productCriteria = DetachedCriteria.forClass(Product.class);
productCriteria.add(Restrictions.eq("accountId", 3));

criteria.createAlias("productCriteria", "p", JoinType.LEFT_OUTER_JOIN, productCriteria);

criteria.add(Restrictions.or(
        Restrictions.and(Restrictions.isNotNull("p.category"), Restrictions.eq("p.category", "clothes")),
   Restrictions.and(Restrictions.isNull("p.category"), Restrictions.eq("category", "clothes"))
));

List list = criteria.list();

编辑

在我的实际问题中,子查询由两个表组成。

【问题讨论】:

  • 什么休眠版本?
  • 不管休眠版本如何,您都必须在实体模型中映射关系,即Order 实体需要与Product 建立一对多关系。您可以使用休眠WITH 子句来限制accountId,例如FROM Order o LEFT JOIN o.products p WITH p.accountId = 3
  • @ChristianBeikov 我有这个,我也可以使用p.accountId = 3。但是,如果子查询包含连接,则不起作用。我已经用 in 子句解决了这个问题......但我想知道这是否可能......
  • Hibernate 不支持 FROM 子句中的子查询,如果这是您想知道的。您几乎总是可以将子查询重新表述为关系连接,但您必须为此调整模型。您不应该再使用 Hibernate Criteria API,因为它在 5 中已被弃用,并且可能在 6 中被删除。
  • @ChristianBeikov 是的,我想在 FROM 子句中使用它。这将大大简化我的查询。但感谢您的回答和信息。我刚刚调整了没有 FROM 子句的查询...

标签: java hibernate


【解决方案1】:

您可以使用 Criteria 类的 createAlias API 并指定连接类型。 有关详细信息,请参阅 this 文档。

    Criteria createAlias(String associationPath,
                 String alias,
                 int joinType)
                 throws HibernateException
Join an association using the specified join-type, assigning an alias to the joined association.
The joinType is expected to be one of CriteriaSpecification.INNER_JOIN (the default), CriteriaSpecification.FULL_JOIN, or CriteriaSpecification.LEFT_JOIN.

【讨论】:

  • 这将进行左连接,但是子查询部分呢? createAlias 采用参数标准,但不采用标准...
【解决方案2】:

您可以使用以下Criteria 方法在连接中使用子查询。

public Criteria createAlias(String associationPath, String alias, JoinType joinType, Criterion withClause) throws HibernateException;

还有一个Criterion 参数,您可以使用Subqueries 工厂类创建,它将在连接条件中生成一个子查询。

你最终会得到这样的结果:

Criteria criteria = session.createCriteria(Order.class);

DetachedCriteria productCriteria = DetachedCriteria.forClass(Product.class)
                .setProjection(property("id"))
                .add(Restrictions.eq("accountId", 3));

criteria.createAlias("product", "p", JoinType.LEFT_OUTER_JOIN, Subqueries.propertyEq("id", productCriteria));
...

【讨论】:

    猜你喜欢
    • 2012-03-17
    • 2012-12-30
    • 2011-07-20
    • 1970-01-01
    • 2010-09-08
    • 1970-01-01
    • 2011-04-13
    • 2013-10-08
    相关资源
    最近更新 更多