我想使用Spring Data Projection技术,只从表中提取一些字段(而不是表格的所有字段)。
如文档(https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections)中所述,我创建了一个简单的界面,例如:
interface NamesOnly {
String getFirstname();
String getLastname();
}
但我使用它有一些问题。
问题1:
首先,我想使用名称findAll()
创建一个查询,查找只包含两个字段(firstName
和lastName
)的所有行:
@Repository
public interface PersonaRepository extends JpaRepository<Persona, Long> {
List<NamesOnly> findAll();
}
但是在这种情况下我有这些错误(可能是因为findAll()
是JpaRepository
的方法):
- 实现org.springframework.data.jpa.repository.JpaRepository.findAll
- 返回类型与JpaRepository.findAll()
不兼容
问题2:
好的,我尝试将方法的名称更改为findAllOnlyNames()
:
@Repository
public interface PersonaRepository extends JpaRepository<Persona, Long> {
List<NamesOnly> findAllOnlyNames();
}
但现在我有这个错误:
引起: org.springframework.data.mapping.PropertyReferenceException:没有 找到类型为Persona的属性findAllOnlyNames!
因为Spring尝试从名称创建查询。
1)是否可以在没有JpaRepository问题的情况下重用方法名findAll()
?
2)是否可以从方法名称关闭查询创建(仅针对某些查询,而不是针对所有项目或存储库)?
答案 0 :(得分:3)
您走在正确的轨道上,您的findAll()
与现有Spring Data接口上指定的@Repository
public interface PersonaRepository extends JpaRepository<Persona, Long> {
List<NamesOnly> findAllOnlyNamesBy();
}
冲突,您可以重命名它(如您所尝试的那样),但它仍然必须是兼容的名称使用查询派生机制。试试这个:
find…By
This part of the Spring Data JPA documentation解释了查询创建过程的工作原理:
该机制从方法中删除前缀
read…By
,query…By
,count…By
,get…By
和By
,然后开始解析其余部分。< / p>
因此,您只需要在方法名称中添加@Query(...)
关键字,将该关键字视为条件后的任何内容,在这种情况下,没有条件,因此它会获取所有内容。
要从方法名称禁用查询派生,您需要向方法添加Object
注释,并指定JPA或本机查询。
答案 1 :(得分:2)
您可以指定显式查询,而不是依赖于从方法名称派生它。
@Repository
public interface PersonaRepository extends JpaRepository<Persona, Long> {
@Query("select p from Persona p")
List<NamesOnly> findAllOnlyNames();
}
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.at-query
覆盖findAll()
(即使在不太可能发生的情况下)也可能是一个坏主意。