我想将查询结果分配给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;
}
}
外观如下
@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();
}
但是,这无法正常工作,因为我收到以下异常:
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]
答案 0 :(得分:0)
首先,您可以查看Spring Data JPA文档,并在以下部分找到一些帮助:Class-based Projections (DTOs)。
还有一个标题为避免投影DTO的样板代码的段落,他们建议您使用Lombok的@Value
批注来生成不可变的DTO 。这与Lombok的@Data
批注相似,但不可变。
如果将其应用于示例,则源代码将如下所示:
@Value
public class MetricDto {
private int share;
private int shareholder;
}
然后,因为您的查询是一个NativeQuery,请在您的Spring Data Repository中指定它。 您可以在文档Native Queries中找到帮助。 您将需要类似的东西:
@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();
答案 1 :(得分:0)
在我的项目中,我已经使用投影进行了如下所示:
@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);
}
// Interface to which result is projected
public interface PeopleDTO {
String getName();
Long getCount();
}
投影接口中的字段必须与该实体中的字段匹配。否则,字段映射可能会中断。
此外,如果您使用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();
并创建interface
MetricDTO
,如下所示:
public interface MetricDTO {
Integer getSum();
Long getCount();
}
还要确保getSum()
和getCount()
的返回类型正确,这可能会因数据库而异。