zoukankan      html  css  js  c++  java
  • hql中in的用法

    平时经常用Hibernate,由于习惯表间不建立关联,所以HQL查询时候经常要用in语句。

    由于表间没有建立外键的关联关系所以使用in是最常见的代替使用对象po中的set。

    但是在写hql时如果在new object()对象的前面写上distinct关键字是可以去掉重复记录的,完全不必考虑使用in排除重复记录,但是在本公司框架中前台的ecside获得记录总数时调用的方法中,获得记录总数代码如下:

    public Page findBy(String query, PageInfo pageInfo)
      {
        String countQuery = "select count(*) " + HqlRemoveUtils.removeSelect(query);
        return findBy(query, countQuery, pageInfo);
      }

    public static String removeSelect(String hql)
      {
        Assert.hasText(hql);
        int beginPos = hql.toLowerCase().indexOf("from");
        Assert.isTrue(beginPos != -1, " hql : " + hql + " must has a keyword 'from'");
        return hql.substring(beginPos);
      }

    可以看到其获得记录总数是从from后面截取hql然后重组hql才获得记录总数的,此时在new前面加上distinct关键字虽然获得的记录是对的,但是在前台的ecside中的记录总数是错误的。

    为了避免这种bug不用distinct而使用in关键字。这样就可以不用关联其他表避免造成多条重复记录的情况,而是使用子查询通过where中的条件使用in限制查询条件,排除重复记录

    使用distinct的代码如下:

    String sql = "select distinct new com.luguang.product.model.LgpProductVo(a.lgpProductId,a.productName,a.productNum,d.userAlias,a.productLeader,a.productGoal,a.description,a.accessControl,'')  from LgpProduct  as a , LgmUser as d , LgpProjectGroup as e   where 1=1 "
        +" and a.productLeader=d.userId"
        +" and ((a.lgpProductId=e.lgpProductId "
        +" and e.userId='"+userId+"'"
        +" )or a.accessControl=0)"
           + "/~ and a.productName = '[productName]' ~/"
        + "/~ and a.productNum = '[productNum]' ~/"
        + "/~ and d.userId = '[productLeader]' ~/"
        + "/~ and a.accessControl = '[accessControl]' ~/"
        + "/~ order by [sortingColumn] [sortingDirection] ~/";

    使用in的代码如下:

    String sql = "select distinct new com.lg.product.model.LgpProductVo(a.lgpProductId,a.productName,a.productNum,d.userAlias,a.productLeader,a.productGoal,a.description,a.accessControl,'')  from LgpProduct  as a , LgmUser as d   where 1=1 "
        +" and a.productLeader=d.userId"
        +" and ((a.lgpProductId in (select e.lgpProductId from LgpProjectGroup as e where e.userId='"+userId+"') "
        +" )or a.accessControl=0)"
           + "/~ and a.productName = '[productName]' ~/"
        + "/~ and a.productNum = '[productNum]' ~/"
        + "/~ and d.userId = '[productLeader]' ~/"
        + "/~ and a.accessControl = '[accessControl]' ~/"
        + "/~ order by [sortingColumn] [sortingDirection] ~/";

    以后处理重复记录时尽量采用in的形式(针对公司框架目的是避免在ecside中的记录总数中产生错误的记录统计数量),原始的hibernate框架中使用distinct较为简单可靠。

        我最常用的情况有2种:

       1、in后是个子查询,如 FROM A WHERE A.ID IN (SELECT B.AID FROM B WHERE ...),这样是没问题的,如果A.ID 和B.AID是相同的数据类型。

       2、in的参数如果已知了,可以直接拼接在后面 如FROM A WHERE A.ID IN (1,2,3,4...)。

       3、上面的情况下,通常(1,2,3,4...)都是作为参数传递过来的,可能是数组或者List。

        假设List<Integer> a;a里面已经有数据了,则HQL查询条件可以为:        

    Java代码 复制代码 收藏代码
    1. String hql="FROM A WHERE A.ID IN (:alist)";   
    2. Query query = getSession().createQuery(hql);   
    3. query.setParameterList("alist", a);  
    String hql="FROM A WHERE A.ID IN (:alist)";
    Query query = getSession().createQuery(hql);
    query.setParameterList("alist", a);
    

       另外,query.setParameterList中的第二个参数,还可以是数组类型,如int[] a,不要被方法名称迷惑。我也是最近刚学会的这种in参数设置。

  • 相关阅读:
    Linux下的tar压缩解压缩命令详解
    python学习笔记-day9-2【面向对象】
    python学习笔记-day9-1【发送邮件模块 yagmail】
    python学习笔记-day8-4-【python 内置函数补充:zip,map,filter】
    python学习笔记-day8-3-【python 网络请求及requests模块】
    python学习笔记-day8-2-【python 异常处理 try except】
    python学习笔记-day8-1-【python flask接口开发】
    day9-Python学习笔记(二十一)单元测试
    day9-Python学习笔记(二十)数据库备份,修改父类的方法
    day8-Python学习笔记(十八)面向对象,self,私有,属性方法
  • 原文地址:https://www.cnblogs.com/moonfans/p/3363984.html
Copyright © 2011-2022 走看看