使用hibernate时出现了点问题,现请教各位。
目的:
删除满足条件的数据。
出现问题:
参数为null时,程序出现异常。
问题描述:
之前代码如下:
[code="java"]
sql="delete table where pId=? and sId=?";
query.setParameter(0, pId);
query.setParameter(1, sId);
[/code]
现在遇到一个问题,就是如果参数传一个null的时候,hibernate不会将sql转换成is null,程序将会出现错误,所以修改成如下:
[code="java"]
//两个参数均不是主键
public void deleteTable(Long sId, Long pId) {
String sql = "delete table where 1=1";
if (null == pId) {
sql = sql + " and pIdis null";
} else {
sql = sql + " and pId=?";
}
if (null == sId) {
sql = sql + " and sIdis null";
} else {
sql = sql + " and sId=?";
}
Query query = getSession().createQuery(sql);
//这样判断简直让人崩溃,有啥好的处理方式?
if (null != pId && null == sId) {
query.setParameter(0, pId);
}
if (null != pId && null != sId) {
query.setParameter(0, pId).setParameter(1, pId);
}
if (null == pId && null != sId) {
query.setParameter(0, pId);
}
query.executeUpdate();
}
[/code]
这样是可以实现业务逻辑的,但是显然程序很笨重,不知到hibernate本身有没有灵活、优雅的方式解决这个问题?
我对hibernate也不是很熟悉,不过之前在使用ibatis的时候,直接使用动态sql就能很好的解决类似的问题。
我想这类情况可以通过数据库的设置使代码简化,将以上2个变量的默认值设置为0,这样不管怎样2个字段都有值的(即永不为null),然后代码就可以改成:
[code="java"]
String sql = "delete table where 1=1 and pId=? and sId=?";
Query query = getSession().createQuery(sql).setParameter(0, null==pId?0:pId).setParameter(1, null==sId?0:sId);
query.executeUpdate();
[/code]
[b]按你的要求改成这样:[/b]
[code="java"]
public void deleteTable(Long sId, Long pId) {
String sql = "delete table where 1=1";
if (null != pId && null == sId) {
sql+=" and pId="+pid;
}
if (null != pId && null != sId) {
sql+=" and pId="+pid+" and sId="+sid;
}
if (null == pId && null != sId) {
sql+=" and sId="+sId;
}
query.executeUpdate();
}
[/code]
[b]少了一个query创建对象补上[/b][code="java"]
Query query = getSession().createQuery(sql);
[/code]
可以的,貌似是建议把在表的entity里定义字段参数的时候,把基本类型写成封装过的 Integer Long,不要用基本类型int long
不过我没试过。。。
[b]把你的if块里再加上一个限制条件,如:[/b]
[code="java"]
if (null != pId && null == sId&&!.equals(pId))
[/code]
[b]按照条件把下边的if块补充完整即可[/b]
这个问题,不管怎么样都需要对参数进行判断,所以你还是可以将判断的语句简化,或者你可以在参数传进来之间就对其做判断,不满足条件就不让传进来。假如是从页面传进来的,可以直接用JS判断
[code="java"]
public void deleteTable(Long sId, Long pId) {
String sql = "delete table where 1=1";
Query query = getSession().createQuery(sql);
int index = 0;
if (null == pId) {
sql = sql + " and pId is null";
} else {
sql = sql + " and pId=?";
query.setParameter(index++, pId);
}
if (null == sId) {
sql = sql + " and sIdis null";
} else {
sql = sql + " and sId=?";
query.setParameter(index, sId);
}
query.executeUpdate();
} [/code]
不好意思, 太大意了。 这样不行。
这种基本类型和对应的封装类型的问题很麻烦的,给你举个例子吧,比如int和Integer类型的,int属性默认的是0,而Integer是null,在你的数据库里你得清楚默认存的是0还是null再选择你代码有int还是Integer。如果0和null都有,那你的sql语句必须考虑到这两种情况了。