tim*_*tim 57 java null hibernate
如何将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);
Run Code Online (Sandbox Code Playgroud)
在我的例子中,状态String可以为null.我调试了这个,然后hibernate然后生成一个像这样的SQL字符串/查询.... status = null
但是这在MYSQL中不起作用,因为正确的SQL语句必须是" status is null
"(Mysql不理解status = null并且计算这个为了没有任何记录将被返回查询,根据我读过的mysql文档...)
我的问题:
为什么没有Hibernate
正确地将空字符串转换为"is null"(而且错误地创建"= null")?
重写此查询以使其为空安全的最佳方法是什么?使用nullsafe,我的意思是,如果"status"字符串为null,则应该创建"is null"?
非常感谢你!蒂姆
小智 39
我相信hibernate首先会将您的HQL查询转换为SQL,然后才会尝试绑定您的参数.这意味着它不能从重写查询param = ?
到param is null
.
尝试使用Criteria api:
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();
Run Code Online (Sandbox Code Playgroud)ega*_*rdo 28
这不是Hibernate特有的问题(它只是SQL本质),是的,有一个SQL和HQL的解决方案:
@Peter Lang有正确的想法,你有正确的HQL查询.我想你只需要一个新的清理运行来获取查询更改;-)
以下代码绝对有效,如果您将所有查询保存在orm.xml中,那就太棒了
from CountryDTO c where ((:status is null and c.status is null) or c.status = :status) and c.type =:type
如果参数String为null,则查询将检查行的状态是否也为空.否则它将与等号进行比较.
笔记:
问题可能是特定的MySql怪癖.我只用Oracle测试过.
以上查询假定存在c.status为null的表行
优先考虑where子句,以便首先检查参数.
参数名称"type"可能是SQL中的保留字,但它应该无关紧要,因为它在查询运行之前被替换.
如果你需要跳过:status where_clause; 你可以像这样编码:
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 ");
Run Code Online (Sandbox Code Playgroud)
ska*_*man 13
该对的javadocsetParameter(String, Object)
是明确的,说对象值必须非空.遗憾的是,如果传入null,它不会抛出异常.
另一种方法是setParameter(String, Object, Type)
,它确实允许空值,虽然我不知道什么Type
参数是最合适的位置.
看来你必须使用is null
的HQL,但这里是一个可能的解决方案(这可能导致复杂的排列组合,如果有一个以上的参数与空潜力.):
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)
}
Run Code Online (Sandbox Code Playgroud)
HQL 支持coalesce,允许丑陋的解决方法,例如:
where coalesce(c.status, 'no-status') = coalesce(:status, 'no-status')
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
117258 次 |
最近记录: |