Spring JPA 投影 findAll

Spring JPA Projection findAll

是否可以将 "findAll" 用于返回 Collection/List 投影的 JPARepository? 示例:

@Entity
public class Login {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
    @GenericGenerator(name = "native", strategy = "native")
    private Integer id;

    private String name;

    private String pass;

    (...)

}

public interface LoginProjection {
    public String getName();
}

@Repository
public interface LoginRepository extends JpaRepository<Login, Long> {
    Login findByName(String name);

    @Query(value = "SELECT name FROM login", nativeQuery = true)
    List<LoginProjection> findAllLoginProjection();
}

使用@Query 就可以了!但是不能使用

 List<LoginProjection> findAll();

因为 LoginProjection 它不扩展 T(登录)。

我在想是否可以为 findAll 提供一个 "alias",比如 findAllXYZ,它与 findAll 的功能相同。 使用过滤器也可以,但我不想使用它们:

 List<LoginProjection> findAllByName(String name);

我的主要目标是这样的:

@Repository
public interface LoginRepository extends JpaRepository<Login, Long> {
    Login findByName(String name);

    List<Login> findAll();

    List<LoginProjection> findAllLoginProjection();
}

这很简单 "zero @Query"

并向存储库添加方法:

List<LoginProjection> findAllProjectedBy();

方法名称可以简化为 findBy() 以匹配 https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections

中的文档示例

我假设您没有使用 Spring Data REST,因此 @Projection 在这里无济于事。 @pavel-molchanov 展示了一种表达投影的形式,另一种形式是:

List<LoginProjection> findBy();

如果您有多个投影,您可以避免在存储库中为每个投影创建一个方法,方法是使用 dynamic projections,例如这个:

<T> List<T> findBy(Class<T> projection);

// usage e.g.
... = findBy(LoginProjection.class);
... = findBy(UserSummaryProjection.class);

如果您想更灵活,可以将此方法添加到存储库中

<T> List<T> findBy(Class<T> projection);

然后你可以用下面的方式调用它

List<LoginProjection> rows = loginRepository.findBy(LoginProjection.class);

这种方法的优点是您可以使用同一个查询使用您想要的所有投影