【问题标题】:Most efficient way to implement Liked/Disliked status retrieval in JPA/Hibernate?在 JPA/Hibernate 中实现喜欢/不喜欢状态检索的最有效方法?
【发布时间】:2021-01-08 17:34:32
【问题描述】:

我目前正在实现一个带有类似按钮的文档:

点赞按钮与某个用户帐户相关联。当您按赞时,该用户将继续为该用户点赞(类似于 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;
}

用户.java:

@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;
}

DocDetailsDTO.java(这将被发送到客户端)。

@Data
public class DocDetailsDTO {
    private Long id;

    private Boolean isDisliked;

    private Boolean isLiked;
}

我有一些解决方案:

  1. 将名为 isLiked 的字段添加到 Doc.java 与 @Formular 结合 @Transient 并对数据库执行查询。
  2. 有另一个 API 接受来自客户端的 DocID 列表和一个 UserID,然后返回 UserID 喜欢的 DocID 列表。
  3. 检查用户 ID 是否存在于 likeUsers 列表中(效率不高, 有时不可行,因为我必须初始化那么大 延迟加载列表)。

问题是:对于大约 1000 个用户 (1000 CCU) 一次检索多个帖子的喜欢/不喜欢状态的最有效方法是什么(> 10 个文档,但每个请求最多 100 个文档)?以上解决方案是否已经最优?

感谢任何帮助。感谢您花时间阅读问题。

【问题讨论】:

    标签: java spring postgresql hibernate jpa


    【解决方案1】:
    1. 如果我正确理解问题,这种方法是不正确的。您想确定给定用户是否喜欢指定的文档,因此公式需要一个用户 ID 参数,您无法将其传递给公式。即使可以以某种方式使用@Formula,它也会导致 N+1 问题(每个文档的额外查询)。另外,您使用托管实体,这意味着最后需要额外的脏检查。

    2. 我认为这是最佳 - 一个查询,能够使用投影(无托管实体)。

    3. 如您所见,这将杀死您的应用程序和数据库。另外,您再次使用托管实体,这意味着最后需要进行额外的脏检查。绝对不要用这个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-06
      • 1970-01-01
      • 2016-01-01
      相关资源
      最近更新 更多