我使用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;
}
所以,我有多对一单向,这意味着人看不到猫和狗。
答案 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()
(catList
和dogList
由于没有看到您的映射而被假定为亲自列表。
此查询会急切地为每个人提取您的猫狗名单。然后就可以了
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);
}