Java 最常用标记的NamedQuery
假设我有以下两门课:Java 最常用标记的NamedQuery,java,sql,jpa,jpql,Java,Sql,Jpa,Jpql,假设我有以下两门课: @Entity class Article { @Id int id; @ManyToMany(mappedBy="articles") List<Tag> tags; } @Entity @NamedQueries({ @NamedQuery(name = "Tag.trends", query = "SELECT t FROM Tag t") // Some magic stuff here.. }) class
@Entity
class Article {
@Id
int id;
@ManyToMany(mappedBy="articles")
List<Tag> tags;
}
@Entity
@NamedQueries({
@NamedQuery(name = "Tag.trends", query = "SELECT t FROM Tag t") // Some magic stuff here..
})
class Tag {
@Id
String name;
@ManyToMany
List<Articles> articles;
}
输出
A // 3 times
C // 2 times
B // 1 time
在这类问题上,你要倒行逆施。从SQL查询开始:
select
count(t.name), t.name
from article a
join article_tags ats
join tag t
where
a.id=ats.article_id
and ats.tag_id = t.id
group by
t.name
order by
count(t.name)
desc;
那么JPQL应该或多或少遵循以下原则:
List<Tuple> t = em.createQuery("select t.name as name, count(t.name) as count from Article a join a.tags t group by (t.name) order by count(t.name) desc", Tuple.class).getResultList();
t.stream().forEach((tp)-> {
System.out.println("Count of " + tp.get("name") + " = " + tp.get("count"));
});
更新:如果您想要标签列表,只需将元组的第一个元素更改为标签。当然,如果您愿意,您可以忽略计数:
List<Tag> t = em.createQuery("select t from Article a join a.tags t group by (t.name) order by count(t.name) desc", Tag.class).getResultList();
t.stream().forEach((tag)-> {
System.out.println("Tag = " + tag.getName());
});
在这类问题上,你要倒行逆施。从SQL查询开始:
select
count(t.name), t.name
from article a
join article_tags ats
join tag t
where
a.id=ats.article_id
and ats.tag_id = t.id
group by
t.name
order by
count(t.name)
desc;
那么JPQL应该或多或少遵循以下原则:
List<Tuple> t = em.createQuery("select t.name as name, count(t.name) as count from Article a join a.tags t group by (t.name) order by count(t.name) desc", Tuple.class).getResultList();
t.stream().forEach((tp)-> {
System.out.println("Count of " + tp.get("name") + " = " + tp.get("count"));
});
更新:如果您想要标签列表,只需将元组的第一个元素更改为标签。当然,如果您愿意,您可以忽略计数:
List<Tag> t = em.createQuery("select t from Article a join a.tags t group by (t.name) order by count(t.name) desc", Tag.class).getResultList();
t.stream().forEach((tag)-> {
System.out.println("Tag = " + tag.getName());
});
你可以通过以下方式实现你想要的
SELECT t FROM Tag t ORDER BY SIZE(t.articles) ASC
这将为您提供按文章数量排序的标签列表。您可以使用以下方法实现所需的功能
SELECT t FROM Tag t ORDER BY SIZE(t.articles) ASC
这将为您提供按文章数量排序的标签列表。您想对所有标签进行分组,并获得计数和降序结果吗?@Nicholas我不确定是否要对它们进行分组。我想按项目类实例中出现的次数降序排列。这里可能有一个联接表,因为没有联接表的M-N有点没有意义SBTW:我知道您希望在标记表中有唯一的标记,但是您应该在标记表中设置一个约束并使用一个整数或长id,否则性能会很差。是否要对所有标记进行分组,并获得计数和降序?@Nicholas我不确定是否要对它们进行分组。我想按项目类实例中出现的次数降序排列。这里可能有一个联接表,因为没有联接表的M-N有点没有意义SBTW:我知道您希望在标记表中有唯一的标记,但是您应该在标记表中设置一个约束并使用一个整数或长id,否则性能会很差。太棒了,但是如何有效地从中获取标记列表?但是我需要按名称查询所有标记,这会很低效。是的,我的输出有点混乱。我想检索
列表
。我真的不关心事件的数量,它只需要按它们排序。我不想听起来不感激,但我希望它更高效,我不能再次按名称(Id)查询所有标记。我希望你能这样改变它!有关完整的可能性,请参阅更新。你可以选择任何你想要的。为什么你不直接用setMaxResults()
从标签t按大小排序(t.articles)desc中?太棒了,但是我如何有效地从中获得标签列表呢?但是我需要按名称查询所有标签,这样效率会很低。是的,我的输出有点混乱。我想检索列表
。我真的不关心事件的数量,它只需要按它们排序。我不想听起来不感激,但我希望它更高效,我不能再次按名称(Id)查询所有标记。我希望你能这样改变它!有关完整的可能性,请参阅更新。你可以选择任何你想要的。你为什么不用setMaxResults()
从标签t按大小排序(t.articles)desc
中选择呢?我会用desc
代替asc
,然后使用.setMaxResults()
来显示最流行的标签first@SashaSalauyou就这样。:)我会使用desc
而不是asc
,以及.setMaxResults()
来显示最流行的标记first@SashaSalauyou就这样。:)