例如,我有这段代码:
@Entity
@Table(name = "Foo")
public class FooImpl implements Foo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", nullable = false)
private Long id;
@Column(name = "name", nullable = false)
private String fooName;
@ElementCollection
private Set<Long> fooSet = new HashSet<Long>();
// constructors + getters
}
我想在我的服务类中创建一个方法,该方法将返回最大fooSet
大小的对象。如何使用JPQL实现这一目标?以下代码不正确,但这是我尝试过的:
@Override
public Foo getTopFoo() {
return (Foo)entityManager.createQuery("select c from Foo where max(size(c.fooSet)) ").getSingleResult();
}
答案 0 :(得分:2)
你可以尝试一下,因为我知道你可以在JPQL中使用/ =中的子查询,但我很怀疑它是否有效或者它是一个有效的语法(请注意使用Foo.class
来避免强制转换!):
@Override
public Foo getTopFoo() {
return entityManager.createQuery("select c from Foo c where size(c.fooSet) = (select max(size(c.fooSet)) from Foo c)", Foo.class).getSingleResult();
}
我认为你的JPA实现不会正确翻译max(size())
,因为它是一个计算值:在伪SQL中,它会给出这样的结果:
select f.*, count(ff.*) as cu
from Foo f
left join Foo_fooSet ff on [...]
group by f.*
当然,您需要枚举表Foo
(或f
)的所有列。
您需要根据该计数返回子查询,例如:
select max(cu) from (
select f.*, count(ff.*) as cu
from Foo f
left join Foo_fooSet ff on [...]
group by f.*
)
但我不记得JPQL允许from
接受子查询。
但是,您可以使用本机查询,这可以工作:
select f.*
from Foo f
left join Foo_fooSet ff on [...]
group by f.*
having count(ff.*) = (
select max(cu) from (
select f.id, count(ff.*) as cu
from Foo f
left join Foo_fooSet ff on [...]
group by f.id
)
)
在子查询(计数)中,您只需要id。
如果是第一个select
(f。*),则必须将所有列对应于实体的字段。玩得开心!
或:返回实体的ID,然后使用entityManager
加载它们。
答案 1 :(得分:0)
最简单,最易读的方法是使用两个查询。
select id, count(*) from Bar group by id order by count(*) desc, id asc
此查询将为您提供ID和集合大小(假设Bar
是集合表的名称。
使用JPA,您可以轻松select only the first result。使用该ID,选择Foo
对象很容易。
另一种选择是在SQL中限制结果并与Foo表连接。
from Foo where id = (select top 1 id from (select id, count(*) from Bar group by id, order by count(*) desc, id asc))
然而,这不能以db不可知的方式完成。
答案 2 :(得分:0)
您似乎走在正确的轨道上,只需要子查询返回最大值并将其与当前c列表的大小进行比较。类似的东西:
因此,如果"Select max(size(c.fooSet)) from Foo c"
为您提供最大值,
"select f from Foo f where size(f.fooSet) = (select max(size(c.fooSet)) from Foo c)"
应该为您提供尺寸等于最大尺寸的Foos。