2013-05-07 33 views
31

Tôi đang sử dụng JPA dữ liệu mùa xuân trong dự án của mình. Tôi đang chơi với hàng triệu bản ghi. Tôi có một yêu cầu mà tôi phải lấy dữ liệu cho các bảng khác nhau và xây dựng một đối tượng và sau đó vẽ nó trên một giao diện người dùng. Bây giờ làm thế nào để đạt được điều này kho dữ liệu mùa xuân của tôi. Tôi đã đọc rằng nó có thể đạt được bằng cách đặt tên truy vấn gốc.JPA dữ liệu mùa xuân: Làm thế nào để truy vấn trả về đối tượng không phải đối tượng hoặc danh sách đối tượng?

Nếu truy vấn nguồn gốc tên không trả lại một thực thể hoặc một danh sách các thực thể , chúng ta có thể lập bản đồ các kết quả truy vấn đến một kiểu trả về chính xác bằng cách sử dụng chú thích @SqlResultSetMapping.

Nhưng khi tôi đang cố gắng sử dụng @SqlResultSetMapping nó được tham gia một entityResult. Có nghĩa là những gì tôi hiểu là nó chỉ là chuyển đổi một số kết quả truy vấn để tập kết quả thực thể chỉ, nhưng tôi muốn có một tập kết quả của các đối tượng không thực thể.

@SqlResultSetMapping(
    name="studentPercentile", 
    entities={ 
     @EntityResult(
      entityClass=CustomStudent.class, 
       fields={ 
        @FieldResult(name="id", column="ID"), 
        @FieldResult(name="firstName", column="FIRST_NAME"), 
        @FieldResult(name="lastName", column="LAST_NAME") 
       }   
     ) 
    } 
) 
@NamedNativeQuery(
    name="findStudentPercentile", 
    query="SELECT * FROM STUDENT", 
    resultSetMapping="studentPercentile") 

Trong ví dụ trên tôi chỉ cố gắng để có được một kết quả từ sinh viên Entity vào một POJO 'CustomStudent' mà không phải là một thực thể. (Ví dụ này tôi đang cố gắng thực hiện chỉ cho mục đích POC, usecase thực tế là phức tạp, với truy vấn phức tạp trả về kết quả khác nhau).

Làm thế nào để đạt được trên usecase? Có cách nào khác ngoài việc sử dụng truy vấn tên mà phương thức kho lưu trữ của tôi trả về các đối tượng Non-Entities không?

+0

Tôi đã gặp vấn đề tương tự gần đây và vui mừng khi thấy ai đó đăng và nhận giải pháp cho nó! –

Trả lời

23

Tôi vô cùng ngạc nhiên khi lần đầu tiên vượt qua điều này nhưng, có, bạn có thể ánh xạ kết quả truy vấn bằng cách sử dụng @SqlResultSetMapping chỉ với vô hướng và các thực thể được quản lý.

Điều tốt nhất bạn có thể làm, tôi đoán, là bỏ qua ánh xạ tự động. Truy vấn không có ánh xạ sẽ trả lại List<Object[]> và bạn có thể ánh xạ nó theo cách bạn cần.

Một cách tiếp cận khác là sử dụng @MappedSuperclass. Lớp được ký hiệu là @MappedSuperclass (CustomStudent trong trường hợp của bạn) có thể (không chắc chắn 100%, mặc dù) được sử dụng trong @SqlResultSetMapping. nhưng bạn cần phải giới thiệu hệ thống phân cấp thừa kế, đó là thực thể Sinh viên của bạn phải mở rộng CustomStudent. Điều đó sẽ hút phần lớn thời gian từ việc thiết kế OO thích hợp, bởi vì thừa kế sẽ là một chút nhân tạo ...

+0

Bạn có nghĩa là các loại nguyên thủy? – Alex78191

+1

Bạn có thể sử dụng ConstructorResult https://stackoverflow.com/a/42942353/4854931 – Alex78191

21

Bạn có thể làm một cái gì đó giống như

@NamedQuery(name="findWhatever", query="SELECT new path.to.dto.MyDto(e.id, e.otherProperty) FROM Student e WHERE e.id = ?1") 

Sau đó, đối tượng MyDto sẽ chỉ cần một constructor định nghĩa với các trường chính xác tức là

public MyDto(String id, String otherProperty) { this.id = id; this.otherProperty = otherProperty; } 
+0

Tôi có thể viết một cái gì đó như 'SELECT new path.to.dto.MyDto (e.id, new path.to.dto.OtherDto)' – masSdev

+0

Không, nhưng trong MyDto bạn có thể có thuộc tính OtherDto và trong hàm tạo của MyDto, bạn có thể đặt thuộc tính OtherDto bằng cách sử dụng dữ liệu được truyền vào hàm tạo MyDto. Hoặc bạn có thể sử dụng chú thích @SqlResultSetMapping. – tlavarea

+0

Khi tôi viết điều này, biên dịch thất bại với 'Xác nhận không thành công cho truy vấn cho phương thức trừu tượng công khai..' –

17

Làm thế nào về JPA 2.1 ConstructorResult?

@SqlResultSetMapping(
    name="studentPercentile", 
    classes={ 
     @ConstructorResult(
      targetClass=CustomStudent.class, 
      columns={ 
       @ColumnResult(name="ID"), 
       @ColumnResult(name="FIRST_NAME"), 
       @ColumnResult(name="LAST_NAME") 
      } 
     ) 
    } 
) 

@NamedNativeQuery(name="findStudentPercentile", query="SELECT * FROM STUDENT", resultSetMapping="studentPercentile") 
+0

Xin chào, điều này nghe hay, nhưng NamedQuery vẫn phải được gắn vào và Thực thể là một phần của đơn vị bền vững? – romainbsl

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