服务于区块链开拓者

www.zhidnet.com

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

平时经常用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参数设置。

posted on 2013-10-11 18:13  知点网  阅读(11163)  评论(0编辑  收藏  举报