Spring JPA一对多加入
Spring JPA one to many join
@Entity
@Getter @Setter
public class IndieApp {
@Id
@Column(name = "indie_app_id")
private Long id;
@Column(name = "name")
private String name;
@OneToMany(mappedBy = "indieApp")
private List<Genre> genres = new ArrayList<>();
}
@Entity
@Getter @Setter
public class Genre {
@Id
@Column(name = "genre_id")
private Long genreId;
@Column(name = "description")
private String description; //like "RPG", "Action"
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "indie_app_id")
private IndieApp indieApp;
}
@Data
public class RandomRecDto {
private final Long id;
private final String name;
private final String genres;
}
@Repository
@RequiredArgsConstructor
public class RandomRecRepository {
private final EntityManager em;
public List<RandomRecDto> findRandomApps() {
return em.createQuery(
"select new study.weba.studyJPA.dto.RandomRecDto(i.id, i.name, g.description)" +
" from IndieApp i join i.genres g", RandomRecDto.class)
.setMaxResults(12)
.getResultList();
}
}
前辈您好!
当我如下所示放置虚拟数据时,
indie_app_id
name
1
App1
2
App2
genre_id
description
indie_app_id
1
Action
1
2
RPG
1
3
FPS
2
4
Sport
2
我可以得到这样的结果。
randomRecDto = RandomRecDto(id=1, name=App1, genres=Action)
randomRecDto = RandomRecDto(id=1, name=App1, genres=RPG)
randomRecDto = RandomRecDto(id=2, name=App2, genres=FPS)
randomRecDto = RandomRecDto(id=2, name=App2, genres=Sport)
然而,我想要的结果是这样的
randomRecDto = RandomRecDto(id=1, name=App1, genres=Action, RPG)
randomRecDto = RandomRecDto(id=2, name=App2, genres=FPS, Sport)
我想通过数组获取描述。
我该怎么办?
为什么不获取 IndieApp
实体,然后将它们转换为 RandomRecDto
DTO?这甚至可以简化处理 IndieApp
而不是 RandomRecDto
:
的存储库
public interface IndieAppRepository extends JpaRepository<IndieApp, Long> {
List<IndieApp> findTop12();
}
您可能想在以下链接中阅读有关 Spring 数据的更多详细信息:
JpaResultMapper jpaResultMapper = new JpaResultMapper();
String sql = "SELECT i.indie_app_id, i.name, group_concat(g.description separator ',') FROM indie_app AS i" +
" JOIN genre AS g ON i.indie_app_id = g.indie_app_id" +
" group by i.indie_app_id, i.name";
Query nativeQuery = em.createNativeQuery(sql);
List<RandomRecDto> results = jpaResultMapper.list(nativeQuery, RandomRecDto.class);
@Entity
@Getter @Setter
public class IndieApp {
@Id
@Column(name = "indie_app_id")
private Long id;
@Column(name = "name")
private String name;
@OneToMany(mappedBy = "indieApp")
private List<Genre> genres = new ArrayList<>();
}
@Entity
@Getter @Setter
public class Genre {
@Id
@Column(name = "genre_id")
private Long genreId;
@Column(name = "description")
private String description; //like "RPG", "Action"
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "indie_app_id")
private IndieApp indieApp;
}
@Data
public class RandomRecDto {
private final Long id;
private final String name;
private final String genres;
}
@Repository
@RequiredArgsConstructor
public class RandomRecRepository {
private final EntityManager em;
public List<RandomRecDto> findRandomApps() {
return em.createQuery(
"select new study.weba.studyJPA.dto.RandomRecDto(i.id, i.name, g.description)" +
" from IndieApp i join i.genres g", RandomRecDto.class)
.setMaxResults(12)
.getResultList();
}
}
前辈您好! 当我如下所示放置虚拟数据时,
indie_app_id | name |
---|---|
1 | App1 |
2 | App2 |
genre_id | description | indie_app_id |
---|---|---|
1 | Action | 1 |
2 | RPG | 1 |
3 | FPS | 2 |
4 | Sport | 2 |
我可以得到这样的结果。
randomRecDto = RandomRecDto(id=1, name=App1, genres=Action)
randomRecDto = RandomRecDto(id=1, name=App1, genres=RPG)
randomRecDto = RandomRecDto(id=2, name=App2, genres=FPS)
randomRecDto = RandomRecDto(id=2, name=App2, genres=Sport)
然而,我想要的结果是这样的
randomRecDto = RandomRecDto(id=1, name=App1, genres=Action, RPG)
randomRecDto = RandomRecDto(id=2, name=App2, genres=FPS, Sport)
我想通过数组获取描述。 我该怎么办?
为什么不获取 IndieApp
实体,然后将它们转换为 RandomRecDto
DTO?这甚至可以简化处理 IndieApp
而不是 RandomRecDto
:
public interface IndieAppRepository extends JpaRepository<IndieApp, Long> {
List<IndieApp> findTop12();
}
您可能想在以下链接中阅读有关 Spring 数据的更多详细信息:
JpaResultMapper jpaResultMapper = new JpaResultMapper();
String sql = "SELECT i.indie_app_id, i.name, group_concat(g.description separator ',') FROM indie_app AS i" +
" JOIN genre AS g ON i.indie_app_id = g.indie_app_id" +
" group by i.indie_app_id, i.name";
Query nativeQuery = em.createNativeQuery(sql);
List<RandomRecDto> results = jpaResultMapper.list(nativeQuery, RandomRecDto.class);