gpt4 book ai didi

dictionary - JPA 查询可以以 Java 映射的形式返回结果吗?

转载 作者:行者123 更新时间:2023-12-03 04:34:23 24 4
gpt4 key购买 nike

我们目前正在根据命名 JPA 查询返回的两个字段手动构建 Map,因为 JPA 2.1 仅提供 getResultList() 方法:

@NamedQuery{name="myQuery",query="select c.name, c.number from Client c"}

HashMap<Long,String> myMap = new HashMap<Long,String>();

for(Client c: em.createNamedQuery("myQuery").getResultList() ){
myMap.put(c.getNumber, c.getName);
}

但是,我觉得自定义映射器或类似工具的性能会更高,因为此列表很容易包含 30,000 多个结果。

任何无需手动迭代即可构建 map 的想法。

(我使用的是 OpenJPA,而不是 hibernate)

最佳答案

使用 JPA Query getResultStream 返回 Map 结果

从JPA 2.2版本开始,您可以使用getResultStream Query方法来转换List<Tuple>结果变成 Map<Integer, Integer> :

Map<Integer, Integer> postCountByYearMap = entityManager.createQuery("""
select
YEAR(p.createdOn) as year,
count(p) as postCount
from
Post p
group by
YEAR(p.createdOn)
""", Tuple.class)
.getResultStream()
.collect(
Collectors.toMap(
tuple -> ((Number) tuple.get("year")).intValue(),
tuple -> ((Number) tuple.get("postCount")).intValue()
)
);

使用 JPA Query getResultList 和 Java 流返回 Map 结果

如果您使用的是 JPA 2.1 或更早版本,但您的应用程序在 Java 8 或更高版本上运行,那么您可以使用 getResultList并转换List<Tuple>到 Java 8 流:

Map<Integer, Integer> postCountByYearMap = entityManager.createQuery("""
select
YEAR(p.createdOn) as year,
count(p) as postCount
from
Post p
group by
YEAR(p.createdOn)
""", Tuple.class)
.getResultList()
.stream()
.collect(
Collectors.toMap(
tuple -> ((Number) tuple.get("year")).intValue(),
tuple -> ((Number) tuple.get("postCount")).intValue()
)
);

使用 Hibernate 特定的 ResultTransformer 返回 Map 结果

另一个选项是使用 MapResultTransformer Hibernate Types 开源项目提供的类:

Map<Number, Number> postCountByYearMap = (Map<Number, Number>) entityManager.createQuery("""
select
YEAR(p.createdOn) as year,
count(p) as postCount
from
Post p
group by
YEAR(p.createdOn)
""")
.unwrap(org.hibernate.query.Query.class)
.setResultTransformer(
new MapResultTransformer<Number, Number>()
)
.getSingleResult();

MapResultTransformer 适用于仍在 Java 6 上运行或使用较旧 Hibernate 版本的项目。

避免返回大型结果集

OP 说:

But, I feel like a custom mapper or similar would be more performantsince this list could easily be 30,000+ results.

这是一个糟糕的主意。您永远不需要选择 30k 条记录。它如何适合用户界面?或者,为什么要对这么大批量的记录进行操作?

您应该使用查询分页,因为这将帮助您减少事务响应时间并提供更好的并发性。

关于dictionary - JPA 查询可以以 Java 映射的形式返回结果吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4371384/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com