Spring-Data JPA CrudRepository 返回 Iterable,可以将其转换为 List 吗?

问题描述 投票:0回答:7

我正在编写一个代码生成工具,使用 Spring Data JPA 为 Spring Boot 应用程序生成后端接线代码,令我有点恼火的是

CrudRepository
中的方法返回
Iterable
而不是
List
,如
Iterable
没有提供足够的功能,但
List
可以,所以我正在寻找将
Iterable
转换为
List
的最佳方法。

我看到这篇文章

Iterable
更改为
Collection
,我想知道,与其使用像Guava这样的库或实现我自己的函数来进行转换,为什么不将其转换为
List
?这样做是不是有什么我不知道的错误?

编辑: 我问这个问题是因为它是一个代码生成工具,让它生成引入对第三方库的依赖关系的代码是不合理的,并且编写我自己的函数来进行转换也不是很合理,因为它必须位于某个地方,而我不想在生成的代码中包含它。一个简单的演员阵容就可以了,虽然有点难看,但只是想知道我是否遗漏了一些东西?

java spring spring-boot spring-data spring-data-jpa
7个回答
136
投票

你提到了

[spring-data-jpa]
所以我猜你使用JPA。在这种情况下,请使用
JpaRepository
而不是
CrudRepository
,其中方法返回
List
就像您想要的那样。


67
投票

不,我觉得不行。

虽然

List
保证是
Iterable
,但
Iterable
可能不是
List
。这意味着如果您确实将
Iterable
转换为
List
,它可能会在运行时失败。即使它有效,也不能保证它在未来会继续工作,因为它可能会在新版本的 Spring Data JPA 中发生变化,而不会破坏接口的契约。

您应该声明自己的返回

List
的查询方法,而不是使用强制转换。

您也可以使用

Streamable.of(iterable).toList()
进行转换。 这个答案还包含一些背景知识,为什么选择
Iterable
作为这些方法的返回类型。


52
投票

您的接口仍然可以扩展CrudRepository,您只需添加一个返回列表的新方法 findAll 即可。就像下面的例子:

@Repository
public interface DataRepository extends CrudRepository<Data, Long> {

    @Override
    List<Data> findAll();

}

如果您有一个“抽象”存储库要由所有存储库扩展,您也可以添加此方法,这样它将对您的所有存储库都有效。就像下面的例子:

@NoRepositoryBean
public interface GenericRepository<T> extends CrudRepository<T, Long> {

    @Override
    List<T> findAll();

}

3
投票

从 Spring Data 3 开始,还有另一个选项:

ListCrudRepository

这篇博文介绍了为什么

CrudRepository
选择
Iterable
而不是
List

https://spring.io/blog/2022/02/22/announcing-listcrudrepository-friends-for-spring-data-3-0


0
投票

嗨,我知道我来晚了,但如果你想将 Iterable 转换为 Collection,你可以这样做。

private <T> Collection<T> map(final Iterable<T> iterable) {
        return StreamSupport.stream(iterable.spliterator(), false)
                            .collect(Collectors.toCollection(HashSet::new));
    }

之后du可以通过.stream().toList()得到一个List;关于收藏。希望有帮助


0
投票

简单地说,您可以使存储库扩展 JpaRepository 而不是 CrudRepository。这将完美地发挥作用。这里 findAll 返回一个 List 而不是 Iterable。


0
投票

我不知道这是否可以帮助将来的任何人,但是在您的 @Repository 界面中,您可以扩展 ListCrudRepository 而不是 CrudRepository

public interface StudentRepository extends ListCrudRepository<student, Integer> {
}

然后在你的控制器中你可以获得一个列表:

    @GetMapping("")
    List<student> findAll() {
        return studentRepository.findAll();
    }
© www.soinside.com 2019 - 2024. All rights reserved.