【问题标题】:Limit items in collection with HQL使用 HQL 限制集合中的项目
【发布时间】:2013-01-12 11:06:23
【问题描述】:

在我的模型中,我有两个实体:Person 和 Puppy(为了简化它:))。它们之间存在一对多关系,因此每个人都有一组小狗。

现在想编写 HQL 查询,该查询将列出所有名为“John”的人,但也将小狗限制为 2 个月以上的人。

我的第一次尝试是这样的:

SELECT p FROM Person p
JOIN FETCH p.puppies pu
WHERE p.name = 'John'
AND pu.age > 2

但它不起作用,因为此查询仅选择那些至少有一只超过两个月的小狗的人,而不是那些只有更年轻的小狗。而且我也想看到他们只是用空的小狗名单。

实际上我想实现类似(伪代码):

SELECT p FROM Person p
JOIN FETCH p.puppies pu HAVING (pu.age > 2 )
WHERE p.name = 'John'

【问题讨论】:

    标签: hibernate hql


    【解决方案1】:

    HQL supports various kinds of joins。因此,您可以像这样使用左(外)联接:

    FROM Person p
    LEFT OUTER JOIN p.puppies pu
    WHERE p.name = 'John'
    AND pu.age > 2
    

    这也应该给你所有没有小狗的约翰。你说“......但不是那些只有更年轻的人​​”。不是很明白。如果明确声明AND pu.age > 2,你为什么要看到那些有更年轻的小狗?

    【讨论】:

    • 这不是我想要的。顺便说一句,我的查询看起来像那样(只是没有 OUTER,如果您使用 LEFT,它是可选的)。也许我没有足够平淡地解释我的问题是什么。我想要所有名叫约翰的人,但将他们的罂粟花限制在 2 个月大的时候。因此,如果有一些 JOHN 有 2 只小狗:1 个月和 3 个月,我应该只用一只小狗得到它。如果有第二个约翰带着一只小狗,那是 1 个月,那么我仍然应该让这个人只带着空的小狗名单。 (看看我的伪代码查询。我认为它说明了这个想法)
    【解决方案2】:

    我设法使用hibernate filters解决了我的问题

    首先我必须定义我的过滤器:

    @Entity
    @FilterDef(name="olderThan", parameters=@ParamDef( name="months", type="integer" ) )
    public class Person{
      @OneToMany
      @Filter(name="olderThan", condition="age > :months")
      private List<Puppy> puppies;
    }
    

    然后在执行查询过滤器之前必须启用:

    public class PersonRepository{
      @PersistenceContext
      private EntityManager em;
    
      public List<Person> findPeopleWithPoppiesLimitedToOlderThan(int months){
        em.unwrap(Session.class).enableFilter("olderThan").setParameter("months", months);
        return em.createQuery("SELECT p FROM Person LEFT JOIN FETCH p.puppies WHERE p.name = 'John'", Person.class).getResultList();
      }
    }
    

    一切正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-22
      • 2011-02-20
      • 1970-01-01
      • 2018-09-03
      • 2019-01-23
      • 2018-03-01
      相关资源
      最近更新 更多