bti*_*sae 6 dto jpql spring-data-jpa spring-boot
我想将查询结果分配给 DTO 对象。DTO 看起来像这样:
@Getter
@Setter
@NoArgsConstructor
public class Metric {
private int share;
private int shareholder;
public Metric(int share, int shareholder) {
this.share = share;
this.shareholder = shareholder;
}
}
Run Code Online (Sandbox Code Playgroud)
查询如下所示:
@RepositoryRestResource(collectionResourceRel = "shareholders", path = "shareholders")
public interface ShareholderRepository extends PagingAndSortingRepository<Shareholder, Integer> {
@Query(value = "SELECT new com.company.shareholders.sh.Metric(SUM(s.no_of_shares),COUNT(*)) FROM shareholders s WHERE s.attend=true")
Metric getMetrics();
}
Run Code Online (Sandbox Code Playgroud)
但是,这不起作用,因为我遇到了以下异常:
Caused by:org.hibernate.QueryException: could not resolve property: no_of_shares of:com.company.shareholders.sh.Shareholder[SELECT new com.company.shareholders.sh.Metric(SUM(s.no_of_shares),COUNT(*)) FROM com.company.shareholders.sh.Shareholder s WHERE s.attend=true]
Run Code Online (Sandbox Code Playgroud)
在我的项目中,我使用了如下所示的投影:
@Repository
public interface PeopleRepository extends JpaRepository<People, Long> {
@Query(value = "SELECT p.name AS name, COUNT(dp.people_id) AS count " +
"FROM people p INNER JOIN dream_people dp " +
"ON p.id = dp.people_id " +
"WHERE p.user_id = :userId " +
"GROUP BY dp.people_id " +
"ORDER BY p.name", nativeQuery = true)
List<PeopleDTO> findByPeopleAndCountByUserId(@Param("userId") Long userId);
@Query(value = "SELECT p.name AS name, COUNT(dp.people_id) AS count " +
"FROM people p INNER JOIN dream_people dp " +
"ON p.id = dp.people_id " +
"WHERE p.user_id = :userId " +
"GROUP BY dp.people_id " +
"ORDER BY p.name", nativeQuery = true)
Page<PeopleDTO> findByPeopleAndCountByUserId(@Param("userId") Long userId, Pageable pageable);
}
Run Code Online (Sandbox Code Playgroud)
结果投影到的接口:
public interface PeopleDTO {
String getName();
Long getCount();
}
Run Code Online (Sandbox Code Playgroud)
来自投影接口的字段必须与该实体中的字段匹配。否则字段映射可能会中断。
此外,如果您使用SELECT table.column表示法,请始终定义与实体名称匹配的别名,如示例所示。
在您的情况下,更改@Query如下所示:
@Query(value = "SELECT new " +
"SUM(s.no_of_shares) AS sum,COUNT(*) AS count FROM " +
"shareholders s WHERE s.attend=true", nativeQuery = true)
MetricDTO getMetrics();
Run Code Online (Sandbox Code Playgroud)
并创建interface MetricDTO 如下所示:
public interface MetricDTO {
Integer getSum();
Long getCount();
}
Run Code Online (Sandbox Code Playgroud)
另外,还要确保的返回类型getSum()和getCount()正确这可能会因不是基于数据库。
首先,您可以查看 Spring Data JPA 文档,您可以在本节中找到一些帮助:基于类的投影(DTO)。
还有一个标题为避免投影 DTO 的样板代码的段落,其中建议您使用 Lombok 的@Value注释来生成不可变的 DTO。这与 Lombok 的注释类似@Data,但不可变。
如果您将其应用到您的示例中,源代码将如下所示:
@Value
public class MetricDto {
private int share;
private int shareholder;
}
Run Code Online (Sandbox Code Playgroud)
然后,由于您的查询是 NativeQuery,因此在 Spring Data Repository 中指定它。您可以在文档中找到帮助:本机查询。你将需要类似的东西:
@Query(value = "SELECT new
com.company.shareholders.sh.MetricDto(SUM(s.no_of_shares),COUNT(*)) FROM
shareholders s WHERE s.attend=true", nativeQuery = true)
MetricDto getMetrics();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18383 次 |
| 最近记录: |