2017-06-16 33 views
5

xem xét truy vấn tầm thường này:Hibernate: Tìm nạp các cột với bí danh của họ

SELECT 1 as first, 2 as second

Khi sử dụng Hibernate sau đó chúng ta có thể làm điều gì đó như:

em.createNativeQuery(query).fetchResultList()

Tuy nhiên, có vẻ như là không có cách nhận các bí danh (hoặc tên cột). Điều này sẽ rất hữu ích khi tạo List<Map<String, Object>> trong đó mỗi bản đồ sẽ là một hàng với bí danh của họ, ví dụ trong trường hợp này: [{first: 1, second: 2}].

Có cách nào để làm điều gì đó như vậy không?

Trả lời

1

Bạn có thể sử dụng giao diện ResultTransformer. Triển khai trình ánh xạ tùy chỉnh để ánh xạ các giá trị bằng bí danh. đây là ví dụ https://vladmihalcea.com/why-you-should-use-the-hibernate-resulttransformer-to-customize-result-set-mappings/

với ResultTransformer bạn dễ dàng có thể tùy chỉnh loại kết quả thiết lập, đặc biệt là nếu bạn cần bí danh

+0

Bài viết thực sự thực sự hữu ích - trước đây tôi đã cố sử dụng 'ResultTransformer' không có hiệu lực. Chính xác những gì tôi cần. –

+0

Có thể bạn có thể trợ giúp với điều này: https://stackoverflow.com/questions/44585825/correct-cast-in-resulttransformer –

+0

Sử dụng các đối tượng bọc không phải là nguyên thủy. Bạn sử dụng db nào? Oracle, mysql, postgressql ... có thể có vấn đề với một số loại – xyz

2

tôi sẽ đề nghị một cách tiếp cận chút khác nhau mà có thể đáp ứng nhu cầu của bạn.

Trong JPA 2.1, có một tính năng được gọi là "lập bản đồ kết quả".

Về cơ bản bạn phải xác định một lớp POJO mà sẽ giữ các giá trị kết quả (tất cả các giá trị phải được thông qua bằng cách sử dụng constructor):

public class ResultClass{ 

    private String fieldOne; 
    private String fieldTwo; 

    public ResultClass(String fieldOne, String fieldTwo){ 
     this.fieldOne = fieldOne; 
     this.fieldTwo = fieldTwo; 
    } 
} 

Sau đó, bạn phải khai báo ánh xạ vào một trong các đơn vị của bạn (không quan trọng mà trên đó, nó chỉ có thể là một @Entity declated):

@SqlResultSetMapping(name="ResultMapping", classes = { 
    @ConstructorResult(targetClass = ResultClass.class, 
    columns = {@ColumnResult(name="columnOne"), @ColumnResult(name="columnTwo")}) 
}) 

các columnOnecolumnTwo là bí danh khi được công bố trong mệnh đề select của truy vấn nguồn gốc.

Và cuối cùng sử dụng trong việc tạo ra truy vấn:

List<ResultClass> results = em.createNativeQuery(query, "ResultMapping").getResultList(); 

Theo tôi đây là thanh lịch hơn và "mức trên" Giải pháp là bạn không phải làm việc với một chìa khóa Map generic/giá trị cặp nhưng với một bê tông Lớp POJO.

+0

Điều tôi không thích là tôi phải đặt tên cho các cột ở nhiều vị trí hơn: 1. Trong lớp, trong ánh xạ và trong truy vấn. Thành thật mà nói tôi muốn tránh ánh xạ để nó sẽ được ánh xạ trực tiếp bởi các bí danh trên lớp. Ngoài ra tôi không thích thực tế, rằng '@ SqlResultSetMapping' phải được chú thích trên lớp hoàn toàn khác. Điều gì có vẻ với tôi thú vị là 'AliasToBeanConstructorResultTransformer', nhưng nó chỉ có sẵn cho các truy vấn tiêu chí. –

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