jpa 如何使用CriteriaQuery以List〈Map〈String,Object>>的形式获取结果?

xnifntxz  于 2023-01-31  发布在  其他
关注(0)|答案(2)|浏览(260)

我有大约50列的大表,客户端将决定哪些是他想要的列。基于此,我需要给予数据。
使用javax.persistence.Query,我可以选择特定的列,如下所示:

String query = "Select new map (dataId as dataId, dataNumber as dataNumber) From Data";
Query q = entityManager.createQuery(query).setMaxResults(10);
List<Map<String, Object>> dataList = q.getResultList();

我想用CriteriaQuery实现相同的功能,我尝试了如下操作:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Data> cQuery = cb.createQuery(Data.class);
Root<Data> c = cQuery.from(Data.class);
cQuery.multiselect(c.get("dataId"), c.get("dataName"));
List<Data> t = entityManager.createQuery(cQuery).setMaxResults(10).getResultList();

对于上面的代码,其预期构造函数为“Data(dataId,dataName)"。
我想找到一种方法,使用CriteriaQuery从表中查询特定字段,而无需为选定字段编写构造函数。请帮助我完成此操作。

lyr7nygr

lyr7nygr1#

正如Hibernate User Guide中所述,在本例中使用map的动态示例化以及使用list的动态示例化是HQL中的附加特性,而不是JPQL的一部分。
Criteria API不提供构造此类选择的方法。

xmjla07d

xmjla07d2#

我认为您所要求的是可以使用普通JPA和Tuple的。

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Tuple> cQuery = cb.createQuery(Tuple.class);
Root<Data> c = cQuery.from(Data.class);
cQuery.multiselect(c.get("dataId"), c.get("dataName"));
List<Tuple> resultList = entityManager.createQuery(cQuery).setMaxResults(10).getResultList();

List<Map<String, Object>> listOfMaps = resultList
   .stream()
   .map(tuple -> tuple.getElements()
                      .stream()
                      .map(element -> Map.entry(element.getAlias(), tuple.get(element.getAlias())))
                      .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)))
   .collect(Collectors.toList());

现在您应该能够在multiselect()中传递您喜欢的字段。
当你有连接和聚合或者更复杂的查询时,你必须小心一点,它并不总是有效。

相关问题