obsession(执念)
2011-11-16 12:02
浏览 1.8k
已采纳

hibernate sql语句参数为null时,如何处理

使用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本身有没有灵活、优雅的方式解决这个问题?

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

9条回答 默认 最新

  • vinceyu 2011-11-28 15:27
    已采纳

    我对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]

    已采纳该答案
    打赏 评论
  • xueliangEmail 2011-11-16 12:21

    [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]

    打赏 评论
  • xueliangEmail 2011-11-16 12:22

    [b]少了一个query创建对象补上[/b][code="java"]
    Query query = getSession().createQuery(sql);
    [/code]

    打赏 评论
  • 爱上一条鱼 2011-11-16 12:22

    可以的,貌似是建议把在表的entity里定义字段参数的时候,把基本类型写成封装过的 Integer Long,不要用基本类型int long

    不过我没试过。。。

    打赏 评论
  • xueliangEmail 2011-11-16 14:22

    [b]把你的if块里再加上一个限制条件,如:[/b]
    [code="java"]
    if (null != pId && null == sId&&!.equals(pId))
    [/code]
    [b]按照条件把下边的if块补充完整即可[/b]

    打赏 评论
  • Canace_lemon 2011-11-16 14:39

    这个问题,不管怎么样都需要对参数进行判断,所以你还是可以将判断的语句简化,或者你可以在参数传进来之间就对其做判断,不满足条件就不让传进来。假如是从页面传进来的,可以直接用JS判断

    打赏 评论
  • carvin_happy 2011-11-16 19:27

    [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]
    
    打赏 评论
  • carvin_happy 2011-11-16 19:32

    不好意思, 太大意了。 这样不行。

    打赏 评论
  • huoyj 2011-11-17 09:33

    这种基本类型和对应的封装类型的问题很麻烦的,给你举个例子吧,比如int和Integer类型的,int属性默认的是0,而Integer是null,在你的数据库里你得清楚默认存的是0还是null再选择你代码有int还是Integer。如果0和null都有,那你的sql语句必须考虑到这两种情况了。

    打赏 评论

相关推荐 更多相似问题