gpt4 book ai didi

java - 在 Spring JPA 中聚合多个表中的数据的正确方法

转载 作者:行者123 更新时间:2023-12-01 19:03:36 38 4
gpt4 key购买 nike

我有一个问答部分,其中每个问题和答案都有一个与之关联的用户个人资料卡。它与堆栈溢出的情况非常相似。构成此用户配置文件卡的数据分布在多个表中。我正在从每个表中获取一列或两列。现在我不确定应该采取什么方法将用户个人资料卡与每个问题和答案关联起来。以下是我的想法

  1. 我无法在问答实体中建立直接关联,因为用户个人资料卡本身不是单个实体,而是一个聚合对象
  2. 我考虑过创建 DTO 作为投影,将问题和用户个人资料卡的数据聚合到一个 DTO 中,如下所示

    @Query("select new com.QuestionDto(q.id, q.topic, q.views, ud.username, ur.points) from QuestionEntity q join UserDetails ud ON q.userId = ud.userId join userRanking ur ON ud.userId = ur.userId where q.id = :id")
    QuestionDto findQuestionDto(@Param("id") Long id);

我发现这种方法的问题是还会有这样的 DTO 用于回答、评论等。因此,每当用户配置文件卡发生更改时,我都需要对所有 DTO 进行相应的更改。从代码可维护性的角度来看,这将是一个非常糟糕的设计。

  • 另一种方法是将用户个人资料卡数据聚合到其自身的 DTO 中,然后从每个问题、答案等中调用此 DTO。通过这种方法,至少用户个人资料卡的逻辑位于一个位置。

    @Query("select new com.UserProfileCard( ud.username, ur.points) from UserDetails ud join userRanking ur ON ud.userId = ur.userId where ud.userId = :id")
    UserProfileCard getUserProfileCard(@Param("id") Long userId);
  • 但另一方面,如果一个问题有 15 个回复,则每个用户将产生 (1 + 15) 次查询。从性能角度来看,我认为这不是非常有效。

    还有什么?从代码可维护性和性能角度来看,我是否缺少任何其他方法?

    谢谢

    最佳答案

    1. I have considered creating DTOs as projections to aggregate data for question and user profile card into one DTO like below

    当您拥有单独的 UserProfileCard dto 时,您仍然可以使用选项 2。

    包 javax.persistance 提供了通过使用注释 javax.persistence.Embedded 将 dto 嵌入到另一个实体 dto 中的功能。嵌入 dto 类由 javax.persistence.Embeddable 注释。您的 dto 类将如下所示 -

    @Embeddable
    public class UserProfileCard {

    private String username;

    private Integer points;
    }

    @Entity
    public class QuestionDto {

    @Id
    private Long id;

    private String topic;

    private Long views;

    @Embedded
    private UserProfileCard userProfileCard;
    }

    您可以使用相同的查询来获取 QuestionDto -

    @Query(nativeQuery = true, value = "select q.id, q.topic, q.views, ud.username, ur.points from question_entity q join user_details ud ON q.user_Id = ud.user_Id join user_ranking ur ON ud.user_Id = ur.user_Id where q.id = :id")
    QuestionDto findQuestionDto(Long id);

    *** 更新 ***

    使用 UserProfileCard 的 sql View 并在所有相关查询中使用它,避免在 dao 接口(interface)中出现代码重复。

    String USER_PROFILE_CARD_VIEW = "select ud.user_id, ud.username, ur.points from user_details as ud join user_ranking as ur on ur.user_id = ud.user_id";

    @Query(nativeQuery = true, value = "select q.id, q.topic, q.views, userprofilecard.* from question_entity q join (" + USER_PROFILE_CARD_VIEW +") as userprofilecard on userprofilecard.user_id = q.user_id where q.id = :id")
    QuestionDto findQuestionDto(Long id);

    关于java - 在 Spring JPA 中聚合多个表中的数据的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59596980/

    38 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com