如何使用 Hibernate 获取 @ElementCollection 的总和?

How to get sum of @ElementCollection with Hibernate?

我有一个实体 table 具有以下内容:

@实体 public class Post {

@Id
@GeneratedValue
private Long id;

@NotBlank
@Size(min = 1, max = 2014)
private String text;

@NotNull
@Temporal(TemporalType.TIMESTAMP)
private Date created;

@NotNull
@ManyToOne
private User author;

@ElementCollection(fetch = FetchType.EAGER)
private Set<String> votesFor;

@ElementCollection(fetch = FetchType.EAGER)
private Set<String> againstFor;

@OneToMany(mappedBy = "post", cascade = CascadeType.REMOVE)
private List<Comment> comments;

public Post() {
    votesFor = new HashSet<>();
    againstFor = new HashSet<>();
    comments = new ArrayList<>();
}

我想创建一个 TypedQuery 以获得最多的投票 post。 我通过以下代码在@ElementCollection 中添加投票。

我如何对 @ElementCollection 求和,然后 return 一个包含 post 的列表,在开始时投票最高,停止时投票较少?

public void votesFor(String userId, long postId) {

    Post post = em.find(Post.class, postId);
    if(post == null) {
        throw new IllegalArgumentException("Post not exists: " + postId);
    }

    if(post.getVotesFor().contains(userId)) {
        throw new IllegalArgumentException("User " + userId + " have already voted");
    }

    post.getVotesFor().add(userId);
    post.getAgainstFor().remove(userId);
}

在 JPQL 中,您可以使用名为 SIZE 的函数来获取 ElementCollection 的大小。

我不太明白你到底想如何查询你的数据,所以我会给你两个不同的例子,说明你的示例实体结构中可能的用法。

获得 N 个最多的投票 posts

要获得 N 个最多的投票 post 我们需要

  1. votesFor 集合的大小对我们的 post 进行排序。
  2. 以N为限

就这样:

select p from Post p order by SIZE(p.votesFor) desc limit :n

其中 :n 是您查询中的某个参数

获得 posts 至少 N 票

第二种可能的方法是查询 post 至少有一定数量的 'votesFor'。为此,您只需要使用 WHERE 表达式,就像那样:

select p from Post p where SIZE(p.votesFor) >= :n

其中 :n 是您正在寻找的最少投票数。

更多关于 SIZE 等特殊运算符的信息 HERE