2011-07-29 26 views
24

Tôi đang viết truy vấn JPQL tham gia trên ba bảng. Trong danh sách kết quả của tôi, tôi muốn có được tất cả ba thực thể cho mỗi hàng phù hợp (hy vọng có ý nghĩa).JPA: Truy vấn trả về nhiều thực thể

Bất kỳ ý tưởng nào?

Hibernate 3.x là nhà cung cấp JPA của tôi.

Trả lời

35

IIRC, bạn có thể thực hiện SELECT o1, o2, o3 FROM EntityA o1, EntityB o2, EntityC o3 WHERE .... và kết quả sẽ là List<Object[3]>, trong đó nội dung mảng sẽ chứa giá trị o1, o2, o3.

+6

@ John: Ngoài ra, bạn có thể gọi nhà xây dựng từ HQL, vì vậy bạn cũng có thể làm 'chọn new Foo (O1, O2, o3) ... 'và lấy Danh sách thay vì Danh sách . –

+3

Ok, nhưng nếu tôi muốn sử dụng một JPA TypedQuery: myEntityManager.createQuery ("chọn o1, o2 ...", ) – AgostinoX

+0

Điều gì sẽ xảy ra nếu bạn muốn sử dụng setFirstResult thực sự sẽ áp dụng cho nối của cả hai danh sách? tức là tôi muốn có thể trả về một danh sách được sắp xếp, đó là kết nối của kết quả cho hai thực thể được truy vấn. – Thomas

0

Vì bạn đang yêu cầu JPA: Query that returns multiple entities, EclipseLink cũng đi kèm theo nó. Và tôi đã đạt được câu hỏi này googling cho EclipseLink. Vì vậy, đây là giải pháp của tôi. Hi vọng nó sẽ giúp ích cho bạn.

TypedQuery<Object[]> query = entityManager.createQuery("select p from Post p where p.publisher.pubId= :ID order by p.createdAt desc", 
       Object[].class); 
query.setParameter("ID", publisherID); 

Sau đó, bạn có thể lặp qua các đối tượng kết quả và truyền chúng cho phù hợp.

for (Object result : query.getResultList()) { 
      myList.add((Post) result); 
     } 

Bạn cũng có thể thử loại này,

Query query = entityManager.createQuery("select p from Post p where p.publisher.pubId= :ID order by p.createdAt desc"); 

tham khảo: http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL

+0

nếu tôi cần lấy dữ liệu từ 2 thực thể nói nhà xuất bản và sách thì sao? – fiddle

16

Đây là một mẫu Xuân dữ liệu, tuy nhiên tác phẩm của mình theo cùng một cách trong JPA

//HQL query 
@Query("SELECT c,l,p,u FROM Course c, Lesson l, Progress p, User u " 
      + "WHERE c.id=l.courseId AND l.id = p.lessonId AND p.userId = u.id AND u.id=:userId AND c.id=:courseId") 
    public List<Object[]> getLessonsWithProgress(@Param("userId") Integer userId, @Param("courseId")Integer courseId); 

Sau đó, , Tôi gọi phương thức này và in kết quả:

List<Object[]> lst = courseRepository.getLessonsWithProgress(userId, courseId); 
for (Object o[] : lst) { 
    Course c = (Course) o[0]; 
    Lesson l = (Lesson) o[1]; 
    Progress p = (Progress) o[2]; 
    User u = (User) o[3]; 
    //all the classes: Course, Lesson, Progress and User have the toString() overridden with the database ID;  
    System.out.printf("\nUser: %s \n Lesson: %s \n Progress: %s \n Course: %s",u,l,p,c); 
} 

Các @Test ra là ở đây:

User: com.cassio.dao.model.User[ id=1965 ] 
Lesson: com.cassio.dao.model.Lesson[ id=109 ] 
Progress: com.cassio.dao.model.Progress[ id=10652 ] 
Course: com.cassio.dao.model.Course[ id=30 ] 

Cheers

+0

hi Cassion, nhưng những gì trong trường hợp tôi chỉ muốn chỉ Coursname, LessionID, ProgressID và username..then phải làm gì? cách xử lý dữ liệu danh sách.Bởi vì tại thời điểm đó hàng này không thể là trường hợp của bất kỳ lớp học –

+0

Hi Utkal, xem xét mã mẫu của tôi, Khóa học, Bài học, Tiến độ và Người dùng là các đối tượng. Bạn có thể nhận được String hoặc Integer mong muốn làm cho @Override trong phương thức toString() của mỗi lớp. Trong khi chờ đợi, thực hành tốt nhất cho trường hợp đó là thay đổi truy vấn HQL, thay vì nhận được Khóa học c, bạn có thể làm điều đó theo cách SELECT c.name, l.id, progress.id và u.firstname FROM ... Do đó bạn sẽ nhận được các chuỗi và số nguyên thay vì các đối tượng phức tạp. –

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