我想知道HQL表达式是否为空安全?例如,考虑以下命名查询
SELECT a
FROM A a
where a.f=:f
,其中f是String、Double、Date等类型的字段。然后我这样使用:
session.getNamedQuery("myNamedQuery").setString("f", myFValue).uniqueResult();
如果a.f和myFValue都为空,我希望条件为真,如果其中只有一个为空,我希望它为假。
如果它不是空安全的,我该如何处理?
对
不,它们不是null安全的。它们被直接转换为SQL,并遵循相同的规则。所以如果你想测试null,你必须使用is [not] null
。
因此,如果f参数可以为null,则必须使用两个不同的HQL查询,或者动态构建它,或者使用Criteria查询来构建动态查询。
它们不是。尝试以下场景来处理您的特定情况:
select a from A a where ((:f is null and a.f is null) or a.f = :f) and ...
如果您的参数String为空,那么查询将检查行状态是否为空。否则,它将求助于与等号进行比较。
如果你需要完全跳过:status where_clause子句;你可以这样写代码:
select a from A a where (:f is null or a.f = :f) and ...
第二个查询相当于:
if(status != null){
sql.append(" a.f = :f and ");
}
您应该使用is null
或is not null
。参见HQL "is null"one_answers"!= null"
它们不是null安全的
HQL将您的HQL查询转换为SQL,然后替换您的参数。所以它不会重写查询从param = ?参数为null
使用Criteria API并使用Restrictions.isNull("f");
它们不是null安全的。使用条件可以达到以下效果
public static void addNullSafeEqualsRestriction(Criteria criteria, String propertyName, Object object) {
if (object == null) {
criteria.add(Restrictions.isNull(propertyName));
} else {
criteria.add(Restrictions.eq(propertyName,object));
}
}