2015-07-20 64 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