2015-07-20 40 views
4

我正在使用hibernate將記錄(即對象)保存到數據庫。在保存我的對象之前,我想驗證數據庫是否已經包含這個對象。 (主鍵只是一個增量鍵,不能用於此目的。)休眠,檢查對象是否存在,空值

在運行時創建一個 HQL語句來檢查這些屬性(即column1-3)記錄是否存在等。

生成的查詢應該是這樣的:

from myTable where column1 is null and column2 = :column2 and column3 = :column3' 

因爲有時列可以包含空值,我檢查的屬性的值,如果它是一個NULL值,然後我用一個is代替該查詢中的=(例如上述語句中的column1 is :column1)。

因爲我開始意識到,我正在做很多工作來實現相關性至關重要的事情,我開始懷疑自己是否走上了正軌。 有沒有更簡單的方法來檢查物體的存在?

編輯:我稍微改寫我的問題後,我意識到,column1 is :column1並不時:column1參數設置爲null工作。顯然,似乎按預期工作的唯一語法是column1 is null。因此,在搜索null值時,您似乎不能使用通配符。但是這並沒有改變我的問題的主要方面:我應該在運行時檢查所有這些東西嗎?

+4

一個簡單的解決方案是在你的數據庫的列1-3組合上添加唯一約束。這種方式自動你不會被允許添加重複數據庫。但是,如果您有多個記錄可以爲這些列包含空值的場景,則這不起作用。 – Waqar

+0

WHERE((column1爲null AND:column1Param爲null)或者column1 =:column1Param)AND(對於column2 ...是一樣的)? – StanislavL

+0

也許您可以創建列的校驗和並將其保存爲單獨的列 - 即使列將爲空,校驗和也會具有值(例如「null,null,null」),而不是創建索引,您將必須計算新對象的校驗和並僅檢查此列 – Zavael

回答

1

這是迄今爲止我發現的最好方法。

我寧願將我的過濾器放在地圖上。鑰匙是指財產(即map.put("column1", Integer.valueOf(1)))。

有一個Restritions.eqOrIsNull方法,可以簡化轉換爲Criterion對象。以下方法將整個Map轉換爲List<Criterion>

public List<Criterion> mapToCriterion(Map<String, Object> params) 
{ 
    if (params == null) return null; 

    // convert the parameter map to a list of criterion 
    List<Criterion> criterionList = new ArrayList<>(params.size()); 
    for (Map.Entry<String, Object> entry : params.entrySet()) 
    criterionList.add(Restrictions.eqOrIsNull(entry.getKey(), entry.getValue())); 
    return criterionList; 
} 

後來,我用的是List<Criterion>建立一個Criteria對象。

Criteria criteria = session.createCriteria(clazz); 
if (criterionList != null) 
{ 
    for(Criterion criterion : criterionList) 
    criteria.add(criterion); 
} 

// get the full list 
@SuppressWarnings("unchecked") 
List<T> objectList = criteria.list(); 

我的總體印象是仍然有在這裏失去了一些方便的方法(例如Criteria#addAll(List<Criterion>)本來不錯)。

-1

我認爲你可以使用下面的方法從數據庫中獲取對象。 public Object get(Class clazz,Serializable id)throws HibernateException

如果對象不爲null,則該對象已經存在。

+0

這使用ID,他不能使用。 – Astrogat