2012-12-04 32 views
19

Tôi đang tạo một truy vấn phức tạp với nhiều bảng và cần liệt kê kết quả. Thông thường, tôi đang sử dụng EntityManager và bản đồ kết quả cho JPA-Đại diện:JPA Query.getResultList() - sử dụng theo cách chung chung

UserEntity user = em.find(UserEntity.class, "5"); 

Sau đó, tôi có thể truy cập vào tất cả các giá trị như là người dùng UserEntity lớp định nghĩa nó. Nhưng làm cách nào tôi có thể truy cập vào trường-giá trị được trả lại từ truy vấn nhiều bảng gốc? Những gì tôi nhận được là một danh sách các đối tượng. Đó là tốt cho đến nay, nhưng những gì "là" mà đối tượng? Mảng? Bản đồ? Bộ sưu tập? ...

//simpleExample 
Query query = em.createNativeQuery("SELECT u.name,s.something FROM user u, someTable s WHERE s.user_id = u.id"); 
List list = query.getResultList(); 

//do sth. with the list, for example access "something" for every result row. 

Tôi đoán câu trả lời khá đơn giản, nhưng hầu hết các ví dụ chỉ hiển thị mức sử dụng khi trực tiếp truyền tới targetClass.

PS: Trong ví dụ, tôi có thể sử dụng ánh xạ lớp học của khóa học. Nhưng trong trường hợp của tôi someTable không được quản lý bởi JPA, và do đó tôi không có thực thể cũng như tôi có một lớp đại diện của nó, và kể từ khi tôi tham gia như 20 bảng, tôi không muốn tạo tất cả các lớp học chỉ để truy cập các giá trị.

Trả lời

47

Nguyên tắc chung là như sau:

  • Nếu select chứa biểu thức duy nhất và đó là một thực thể, sau đó kết quả được rằng thực thể
  • Nếu select chứa biểu thức duy nhất và đó là một nguyên thủy, sau đó kết quả là nguyên thủy
  • Nếu select chứa nhiều biểu thức, thì kết quả là Object[] chứa các nguyên thủy/thực thể tương ứng

Vì vậy, trong trường hợp của bạn listList<Object[]>.

8

Truy vấn trên trả về danh sách đối tượng []. Vì vậy, nếu bạn muốn lấy u.name và s.something từ danh sách thì bạn cần lặp lại và truyền các giá trị đó cho các lớp tương ứng.

+1

Vì vậy, tôi cho rằng 'danh sách [x] .object [0] 'là giá trị đầu tiên (u.name) và' danh sách [x] .object [ 1] 'là thứ hai (s.something) - vì vậy không có quyền truy cập' assoc'? – dognose

+0

Nếu bạn chỉ in ra đối tượng [i] và tất cả nguyên thủy và ngày/giờ phải được in ở định dạng mặc định của chúng. –

+0

@ MGPJ Bạn có thể lập phương án trả lời bằng một ví dụ – Reenu

24

Kể từ khi JPA 2,0 một TypedQuery thể được sử dụng:

TypedQuery<SimpleEntity> q = 
     em.createQuery("select t from SimpleEntity t", SimpleEntity.class); 

List<SimpleEntity> listOfSimpleEntities = q.getResultList(); 
for (SimpleEntity entity : listOfSimpleEntities) { 
    // do something useful with entity; 
} 
5

Nếu bạn cần một cách thuận tiện hơn để truy cập vào các kết quả, nó có thể thay đổi kết quả của một truy vấn SQL tùy tiện phức tạp để một lớp Java với tối thiểu rắc rối:

Query query = em.createNativeQuery("select 42 as age, 'Bob' as name from dual", 
     MyTest.class); 
MyTest myTest = (MyTest) query.getResultList().get(0); 
assertEquals("Bob", myTest.name); 

Lớp cần được khai báo là @Tốc độ, có nghĩa là bạn phải đảm bảo rằng lớp đó có @Id duy nhất.

@Entity 
class MyTest { 
    @Id String name; 
    int age; 
} 
0

Đây là mẫu về những gì hiệu quả đối với tôi. Tôi nghĩ rằng phương thức put là cần thiết trong lớp thực thể để ánh xạ các cột sql vào các thuộc tính lớp java.

//simpleExample 
    Query query = em.createNativeQuery(
"SELECT u.name,s.something FROM user u, someTable s WHERE s.user_id = u.id", 
NameSomething.class); 
    List list = (List<NameSomething.class>) query.getResultList(); 

Entity lớp:

@Entity 
    public class NameSomething { 

     @Id 
     private String name; 

     private String something; 

     // getters/setters 



     /** 
     * Generic put method to map JPA native Query to this object. 
     * 
     * @param column 
     * @param value 
     */ 
     public void put(Object column, Object value) { 
      if (((String) column).equals("name")) { 
       setName(String) value); 
      } else if (((String) column).equals("something")) { 
       setSomething((String) value); 
      } 
     } 
    } 
Các vấn đề liên quan