Java 在JPA/Hibernate中实现喜欢/不喜欢状态检索的最有效方法?

Java 在JPA/Hibernate中实现喜欢/不喜欢状态检索的最有效方法?,java,spring,postgresql,hibernate,jpa,Java,Spring,Postgresql,Hibernate,Jpa,我目前正在实现一个带有类似按钮的文档,如下所示: like按钮与某个用户帐户相关联。当你按下“喜欢”按钮时,该用户会一直喜欢它(类似于youtube视频) 我的实体和DTO如下所示: Doc.java: @Entity(name = "Doc") @Table(name = "doc") @Data public class Doc { //Unrelated code reacted for clarity @ManyToMany(casc

我目前正在实现一个带有类似按钮的文档,如下所示:

like按钮与某个用户帐户相关联。当你按下“喜欢”按钮时,该用户会一直喜欢它(类似于youtube视频)

我的实体和DTO如下所示:

Doc.java:

@Entity(name = "Doc")
@Table(name = "doc")
@Data
public class Doc {
   //Unrelated code reacted for clarity
   @ManyToMany(cascade = {
            CascadeType.MERGE,
            CascadeType.PERSIST
   })
   @JoinTable(
            name = "doc_user_dislike",
            joinColumns = @JoinColumn(name = "doc_id"),
            inverseJoinColumns = @JoinColumn(name = "user_id")
    )
    private Set<UserWebsite> dislikedUsers;

    @ManyToMany(cascade = {
            CascadeType.MERGE,
            CascadeType.PERSIST
    })
    @JoinTable(
            name = "doc_user_like",
            joinColumns = @JoinColumn(name = "doc_id"),
            inverseJoinColumns = @JoinColumn(name = "user_id")
    )
    private Set<UserWebsite> likedUsers;
}
我有一些解决方案:

  • 使用@Formular combine with向Doc.java添加一个名为isLiked的字段 @瞬态和执行对数据库的查询
  • 拥有另一个API,该API接受来自客户端的DocID列表,以及 UserID,然后返回UserID喜欢的DocID列表
  • 检查用户ID是否存在于LikeUsers列表中(效率不高, 有时不可行,因为我必须初始化那么大的 延迟加载列表)
  • 问题是:一次为大约1000个用户(1000个CCU)检索多篇文章的喜欢/不喜欢状态(超过10个文档,但每个请求最多100个文档)的最有效方法是什么?上述解决方案是否已经是最优的

    感谢您的帮助。谢谢你花时间看完这个问题

  • 如果我对问题的理解正确,这种方法是不正确的。您希望确定给定用户是否喜欢指定的文档,因此公式将需要用户id参数,您无法将该参数传递给公式。即使可以以某种方式使用
    @Formula
    ,也会导致N+1问题(每个文档都有额外的查询)。此外,您还可以使用托管实体,这意味着最后需要进行额外的脏检查

  • 在我看来,这个查询是最佳的,一个查询,能够使用投影(没有管理实体)

  • 正如您所注意到的,这将杀死您的应用程序和数据库。此外,您还可以使用托管实体,这意味着最后需要进行额外的脏检查。绝对不要用这个

  • @Entity
    @Table(name = "user_website")
    @Data
    public class UserWebsite {
        //Unrelated code reacted for clarity
        @ManyToMany(mappedBy = "likedUsers")
        private Set<Doc> likedDocs;
    
        @ManyToMany(mappedBy = "dislikedUsers")
        private Set<Doc> dislikedDocs;
    }
    
    @Data
    public class DocDetailsDTO {
        private Long id;
    
        private Boolean isDisliked;
    
        private Boolean isLiked;
    }