从三个实体中检索数据,其中两个实体与最后一个实体存在多对一关系

时间:2018-02-12 13:53:57

标签: json spring spring-data-jpa jpql many-to-one

我使用Spring Boot作为REST后端应用程序。让我们说人有猫和狗,猫和狗都与人有多对一的关系。由此,Cat和Dog将Person id作为外键。由于我使用的是Spring JPA Repository和多对一关系,因此可以直接获得带有人员的猫列表和带有人员的狗列表。这些列表转换为json,我可以使用前端应用访问该人的数据。这是我的问题:
我想为每个人返回所有猫狗名单。
我猜JPA Repository没有我的请求的默认查询,所以我必须使用自定义查询。但是,我不知道如何制作它。我尝试过以下一个:

@Query("select p, c, d from Person p, Cat c, Dog d where c.person.id = :id and d.person.id = :id and person.id = :id")  
List<Object[]> findAllPersonsWithCatsAndDogs(Integer id);  

这个想法是为每个人进行循环,并使用人的身份来检索他的猫和狗。结果是对象列表,其中每个对象具有相同的人,他的一只猫和他的一只狗。我不喜欢这样,因为对于所有人我都列出了猫狗列表 如何获得每个人所有猫狗的所有人的一个列表 由于
以下是使其更清晰的映射:

@Entity  
public class Person {  
//there is no mappings because of unidirectional many to one  
}
...  
@Entity  
public class Cat{  
        @ManyToOne  
        @JoinColumn(name = "person_id")
        private Person person;  
}  
...  
@Entity  
public class Dog{  
        @ManyToOne    
        @JoinColumn(name = "person_id")  
        private Person person;  
} 

所以,我有多对一单向,这意味着人看不到猫和狗。

2 个答案:

答案 0 :(得分:0)

你应该添加人,猫和狗之间的参考。

@Entity  
public class Person {  
  @OneToMany(cascade = CascadeType.PERSIST, mappedBy="person")
  private List<Cat> catList;

  @OneToMany(cascade = CascadeType.PERSIST, mappedBy="person")
  private List<Dog> dogList; 
}

然后,如果你想让所有与他们的猫和狗一起的人,你可以做一些像

@Query("SELECT p FROM Person P JOIN FETCH p.catList JOIN FETCH p.dogList")
List<Person> findAllPersonsWithCatsAndDogs()

catListdogList由于没有看到您的映射而被假定为亲自列表。

此查询会急切地为每个人提取您的猫狗名单。然后就可以了

for (Person p : personRepo.findAllPersonsWithCatsAndDogs()) {
  for (Cat c : p.getCastList()) {

  }

  for (Dog d : p.getDogList()) {

  }
}

答案 1 :(得分:0)

通常,DTO模式用于包装必要的数据。因此,您可以使用多个对象映射框架,例如ModelMapper,Modelstruct,Dozer。

如果为cat and dog Entity创建两个存储库,则可以执行以下方法:

CatRepository中的方法:

List<Cat> findByPersonId(int id);

DogRepository中的方法:

List<Cat> findByPersonId(int id);

询问人:

List<Person> persons = personRepository.findAll();
List<PersonDto> personsDto = new ArrayList<>();

foreach(Person p:persons) {
   PersonDto dto = modelmapper.map(p, PersonDto.class);
   p.setCats(catRepo.findByPersonId(p.getId()));
   p.setCats(catRepo.findByPersonId(p.getId()));

   personsDto.add(dto);
}