2010-03-15 34 views
17

Có cách nào để chỉ định tham số tùy chọn (chẳng hạn như khi tham số tìm kiếm được cung cấp từ biểu mẫu và không phải tất cả tham số được yêu cầu) trong truy vấn được đặt tên khi sử dụng Hibernate? Tôi đang sử dụng một truy vấn SQL tự nhiên, nhưng câu hỏi có thể áp dụng cho các truy vấn HQL được đặt tên là tốt.Tham số tùy chọn với truy vấn được đặt tên trong Hibernate?

Tôi khá chắc chắn câu trả lời cho điều này là 'không', nhưng tôi chưa tìm thấy câu trả lời cuối cùng trong tài liệu.

Trả lời

10

AFAIK, không có thứ gì để bạn phải viết truy vấn động cho việc này. Có thể có một cái nhìn tại đây previous answer cho thấy làm thế nào để làm điều này trong HQL (mà bạn có thể chuyển sang SQL) và cũng cho thấy cách API tiêu chí làm cho nó đơn giản và do đó phù hợp hơn cho công việc này theo ý kiến ​​của tôi.

Cập nhật: (trả lời nhận xét từ OP) Làm việc với cơ sở dữ liệu cũ có thể thực sự phức tạp với Hibernate. Có thể bạn có thể sử dụng truy vấn gốc động và trả lại non-managed entities. Nhưng về lâu dài, mọi thứ có thể tồi tệ hơn (tôi không thể nói điều đó cho bạn). Có lẽ Hibernate không phải là lựa chọn tốt nhất trong trường hợp của bạn và một cái gì đó như iBATIS sẽ cung cấp cho bạn sự linh hoạt mà bạn cần.

+0

Cảm ơn. Đó là khá nhiều những gì tôi figured. Tôi quen thuộc với cả hai cách tiếp cận mà bạn đã đề xuất trong câu trả lời khác của bạn, nhưng tôi bị mắc kẹt với một lược đồ db di sản ác mộng mà không phù hợp với cách tiếp cận Hibernate cho trường hợp cụ thể của tôi. Tôi đã làm cho nó làm việc cho đến nay, nhưng có một số yêu cầu mới tôi chỉ có thể dường như không đáp ứng bằng cách sử dụng lập bản đồ Hibernate thẳng. Tôi có lẽ sẽ từ bỏ và sử dụng iBATIS cho trường hợp này.Không thực sự vui mừng khi thêm một công nghệ khác vào ngăn xếp như một băng cứu trợ, nhưng đó là cuộc sống mà tôi đoán. Cảm ơn. – Ickster

+0

@Ickster Xem cập nhật của tôi. –

+1

Cảm ơn bạn đã cập nhật. Tôi đã xem xét cách tiếp cận đó và đưa ra số lượng tham số mà tôi đang xử lý, tôi đã quyết định có thể sử dụng iBATIS rõ ràng hơn. Cảm ơn vì lời khuyên. – Ickster

29

Như đã đề cập trong một different answer đến question tham chiếu trước đó, HQL sau xây dựng công trình đối với tôi:

select o from Product o WHERE :value is null or o.category = :value 

nếu: giá trị được thông qua tại như null, tất cả các sản phẩm được trả lại.

cũng Xem Optional or Null Parameters

Lưu ý rằng điều này sẽ không làm việc trong một số phiên bản của Sybase do this bug, vì vậy sau đây là một sự thay thế:

select o from Product o WHERE isnull(:value, 1) = 1 or o.category = :value 
5

tiếc là giải pháp dưới "Parameters bắt buộc hoặc Null "không hoạt động cho danh sách IN. tôi đã phải thay đổi các truy vấn như sau ...

Đặt tên định nghĩa truy vấn:

select ls from KiCOHeader co 
... 
join lu.handlingType ht 
where (:inHandlingTypesX = 1 OR ht.name in (:inHandlingTypes)) 

Code:

Set<KiHandlingTypeEnum> inHandlingTypes = ... 

Query query = persistence.getEm().createNamedQuery("NAMED_QUERY"); 
query.setParameter("inHandlingTypesX", (inHandlingTypes == null) ? 1 : 0); 
query.setParameter("inHandlingTypes", inHandlingTypes); 

List<KiLogicalStock> stocks = query.getResultList(); 

nhiều niềm vui làm việc.

+0

không hoạt động nữa .. – george

2

Một giải pháp khác để xử lý các tham số danh sách tùy chọn là kiểm tra giá trị rỗng bằng cách sử dụng hàm COALESCE. COALESCE là supported by Hibernate trả về tham số không null đầu tiên từ danh sách, cho phép bạn kiểm tra null trên danh sách mà không vi phạm cú pháp khi có nhiều mục trong danh sách.

HQL ví dụ với thông số tham số và danh sách tùy chọn:

select obj from MyEntity obj 
where (COALESCE(null, :listParameter) is null or obj.field1 in (:listParameter)) 
    and (:parameter is null or obj.field2 = :parameter) 

này làm việc cho tôi với một phương ngữ SQL Server.

+0

Điều này không hiệu quả đối với tôi, hibernate phàn nàn về 'COALESCE (null,)' khi ': listParameter' không được định nghĩa. Giải pháp của tôi là cũng vượt qua một tham số bổ sung và có điều kiện nơi được viết theo cách này: '(: listParamterSize = 0 hoặc obj.field1 trong (: listParameter))' – jeremija

+0

Nó hoạt động, nhưng ': listParameter' phải được định nghĩa, ít nhất là null. Ưu điểm của giải pháp này là bạn có thể chuyển tham số là null và không cần tham số bổ sung. –

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