2013-06-19 15 views
14

我怎樣才能獲得自定義對象的名單,像下面的查詢結果: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(); 

我需要具有類別ID和類別中的產品數量的地圖。

+0

我推薦看看[這個答案](http://stackoverflow.com/a/12702437/1211174)。這個答案有兩個例子1.使用元組2.使用類和泛型 – oak

回答

33

不幸的是,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]); 
+0

謝謝,這個工程! –

3

假設你正在使用Hibernate(標籤),可以試試下面的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

+1

我剛剛用自己測試過的自定義對象創建自定義連接查詢,它的工作。我有一個包含鍵而不是數字索引的對象列表。訂單沒有保留,但這並不重要,因爲我們已經命名索引來抓取...... –

-1

使用JPA 2.0和EclipseLink的IMPL

對於第一個問題:自定義對象(無表對象)的列表:

答案:創建一個自定義模式,並使用@實體和@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(); 

對於第二:如何看地圖上的響應

答案:使用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); 
     }    
    } 

我希望這可以幫助