从方法名称禁用查询创建 - 使用投影

问题描述 投票:3回答:2

我想使用Spring Data Projection技术,只从表中提取一些字段(而不是表的所有字段)。

如文档(https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections)中所述,我创建了一个简单的界面,例如:

interface NamesOnly {
  String getFirstname();
  String getLastname();
}

但我使用它有一些问题。

问题1:

首先,我想使用名称findAll()创建一个查询,查找只有两个字段的所有行(firstNamelastName):

@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)是否可以重用方法名称findAll()而不会遇到JpaRepository问题?

2)是否可以从方法名称关闭查询创建(仅针对某些查询,而不是针对所有项目或存储库)?

spring-data spring-data-jpa
2个回答
3
投票

您走在正确的轨道上,您的findAll()与现有Spring Data接口上指定的那些冲突,您可以重命名它(如您所尝试的那样),但它仍然必须是与查询派生机制兼容的名称。试试这个:

@Repository
public interface PersonaRepository extends JpaRepository<Persona, Long> {
    List<NamesOnly> findAllOnlyNamesBy();
}

This part of the Spring Data JPA documentation解释了查询创建过程的工作原理:

该机制从方法中删除前缀find…Byread…Byquery…Bycount…Byget…By,并开始解析其余部分。

所以你只需要在方法名称中添加By关键字,在该关键字被视为条件之后的任何内容,在这种情况下没有条件因此它获取所有内容。

要从方法名称禁用查询派生,您需要向方法添加@Query(...)批注,并指定JPA或本机查询。


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()(即使在不太可能的情况下有可能)可能是一个坏主意。

© www.soinside.com 2019 - 2024. All rights reserved.