首页 > 解决方案 > Hibernate 查询获取对象列表,每个所需对象都在其他对象列表中。该列表是另一个对象的一部分

问题描述

我从早上起就一直在为一个查询而苦苦挣扎。我有以下 JSON:

{
    "id": "87ee51c7-3f15-4772-a2fb-bee379e1054d",
    "description": "What color do you like?",
    "option1": "Yellow",
    "option2": "Blue",
    "option3": "Green",
    "option4": "Red",
    "option5": "Pink",
    "votes": [
      {
        "id": "26bf4e30-c75a-4267-8850-4f04101fdd35",
        "answerOption": "Pink",
        "user": {
          "id": "f836bd80-53d8-4623-8198-ca375abfdbbc",
          "authId": "auth0|5ff8fe4bee9af4febf00762c3f1e",
          "firstName": "Test",
          "lastName": "Name",
          "phone": "07545166181",
          "email": "user@yahoo.com",
          "buildingStreet": "test",
          "buildingNumber": "15",
          "buildingName": "8",
          "buildingEntrance": "A",
          "town": "town",
          "country": "country",
          "other": ""
        },
        "date": "2021-01-30"
      },
      {
        "id": "0047474f-ecf1-424b-960a-a512e6bb14f5",
        "answerOption": "Blue",
        "user": {
          "id": "7da77dff-a22a-47ac-b995-41fa90866016",
          "authId": "auth0|60055f048ec4a3006ee36d64",
          "firstName": "John",
          "lastName": "Doe",
          "phone": "0755888999",
          "email": "user2@yahoo.com",
          "buildingStreet": "street",
          "buildingNumber": "15",
          "buildingName": "8",
          "buildingEntrance": "A",
          "town": "town",
          "country": "country",
          "other": ""
        },
        "date": "2021-01-30"
      }
    ],
    "status": "active",
    "endDate": "2021-02-05"
  }

所以我有一个投票,有一个 id、描述和 5 个投票选项。民意调查有一张选票清单,所以我有多个选票。每个投票都包含一个答案、日期和用户。

是否有一个查询来建立一个知道问题 id 的用户列表?

这个想法是建立这个已经投票的用户列表,所以我限制他们为同一个投票投票两次。

我使用 Hibernate 作为 ORM,Spring Boot 用于后面,React 用于前面。

列出 findAllUsers .... 投票 id 在哪里...

有没有办法通过声明到达那里?最近我在使用 Hibernate,我对手工查询非常生疏。

先感谢您

标签: sqlspring-boothibernate

解决方案


假设数据结构看起来几乎像这样:

public class User {

  @Id private Long id;
  
  // getters & setters

}

public class Vote {

  @Id private Long id;
  
  @ManyToOne private Poll poll;
  
  @ManyToOne private User user;
  
  // getters & setters

}

public class Poll {

  @OneToMany List<Vote> votes;
  
  // getters & setters
  
}

使用存储库,恕我直言,指定的最干净的地方是VoteRepository. 为此,存储库应如下所示(使用带有方法名称的查询生成,请参阅Spring Data JPA 参考指南中的查询方法):

public interface VoteRepository extends JpaRepository<Vote> {

  List<Vote> findByPoll(Poll poll);

}

然后,要获取与投票相关的所有用户,例如在控制器中,应该完成从投票到用户的映射:

@Autowired
VoteRepository voteRepository;

public List<User> getUsersRelatedToPoll(Poll poll) {
  List<Vote> votes = voteRepository.findByPoll(poll);
  return votes.stream().map(Vote::getUser).collect(Collectors.toList());
}

另一种方式,恕我直言,不是最干净的方式(^1),可能是一种@Query方法(请参阅Spring Data JPA 参考指南中的使用@Query)。此方法如下所示:

public interface FooRepository extends JpaRepository<Foo> {

  @Query("SELECT v.user FROM VOTE as v WHERE v.poll = :poll")
  List<User> findUsersByPoll(@Param("poll") Poll poll);

}

^1:我认为,例如在不UserRepository应该知道或使用PollVote...


推荐阅读