我目前正在实现一个带有类似按钮的文档,如下所示:
like按钮与某个用户帐户相关联。当你按下like时,它将保持该用户的喜欢(类似于youtube视频)。
我的实体和DTO如下:
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;
}
我有一些解决办法:
使用@formular combine with@transient向doc.java添加一个名为isliked的字段,并对db执行查询。
另一个api从客户端接受docid列表和userid,然后返回userid喜欢的docid列表。
检查likedusers列表中是否存在userid(效率不高,有时不可行,因为我必须初始化那个大的延迟加载列表)。
问题是:一次为大约1000个用户(1000个ccu)检索许多帖子的喜欢/不喜欢状态(大于10个文档,但每个请求最多100个文档)最有效的方法是什么?上述解决方案是否已经是最优的?
感谢您的帮助。谢谢你花时间看完这个问题。
1条答案
按热度按时间i5desfxk1#
如果我对问题理解正确,这种方法是不正确的。您希望确定给定的用户是否喜欢指定的文档,因此公式将需要一个用户id参数,您无法将该参数传递给公式。即使不知何故
@Formula
如果无法使用,则会导致n+1问题(每个文档都有额外的查询)。另外,您使用托管实体,这意味着在最后进行额外的脏检查。在我看来,这个查询是最佳的—一个查询,能够使用投影(没有托管实体)。
正如您所注意到的,这将杀死您的应用程序和数据库。另外,您还可以使用托管实体,这意味着在最后进行额外的脏检查。绝对不要用这个。