JPA, диспетчер сущностей, выберите много столбцов и получите список пользовательских объектов списка результатов
Как я могу получить список пользовательских объектов, например, результаты ниже запроса:
SELECT p.category.id, count(p.id) FROM Product p left join p.category c WHERE p.seller.id=:id GROUP BY c.id
Пример:
return getEntityManager().createQuery("SELECT p.category.id, count(p.id) FROM Product p left join p.category c WHERE p.seller.id=:id GROUP BY c.id").setParameter("id", id).getResultList();
Мне нужна карта с идентификатором категории и количеством продуктов в категории.
Ответы
Ответ 1
К сожалению, JPA не предоставляет стандартный способ получения результатов в Map
. Однако создать карту вручную, пройдя через список результатов, достаточно просто:
TypedQuery<Object[]> q = getEntityManager().createQuery(
"SELECT c.id, count(p.id) " +
"FROM Product p LEFT JOIN p.category c " +
"WHERE p.seller.id = :id " +
"GROUP BY c.id", Object[].class).setParameter("id", id);
List<Object[]> resultList = q.getResultList();
Map<String, Long> resultMap = new HashMap<String, Long>(resultList.size());
for (Object[] result : resultList)
resultMap.put((String)result[0], (Long)result[1]);
Ответ 2
Предполагая, что вы используете hibernate (tagged), можете попробовать нижний запрос HQL, я не тестировал.
SELECT new map(p.category.id as category_id, count(p.id) as id_count) FROM Product p left join p.category c WHERE p.seller.id=:id GROUP BY c.id
Ответ 3
Использование JPA 2.0 и EclipseLink impl
Для первого вопроса: список пользовательских объектов (без объектов таблицы):
answer: создать пользовательскую модель и использовать @Entity и @Id
@Entity
public class QueryModelDTO implements Serializable{
@Id
private Integer categoryId;
private int count;
---gets and sets
}
создать запрос и выполнить
QueryModelDTO qm = (QueryModelDTO) em.createQuery(
"SELECT p.category.id as categoryId, count(p.id) as count FROM Product p
left join p.category c WHERE p.seller.id=:id
GROUP BY c.id",QueryModelDTO.class)
.setParameter("id", id).getSingleResult();
Для второго: как прочитать ответ на карте
answer: Используйте QueryHints и ResultTypes (это один из вариантов ответа @DannyMo)
Query q = em.createNativeQuery("SELECT * FROM Foo f");
q.setHint(QueryHints.RESULT_TYPE, ResultType.Map);
List<Map> lm = q.getResultList();
for (Map map : lm) {
for (Object entry : map.entrySet()) {
Map.Entry<DatabaseField, Object> e = (Map.Entry<DatabaseField, Object>) entry;
DatabaseField key = e.getKey();
Object value = e.getValue();
log.debug(key+"="+value);
}
}
Я надеюсь, что это поможет