Hibernate:如何使用HQL设置NULL查询参数值?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate:如何使用HQL设置NULL查询参数值?相关的知识,希望对你有一定的参考价值。
如何将Hibernate参数设置为“null”?例:
Query query = getSession().createQuery("from CountryDTO c where c.status = :status and c.type =:type")
.setParameter("status", status, Hibernate.STRING)
.setParameter("type", type, Hibernate.STRING);
在我的例子中,状态String可以为null。我调试了这个,然后hibernate然后生成一个像这样的SQL字符串/查询.... status = null
...然而这在mysql中不起作用,因为正确的SQL语句必须是“status is null
”(Mysql不理解status = null和将此值计算为false,以便根据我读过的mysql文档,不会为查询返回任何记录...)
我的问题:
- 为什么qazxsw poi没有正确地将空字符串转换为“is null”(而且错误地创建了“= null”)?
- 重写此查询以使其为空安全的最佳方法是什么?使用nullsafe,我的意思是,如果“status”字符串为null,则应该创建“is null”?
非常感谢你!蒂姆
- 我相信hibernate首先会将您的HQL查询转换为SQL,然后才会尝试绑定您的参数。这意味着它无法将查询从
Hibernate
重写为param = ?
。 - 尝试使用Criteria api:
param is null
这似乎也有效 - >
where ((:orderItemId is null) OR (orderItem.id != :orderItemId))
顺便说一句,我对此很新,所以如果出于任何原因这不是一个好主意,请告诉我。谢谢。
这不是Hibernate特定的问题(它只是SQL本质),是的,有一个SQL和HQL的解决方案:
@Peter Lang有正确的想法,你有正确的HQL查询。我想你只需要一个新的清理运行来获取查询更改;-)
以下代码绝对有效,如果您将所有查询保存在orm.xml中,那就太棒了
Criteria c = session.createCriteria(CountryDTO.class);
c.add(Restrictions.eq("type", type));
c.add(status == null ? Restrictions.isNull("status") : Restrictions.eq("status", status));
List result = c.list();
如果参数String为null,则查询将检查行的状态是否也为空。否则它将与等号进行比较。
笔记:
问题可能是特定的MySql怪癖。我只用Oracle测试过。
以上查询假定存在c.status为null的表行
优先考虑where子句,以便首先检查参数。
参数名称“type”可能是SQL中的保留字,但它应该无关紧要,因为它在查询运行之前被替换。
如果你需要跳过:status where_clause;你可以像这样编码:
from CountryDTO c where ((:status is null and c.status is null) or c.status = :status) and c.type =:type
它相当于:
from CountryDTO c where (:status is null or c.status = :status) and c.type =:type
sql.append(" where ");
if(status != null){
sql.append(" c.status = :status and ");
}
sql.append(" c.type =:type ");
是显式的,表示Object值必须为非null。遗憾的是,如果传入null,它不会抛出异常。
另一种选择是javadoc for setParameter(String, Object)
,它允许空值,但我不确定setParameter(String, Object, Type)
参数在这里最合适。
看来你必须在HQL中使用Type
(如果存在多个具有零潜力的参数,则可能导致复杂的排列。)但这是一个可能的解决方案:
is null
我没试过这个,但是当你使用String statusTerm = status==null ? "is null" : "= :status";
String typeTerm = type==null ? "is null" : "= :type";
Query query = getSession().createQuery("from CountryDTO c where c.status " + statusTerm + " and c.type " + typeTerm);
if(status!=null){
query.setParameter("status", status, Hibernate.STRING)
}
if(type!=null){
query.setParameter("type", type, Hibernate.STRING)
}
两次检查:status
时会发生什么?
NULL
HQL支持Query query = getSession().createQuery(
"from CountryDTO c where ( c.status = :status OR ( c.status IS NULL AND :status IS NULL ) ) and c.type =:type"
)
.setParameter("status", status, Hibernate.STRING)
.setParameter("type", type, Hibernate.STRING);
,允许丑陋的解决方法,如:
coalesce
对于实际的HQL查询:
where coalesce(c.status, 'no-status') = coalesce(:status, 'no-status')
您可以使用
FROM Users WHERE Name IS NULL
代替
Restrictions.eqOrIsNull("status", status)
这是我在Hibernate 4.1.9上找到的解决方案。我必须将一个参数传递给我的查询,有时可能有值NULL。所以我通过了使用:
status == null ? Restrictions.isNull("status") : Restrictions.eq("status", status)
之后,我在查询中使用以下where子句:
setParameter("orderItemId", orderItemId, new LongType())
正如您所看到的,我使用的是Query.setParameter(String,Object,Type)方法,我无法使用我在文档中找到的Hibernate.LONG(可能是旧版本)。有关type参数的完整选项集,请检查org.hibernate.type.Type接口的实现类列表。
希望这可以帮助!
以上是关于Hibernate:如何使用HQL设置NULL查询参数值?的主要内容,如果未能解决你的问题,请参考以下文章