弹簧数据 jpa。返回 Map 作为分组操作的结果
Posted
技术标签:
【中文标题】弹簧数据 jpa。返回 Map 作为分组操作的结果【英文标题】:Spring data jpa. Return Map as result of group by operation 【发布时间】:2015-09-10 08:35:55 【问题描述】:我的 jpa 存储库界面中有一个查询。
@Query("select e.campaignId, e from CampaignCrTargetingProfile e where e.campaignId in :ids group by e.campaignId")
public Map<Integer, List<CampaignCrTargetingProfile>> findByCampaignIdIn(@Param("ids") Iterable<Integer> ids);
campaignId 是整数。
但是当我尝试执行这个查询时,我发现了一个异常。
Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type java.lang.Integer to type java.util.Map<?, ?>
at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:311) ~[spring-core-4.1.5.RELEASE.jar:4.1.5.RELEASE]
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:192) ~[spring-core-4.1.5.RELEASE.jar:4.1.5.RELEASE]
at org.springframework.core.convert.support.ArrayToObjectConverter.convert(ArrayToObjectConverter.java:66) ~[spring-core-4.1.5.RELEASE.jar:4.1.5.RELEASE]
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:35) ~[spring-core-4.1.5.RELEASE.jar:4.1.5.RELEASE]
... 192 common frames omitted
是否可以通过其字段摸索实体并将结果作为地图返回?如果不可能,有没有其他方法可以制作类似的东西?
【问题讨论】:
您的查询中没有任何内容可以分组,没有计算等。所以不确定您是否理解分组... @M.Deinum。抱歉,我的查询有误,我已更改。 @M.Deinum 我想按campaignId 检索实体并制作地图,其中键是campaignId 值,值是实体列表。 这不是分组的工作原理...例如,您可以根据计数或总和进行分组。在您的情况下,只需返回一个 List 并处理它以供以后映射。这是我怀疑的最简单的方法。 ***.com/questions/12076238/… 【参考方案1】:您可以从 JPQL 查询中获取列表,然后使用 Java 8 Stream API 将其转换为映射。
// This method in your Repository interface
@Query("SELECT e FROM CampaignCrTargetingProfile e WHERE e.campaignId IN :ids")
public List<CampaignCrTargetingProfile findByCampaignIdIn(@Param("ids") Iterable<Integer> ids);
// This source from your Service class
List<CampaignCrTargetingProfile> list = repo.findByCampaignIdIn(iterableArg);
Map<Integer, List<CampaignCrTargetingProfile>> mapResult = list.stream()
.collect(Collectors.groupingBy(CampaignCrTargetingProfile::getCampaignId));
最好让 DBMS 准备 GROUP BY 操作,但为了获得 Map 作为结果,上述代码只需一行代码即可使用 Java 8 Stream API 准备它。 据我所知,spring data 不支持 Map 的结果类型。 它效率低下,但我建议它用于小型数据集。
重要
我建议仅在您的数据集包含少量条目并且您绝对确定该数量在未来不会增长时使用此解决方案,例如。当您使用分页来限制您的结果集或枚举值表时,因为正如@adamwilliams 评论的那样,应用程序在内存中进行分组是低效的。
【讨论】:
这是低效的,分组是由应用程序而不是数据库引擎在内存中完成的。 你是对的,它只建议用于小数据集。如果您的要求是分组,比如说 20.000 行,那么最好让 DBMS 来完成这项工作。以上是关于弹簧数据 jpa。返回 Map 作为分组操作的结果的主要内容,如果未能解决你的问题,请参考以下文章