2013-03-14 31 views
7

Có thể viết truy vấn này như là một typedQuery và để cho hai của Long chạy vào một đối tượng với hai trường công khai dài bên trong.TypedQuery thay vì truy vấn bình thường trong JPA

Query q = em.createQuery(
      "SELECT c.id, COUNT(t.id) " + 
      "FROM PubText t " + 
      "JOIN t.comm c " + 
      "WHERE c.element = ?1 " + 
      "GROUP BY c.id"); 
    q.setParameter(1, e); 
    List<?> rl = q.getResultList(); 
    Iterator<?> it = rl.iterator(); 
    HashMap<Long, Long> res = new HashMap<Long, Long>(); 
    while (it.hasNext()) { 
     Object[] n = (Object[]) it.next(); 
     res.put((Long)n[0], (Long)n[1]); 
    } 
    return res; 

Trả lời

12

JPA có một tính năng chỉ cho điều này - biểu constructor:

Query q = entityManager.createQuery("SELECT NEW com.example.DTO(c.id, COUNT(t.id)) FROM ..."); 
List<DTO> dtos = q.getResultList(); 

lớp DTO của bạn có thể là một POJO. Tất cả những gì nó cần là một nhà xây dựng công cộng chấp nhận 2 Long s. Xin lưu ý rằng bạn phải cung cấp tên đầy đủ của lớp học của bạn sau khi nhà điều hành NEW.

+0

hi @kostja Tôi gặp lỗi (Không thể tạo TypedQuery cho truy vấn có nhiều lần trả lại). SQL của tôi trông như thế này: 'SELECT NEW com.company.ui.EntityIDKey (c.companyId, c.name) FROM Công ty c WHERE c.companyId không phải là null và c.name không phải là null và length (trim (c.name))> 0 thứ tự của c.name asc'. Tôi đang sử dụng một TypedQuery như sau: 'List companies = getEntityManager(). CreateQuery (sql, EntityIDKey.class) .getResultList();' –

+1

điều này có thể là trường hợp nếu EntityIDKey của bạn không phải là một thực thể. Nhà cung cấp miễn phí không hỗ trợ các truy vấn như vậy. Bạn đã thử sử dụng Truy vấn thông thường chưa? – kostja

+0

đúng, 'EntityIDKey' không phải là một thực thể. Tôi đang sử dụng nhà cung cấp Hibernate và bằng cách nào đó giả sử nó sẽ hoạt động. Truy vấn thông thường xây dựng bộ sưu tập 'Công việc' hoạt động tốt. –

8

Mã mới trông như thế này ngay bây giờ. Cảm ơn sự giúp đỡ của bạn.

TypedQuery<CommUsed> q = em.createQuery(
     "SELECT new CommUsed(c.id,COUNT(t.id)) " + 
     "FROM PubText t " + 
     "JOIN t.comm c " + 
     "WHERE c.element = ?1 " + 
     "GROUP BY c.id", CommUsed.class); 
    q.setParameter(1, e); 
    HashMap<Long, Long> res = new HashMap<Long, Long>(); 
    for (CommUsed u : q.getResultList()) 
     res.put(u.commID, u.cnt); 
+0

Tôi thấy, vì vậy bạn có thể sử dụng TypedQueries sau khi tất cả :) tốt để biết. Thật không may có vẻ như không có cách nào hợp lý để điền vào một 'Bản đồ' ngay từ truy vấn, vì vậy phần chuyển đổi trong 3 dòng cuối cùng phải ở lại, tôi sợ. – kostja

+1

Ach, được rồi. Chúng tôi không cần phải nhấn tất cả mọi thứ vào một dòng như trong C ngày cũ. :-) –

+0

@HasanTuncay tại sao bạn không tận dụng tính năng biểu hiện hàm tạo được đề xuất bởi @kostja? –

Các vấn đề liên quan