spring data jpa 能不能只返回一个字段的值,而不是整个对象

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring data jpa 能不能只返回一个字段的值,而不是整个对象相关的知识,希望对你有一定的参考价值。

参考技术A 你用all() 返回的是一个对象列表。这样的 [obj1, obj2, ...] 使用 obj.objects.get(id=**) 这样得到的是一个对象, 或者使用 get_object_or_404(obj, id=**) 这样的话, 使用 obj.objects.get(id=**).属性名 既可以了 或者 for obj in obj.objec...本回答被提问者采纳

Spring Data:JPA 存储库 findAll() 返回 *Map 而不是 List?

【中文标题】Spring Data:JPA 存储库 findAll() 返回 *Map 而不是 List?【英文标题】:Spring Data: JPA repository findAll() to return *Map instead of List? 【发布时间】:2017-06-12 01:57:10 【问题描述】:

我有一个 Spring Data JPA 存储库接口,看起来像这样:

@Repository
public interface DBReportRepository extends JpaRepository<TransactionModel, Long> 

    List<TransactionModel> findAll();
    List<TransactionModel> findByClientId(Long id);

除了要返回HashMap&lt;K, V&gt; 类型的集合之外,是否有解决方法可以做到这一点?我查看了 Spring Data 类,除了 List 返回值之外找不到任何东西。

【问题讨论】:

没有,是什么阻止你自己做? @isah 你的意思是自己为spring数据创建这样一个函数? 为自己创建这样一个函数我的意思是,无论你在哪里调用这个存储库,在加载列表后,你都可以使用 Java 8 单线将其映射到 Map Map is not a supported return type for Spring Data repository methods 所以下面@Patrick 的回答是正确的解决方案。 @DenissM.迭代会导致线性时间复杂度,反正你会得到,如果你需要访问每个项目,所以这不是问题:en.wikipedia.org/wiki/Time_complexity 【参考方案1】:

我认为您不会找到更简单的解决方案,即创建一个简单的单行线来将您的结果转换为地图。使用 java 8 lambdas 既简单又快速:

Map<Long, Transaction> transactionMap = transactionList.stream()
         .collect(Collectors.toMap(Transaction::getId, Function.identity()));

【讨论】:

【参考方案2】:

只需要解决类似的问题,帕特里克的回答有所帮助,但可以通过指出添加位置来改进它。

为了使它看起来像 JPA 存储库返回一个映射,改进方法是将其包装在存储库接口中的默认方法中。无需在所有消费类中执行流。

@Repository
public interface DBReportRepository extends JpaRepository<TransactionModel, Long> 

    List<TransactionModel> findAll();

    default Map<Long, TransactionModel> findAllMap() 
        return findAll().stream().collect(Collectors.toMap(TransactionModel::getId, v -> v));
    

    List<TransactionModel> findByClientId(Long id);

    default Map<Long, TransactionModel> findByClientIdMap(Long id) 
        return findByClientId(id).stream().collect(Collectors.toMap(TransactionModel::getId, v -> v));
    

【讨论】:

虽然我认为使用流将列表转换为地图的方法是一种简单而体面的方法,但它不属于存储库。存储库用于 CRUD 和查找器。转换是业务逻辑;因此,它属于服务代码,而不是存储库代码。作为软件开发人员,我们需要练习适当的关注点分离。【参考方案3】:

另一种解决方案使用 java 8 lambdas:

使用 Collectors 的 groupingBy 方法,按 ID 对 transactionList 进行分组并将结果存储在 Map 实例中

Map<Long, Transaction> transactionMap = transactionList.stream().collect(Collectors.groupingBy(v->v.getId()));

【讨论】:

另一种解决方案如何?即使这不起作用,您是否对此进行了测试? 当然,我测试过了。但是您无法实现直接在存储库中返回地图的方法。您需要在返回 List 的存储库类中实现该方法,然后获取此列表并将其转换为地图(使用上述代码) 不,你没有测试它。至少不是您发布为返回类型 Map 的版本甚至都不正确。

以上是关于spring data jpa 能不能只返回一个字段的值,而不是整个对象的主要内容,如果未能解决你的问题,请参考以下文章

spring data jpa 能不能只返回一个字段的值,而不是整个对象

Spring Data JPA 查询结果返回至自定义实体

处理 JPA 规范和 spring-data-jpa 时如何使用声明 Stream 作为返回类型

Spring Data JPA 查询从一个连接表中选择所有值

Spring data jpa JavassistLazyInitializer 不仅是Json序列化问题.以及解决办法

Spring Data JPA 获取列表始终返回至少一个结果