2010-03-15 29 views
17

在使用Hibernate時,有沒有什麼方法可以指定可選參數(例如,當從表單提供搜索參數,而不是所有參數都是必需的)?我正在使用本機SQL查詢,但問題可能也適用於命名的HQL查詢。Hibernate中帶有命名查詢的可選參數?

我很肯定這個答案是'不',但我還沒有在文檔中找到確切的答案。

回答

10

AFAIK,沒有這樣的事情,所以你必須爲此寫一個動態查詢。也許看看這個previous answer顯示瞭如何在HQL中執行此操作(可以轉換爲SQL),並且還顯示了Criteria API如何使它更簡單,並因此更適合我的這一工作。

更新:(回答OP的評論)使用舊數據庫對於Hibernate來說確實很棘手。也許你可以使用動態原生查詢並返回non-managed entities。但從長遠來看,事情可能會變得更糟(我不能告訴你)。也許Hibernate並不是您的案例中的最佳選擇,而像iBATIS這樣的東西可以爲您提供所需的靈活性。

+0

謝謝。這幾乎是我所想的。我熟悉你在其他答案中提出的兩種方法,但我堅持使用一種噩夢般的遺留數據庫模式,這對我的特殊情況來說並不適合Hibernate方法。到目前爲止,我已經完成了它的工作,但有一些新的要求,我似乎無法滿足使用直接的Hibernate映射。我可能會放棄並使用iBATIS來處理這種情況。不是真正的興奮,添加另一種技術作爲一種創可貼,但我想這就是生活。謝謝。 – Ickster 2010-03-15 02:14:53

+0

@Ickster查看我的更新。 – 2010-03-15 03:21:14

+1

感謝您的更新。我也考慮過這種方法,並且考慮到我正在處理的參數的數量,我決定使用iBATIS可能更乾淨。感謝您的建議。 – Ickster 2010-03-15 15:30:03

29

如在different answer提到前面引用的question,下面的HQL建設工作對我來說:

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

如果:值在給定值爲null,將返回所有產品。

又見Optional or Null Parameters

請注意,這不會因this bug的Sybase的某些版本的工作,所以下面是一個另類:

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

遺憾的是「可選或空參數下的解決方案「不適用於IN列表。 我不得不改變了查詢作爲跟隨...

命名查詢定義:

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

代碼:

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(); 

非常有趣的工作。

+0

不能工作了.. – george 2016-11-17 16:59:38

2

處理可選列表參數的另一個解決方案是使用COALESCE函數檢查null。 COALESCE爲supported by Hibernate返回列表中的第一個非空參數,允許您在列表中有多個項目時檢查列表上的空值而不中斷語法。

HQL例如具有可選的參數和列表參數:

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

這與SQL Server方言爲我工作。

+0

這對我沒有用,當':listParameter'沒有被定義時,hibernate抱怨'COALESCE(null,)'。我的解決方案是也傳遞一個額外的參數,並以這種方式寫入where條件:'(:listParamterSize = 0或obj.field1 in(:listParameter))' – jeremija 2015-05-13 09:59:32

+0

它有效,但必須定義':listParameter',至少爲空。此解決方案的優點是您可以將參數傳遞爲null,並且不需要額外的參數。 – 2015-11-27 09:53:52