Thêm danh sách mệnh đề IN vào một truy vấn JPA


125

Tôi đã xây dựng một NamedQuery trông giống như sau:

@NamedQuery(name = "EventLog.viewDatesInclude",
        query = "SELECT el FROM EventLog el WHERE el.timeMark >= :dateFrom AND "
        + "el.timeMark <= :dateTo AND "
        + "el.name IN (:inclList)")

Những gì tôi muốn làm là điền vào tham số: inclList với danh sách các mục thay vì một mục. Ví dụ: nếu tôi có một new List<String>() { "a", "b", "c" }cách làm thế nào để tôi nhận được điều đó trong tham số: inclList? Nó chỉ cho phép tôi mã hóa một chuỗi. Ví dụ:

setParameter("inclList", "a") // works

setParameter("inclList", "a, b") // does not work

setParameter("inclList", "'a', 'b'") // does not work

setParameter("inclList", list) // throws an exception

Tôi biết tôi chỉ có thể xây dựng một chuỗi và tạo toàn bộ Truy vấn từ đó, nhưng tôi muốn tránh chi phí. Có cách nào tốt hơn để làm điều này không?

Câu hỏi liên quan: nếu Danh sách rất lớn, có cách nào tốt để xây dựng truy vấn như vậy không?


Đây là bản sao của stackoverflow.com/questions/1557085/… nhưng chủ đề này cung cấp các câu trả lời hữu ích.
Mike Ryan

Câu trả lời:


181

Khi sử dụng INvới tham số có giá trị tập hợp, bạn không cần (...):

@NamedQuery(name = "EventLog.viewDatesInclude", 
    query = "SELECT el FROM EventLog el WHERE el.timeMark >= :dateFrom AND " 
    + "el.timeMark <= :dateTo AND " 
    + "el.name IN :inclList") 

6
Không ... tôi trường hợp của tôi ngược lại. Nếu tôi sử dụng: inclList thì nó không hoạt động. Nếu tôi sử dụng IN (: inclList) thì nó hoạt động.
Gunjan Shah,

1
Cũng lưu ý đề cập: loại tham số của bạn phải là một tập hợp (không phải một mảng) các đối tượng. Các đối tượng phải phù hợp với loại trường. ToString () là không thay thế cho lớp String
Dube

2
Tôi nghĩ rằng đây là một cái gì đó đã thay đổi với các phiên bản của Hibernate, theo như tôi có thể nhớ, tôi đã gặp lỗi khi không có dấu ngoặc đơn xung quanh biến khi sử dụng IN. Thật lạ nếu nó không tương thích ngược ..
Tobb

1
Đây thực sự là một lỗi ngủ đông (cần có dấu ngoặc đơn) đã được sửa trong 3.6.1
Mat

1
Đối với câu hỏi liên quan: Trong trường hợp danh sách rất lớn, có thể có những hạn chế cho việc thực hiện. Vd: 11g oracle. tối đa 1000 phần tử danh sách là tham số có thể. Một cách giải quyết là cắt danh sách trong Danh sách con và thu thập kết quả. Bản thân JPA không hạn chế kích thước danh sách.
Mahttias Schrebiér

81

Định dạng truy vấn JPA thích hợp sẽ là:

el.name IN :inclList

Nếu bạn đang sử dụng phiên bản Hibernate cũ hơn làm nhà cung cấp của mình, bạn phải viết:

el.name IN (:inclList)

nhưng đó là một lỗi ( HHH-5126 ) (EDIT: hiện đã được giải quyết).


5
Cảm ơn bạn đã phân biệt các phiên bản cũ của Hibernate sử dụng ()
Rob L

31
public List<DealInfo> getDealInfos(List<String> dealIds) {
        String queryStr = "SELECT NEW com.admin.entity.DealInfo(deal.url, deal.url, deal.url, deal.url, deal.price, deal.value) " + "FROM Deal AS deal where deal.id in :inclList";
        TypedQuery<DealInfo> query = em.createQuery(queryStr, DealInfo.class);
        query.setParameter("inclList", dealIds);
        return query.getResultList();
    }

Làm việc cho tôi với JPA 2, Jboss 7.0.2


9

Bạn phải chuyển đổi thành Listnhư hình dưới đây:

    String[] valores = hierarquia.split(".");       
    List<String> lista =  Arrays.asList(valores);

    String jpqlQuery = "SELECT a " +
            "FROM AcessoScr a " +
            "WHERE a.scr IN :param ";

    Query query = getEntityManager().createQuery(jpqlQuery, AcessoScr.class);                   
    query.setParameter("param", lista);     
    List<AcessoScr> acessos = query.getResultList();

Thx câu trả lời này đã giúp tôi
cabaji99
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.