spring-data-jpa Spring-Data JPA CrudRepository返回Iterable,是否可以将其转换为List?

oalqel3c  于 2022-11-10  发布在  Spring
关注(0)|答案(6)|浏览(216)

我正在编写一个代码生成工具,为使用Spring-Data-Jpa的Spring-boot应用程序生成后端连接代码,CrudRepository中的方法返回Iterable而不是List,这让我有点恼火,因为Iterable没有提供足够的功能,但List提供了,所以我正在寻找将Iterable转换为列表的最佳方法。
我看过this post关于把一个可迭代对象转换成一个集合,我想知道,与其使用Guava这样的库或者实现我自己的函数来做转换,为什么不直接把它转换成List呢?这样做有什么我不知道的错误吗?
编辑:我这么问是因为它是一个代码生成工具,让它生成依赖于第三方库的代码是不合理的,而且我自己编写函数来做转换也是不合理的,因为它必须存在于某个地方,我宁愿在生成的代码中没有它。简单的强制转换是可行的,如果有点难看,但只是想知道是否有什么我遗漏了?

rseugnpd

rseugnpd1#

你提到了[spring-data-jpa],所以我猜你使用的是JPA。在这个例子中,使用JpaRepository而不是CrudRepository,其中的方法返回的是你想要的List

gkn4icbw

gkn4icbw2#

不,我不认为这是确定的。
虽然List保证是Iterable,但Iterable可能不是List。这意味着如果您将Iterable转换为List,它可能会在运行时失败。即使它工作,也不能保证它将来继续工作,因为它可能会在Spring Data JPA的新版本中更改,而不会破坏接口的约定。
您应该声明自己的返回List的查询方法,而不是使用强制转换。
或者,您可以使用Streamable.of(iterable).toList()来进行转换。This answer还包含一些背景信息,说明为什么选择Iterable作为这些方法的返回类型。

y3bcpkx1

y3bcpkx13#

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

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

    @Override
    List<Data> findAll();

}

如果你有一个“abstract”仓库可以被你所有的仓库扩展,你也可以添加这个方法,这样它就会对你所有的仓库都有效。比如下面的例子:

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

    @Override
    List<T> findAll();

}
vnjpjtjt

vnjpjtjt4#

从Spring Data 3开始,还有另一个选项:ListCrudRepository .
这篇博客文章讨论了为什么CrudRepository选择Iterable而不是List
https://spring.io/blog/2022/02/22/announcing-listcrudrepository-friends-for-spring-data-3-0

gg58donl

gg58donl5#

你好,我知道我迟到了,但是如果你想把一个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;希望对你有所帮助

mwkjh3gx

mwkjh3gx6#

简单地说,你可以让你的仓库扩展JpaRepository而不是CrudRepository,这会很好地工作,这里findAll返回一个List而不是Iterable。

相关问题