Mệnh đề JPQL IN: Java-Mảng (hoặc Danh sách, Bộ…)?


108

Tôi muốn tải tất cả các đối tượng có thẻ văn bản được đặt thành bất kỳ số lượng giá trị nhỏ nhưng tùy ý nào từ cơ sở dữ liệu của chúng tôi. Cách hợp lý để thực hiện điều này trong SQL là xây dựng một mệnh đề "IN". JPQL cho phép IN, nhưng có vẻ như yêu cầu tôi chỉ định trực tiếp mọi tham số đơn lẻ cho IN (như trong, "in (: in1,: in2,: in3)").

Có cách nào để chỉ định một mảng hoặc một danh sách (hoặc một số vùng chứa khác) cần được hủy cuộn vào các giá trị của mệnh đề IN không?

Câu trả lời:


208

Tôi không chắc cho JPA 1.0 nhưng bạn có thể vượt qua điểm Collectiontrong JPA 2.0:

String qlString = "select item from Item item where item.name IN :names"; 
Query q = em.createQuery(qlString, Item.class);

List<String> names = Arrays.asList("foo", "bar");

q.setParameter("names", names);
List<Item> actual = q.getResultList();

assertNotNull(actual);
assertEquals(2, actual.size());

Đã kiểm tra với EclipseLInk. Với Hibernate 3.5.1, bạn sẽ cần đặt tham số trong dấu ngoặc đơn:

String qlString = "select item from Item item where item.name IN (:names)";

Nhưng đây là một lỗi, truy vấn JPQL trong mẫu trước là JPQL hợp lệ. Xem HHH-5126 .


5
có số lượng tên tối đa để sử dụng trong "trong mệnh đề" không?
Gondim

3
Lỗi nói trên trong Hibernate dường như được cố định trong phiên bản 3.6.1
Denis Kniazhev

1
@pringlesinn số các giá trị trong một IN-khoản phụ thuộc vào DBMS của bạn
Tim Buthe

làm việc tại JPA 1.0 (và vòm không bắt buộc của nó với dấu ngoặc đơn, nhưng để có thể đọc bạn nên)
Javier Larios

điều gì sẽ xảy ra nếu bạn muốn => item.name trong (như: tên)
dzgeek

3

Giới hạn oracle là 1000 tham số. Sự cố đã được giải quyết bằng chế độ ngủ đông trong phiên bản 4.1.7 mặc dù bằng cách tách danh sách tham số đã truyền thành bộ 500, hãy xem JIRA HHH-1123


1
Thật không may, điều này đã không được giải quyết. Vé được đánh dấu là đã được giải quyết, nhưng vấn đề (như được hiển thị trong các nhận xét) không được nhóm Hibernate khắc phục.
Druckles

@Druckles ừm ở đâu? Tôi không thấy bất kỳ bình luận nào cũ hơn năm 2016. Và đó chỉ là hai bình luận thực tế không có gì khác ngoài internet thông thường 'help plz !!! 11 !!!!'. Bạn không có lý do gì để tin tưởng rằng báo cáo lỗi đã được giải quyết.
searchhengine27

@ searchhengine27 Tôi cho biết báo cáo chưa được giải quyết, mặc dù nó được đánh dấu là đã giải quyết. Theo báo cáo của Steve Ebersole, giải pháp là: "Giải pháp cho vấn đề này là chúng tôi chỉ đơn giản là sẽ cảnh báo người dùng thông qua việc ghi nhật ký khi tình trạng này được phát hiện." Các ý kiến ​​của Noel Trout vào năm 2012 mở rộng về lý do tại sao điều này là không đủ.
Druckles

Nói cách khác, câu trả lời này sai hoặc tốt nhất là gây hiểu lầm.
Druckles
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.