2016-06-01 70 views
0

在我的代码中,我使用条件投影列表来列出选择字段并设置first/max结果来限制行号。在使用rownum时选择子选择(Java Hibernate Persistence)

private Criteria getCriteria(Status status, Class<?> T, String aliasName, String subTable, String subAlias, List<Criterion> criterionList, List<Order> orderList, ProjectionList projectionList, Integer firstResult, Integer maxResult, Session session) { 
    StringBuilder methodFullNameSb = new StringBuilder("Criteria: getCriteria(Status, Class<?>, String, String, String, List<Criterion>, List<Order>, ProjectionList,Integer, Integer)"); 
    MethodLevelLogger methodLevelLogger = MethodLevelLogger.getCurrentInstance(methodFullNameSb.toString()); 
    methodLevelLogger.start(); 

    Criteria criteria = null; 
    try { 
     criteria = session.createCriteria(T, aliasName); 
     if (subAlias != null && !subAlias.isEmpty()) { 
      criteria.createAlias(subTable, subAlias).setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).setReadOnly(true); 
     } 

     if (criterionList != null) { 
      for (Criterion criterion : criterionList) { 
       criteria.add(criterion); 
      } 
     } 

     if (orderList != null) { 
      for (Order order : orderList) { 
       criteria.addOrder(order); 
      } 
     } 

     //to setlect field 
     if (projectionList != null) { 
      criteria.setProjection(projectionList); 
     } 

     //to limit row number 
     if (firstResult != null && maxResult != null) { 
      criteria.setFirstResult(firstResult); 
      criteria.setMaxResults(maxResult); 
     } 
     // Set Cache MODE DISABLE 
     criteria.setCacheMode(CacheMode.IGNORE).setReadOnly(true); 

    } catch (HibernateException | NullPointerException e) { 
     ApplicationExceptionHandle.doApplicationExceptionHandleAPP001withStackTrace(status, e, log); 
    } catch (Exception exception) { 
     ApplicationExceptionHandle.doApplicationExceptionHandleAPP001withStackTrace(status, exception, log); 
    } 

    methodLevelLogger.end(); 
    log.debug(methodLevelLogger.getMessageTimeDiff()); 
    return criteria; 
} 

但是,如果没有限制行号,那么每个事物都会看起来很像SQL日志中所示。

2016-05-31 16:49:41,769 INFO [stdout]:71 - Hibernate: 
2016-05-31 16:49:41,769 INFO [stdout]:71 -  /* criteria query */ select 
2016-05-31 16:49:41,769 INFO [stdout]:71 -   /*+index(this_  ORDHIS_IDX)*/ this_.ORDER_HISTORY_ID as H_ORDER_HISTORY_ID, 
2016-05-31 16:49:41,769 INFO [stdout]:71 -   this_.ORDER_TRAN_ID as y1_, 
2016-05-31 16:49:41,769 INFO [stdout]:71 -   this_.UUID as y2_, 
2016-05-31 16:49:41,769 INFO [stdout]:71 -   this_.MOBILE_NO as y3_, 
2016-05-31 16:49:41,769 INFO [stdout]:71 -   this_.MOBILE_SEGMENT as y4_,... 
2016-05-31 16:49:41,779 INFO [stdout]:71 -  from 
2016-05-31 16:49:41,779 INFO [stdout]:71 -   suiadm.SSC_ORDER_HISTORY this_, 
2016-05-31 16:49:41,779 INFO [stdout]:71 -   suiadm.SSC_ORDER_ITEM orderitems1_ 
2016-05-31 16:49:41,779 INFO [stdout]:71 -  where 
2016-05-31 16:49:41,779 INFO [stdout]:71 -   this_.ORDER_HISTORY_ID=orderitems1_.ORDER_HISTORY_ID 
2016-05-31 16:49:41,779 INFO [stdout]:71 -   and this_.CREATE_BY=? 
2016-05-31 16:49:41,779 INFO [stdout]:71 -   and this_.SFF_STATUS in (
2016-05-31 16:49:41,779 INFO [stdout]:71 -    ?, ?, ?, ? 
2016-05-31 16:49:41,779 INFO [stdout]:71 -  ) 
2016-05-31 16:49:41,779 INFO [stdout]:71 -   and this_.MOBILE_SEGMENT in (
2016-05-31 16:49:41,779 INFO [stdout]:71 -    ?, ? 
2016-05-31 16:49:41,779 INFO [stdout]:71 -  ) 
2016-05-31 16:49:41,779 INFO [stdout]:71 -   and this_.CREATE_DATE between ? and ? 
2016-05-31 16:49:41,779 INFO [stdout]:71 -   and orderitems1_.EFF_CODE in (
2016-05-31 16:49:41,779 INFO [stdout]:71 -    ?, ? 
2016-05-31 16:49:41,779 INFO [stdout]:71 -  ) 
2016-05-31 16:49:41,779 INFO [stdout]:71 -   and this_.SERVICE_TYPE=? 

无论如何,当我限制的行数,SQL是遵循

2016-05-31 17:00:46,561 INFO [stdout]:71 - Hibernate: 
    2016-05-31 17:00:46,561 INFO [stdout]:71 -  select 
    2016-05-31 17:00:46,561 INFO [stdout]:71 -   * 
    2016-05-31 17:00:46,561 INFO [stdout]:71 -  from 
    2016-05-31 17:00:46,561 INFO [stdout]:71 -   (/* criteria query */ select 
    2016-05-31 17:00:46,561 INFO [stdout]:71 -    /*+index(this_ ORDHIS_IDX)*/ this_.ORDER_HISTORY_ID as H_ORDER_HISTORY_ID, 
    2016-05-31 17:00:46,561 INFO [stdout]:71 -    this_.ORDER_TRAN_ID as y1_, 
    2016-05-31 17:00:46,561 INFO [stdout]:71 -    this_.UUID as y2_, 
    2016-05-31 17:00:46,561 INFO [stdout]:71 -    this_.MOBILE_NO as y3_, 
    2016-05-31 17:00:46,561 INFO [stdout]:71 -    this_.MOBILE_SEGMENT as y4_,..... 
    2016-05-31 17:00:46,579 INFO [stdout]:71 -   from 
    2016-05-31 17:00:46,580 INFO [stdout]:71 -    suiadm.SSC_ORDER_HISTORY this_, 
    2016-05-31 17:00:46,580 INFO [stdout]:71 -    suiadm.SSC_ORDER_ITEM orderitems1_ 
    2016-05-31 17:00:46,580 INFO [stdout]:71 -   where 
    2016-05-31 17:00:46,580 INFO [stdout]:71 -    this_.ORDER_HISTORY_ID=orderitems1_.ORDER_HISTORY_ID 
    2016-05-31 17:00:46,580 INFO [stdout]:71 -    and this_.MOBILE_NO=? 
    2016-05-31 17:00:46,581 INFO [stdout]:71 -    and this_.SFF_STATUS in (
    2016-05-31 17:00:46,582 INFO [stdout]:71 -     ?, ?, ?, ? 
    2016-05-31 17:00:46,582 INFO [stdout]:71 -   ) 
    2016-05-31 17:00:46,582 INFO [stdout]:71 -    and this_.MOBILE_SEGMENT in (
    2016-05-31 17:00:46,582 INFO [stdout]:71 -     ?, ? 
    2016-05-31 17:00:46,583 INFO [stdout]:71 -   ) 
    2016-05-31 17:00:46,583 INFO [stdout]:71 -    and this_.CREATE_DATE between ? and ? 
    2016-05-31 17:00:46,583 INFO [stdout]:71 -    and orderitems1_.EFF_CODE in (
    2016-05-31 17:00:46,583 INFO [stdout]:71 -     ?, ? 
    2016-05-31 17:00:46,583 INFO [stdout]:71 -   ) 
    2016-05-31 17:00:46,583 INFO [stdout]:71 -    and this_.SERVICE_TYPE=?) 
    2016-05-31 17:00:46,584 INFO [stdout]:71 -  where 
    2016-05-31 17:00:46,584 INFO [stdout]:71 -   rownum <= ? 

而不是

select ... from ... where criteria1 and criteria2 and rownum < ? 

我选择与子选择

select ... from select ... from where creiterai1 and criteria2 where rownum < ? 

是这与正常冬眠?或者我做错了什么?如果我想要

select ... from ... where criteria1 and criteria2 and rownum < ? 

如何编辑我的代码?

回答

1

这是通过oracle获取结果集第一页的通用方法。

它等同于您希望hibernate生成的查询。

请注意,当您在查询上应用分页时,应对完整的结果集进行排序,否则每次运行查询时可能会得到不同的结果。

ORDER BY子句将产生的子选择休眠里面放(你排序的结果集满,限制到一个页面的前):

select 
    * 
from 
    (/* criteria query */ select 
     /*+index(this_ ORDHIS_IDX)*/ this_.ORDER_HISTORY_ID as H_ORDER_HISTORY_ID, 
     this_.ORDER_TRAN_ID as y1_, 
     this_.UUID as y2_, 
     this_.MOBILE_NO as y3_, 
     this_.MOBILE_SEGMENT as y4_,..... 
    from 
     suiadm.SSC_ORDER_HISTORY this_, 
     suiadm.SSC_ORDER_ITEM orderitems1_ 
    where 
     this_.ORDER_HISTORY_ID=orderitems1_.ORDER_HISTORY_ID 
     and this_.MOBILE_NO=? 
     and this_.SFF_STATUS in (
      ?, ?, ?, ? 
     ) 
     and this_.MOBILE_SEGMENT in (
      ?, ? 
     ) 
     and this_.CREATE_DATE between ? and ? 
     and orderitems1_.EFF_CODE in (
      ?, ? 
     ) 
     and this_.SERVICE_TYPE=? 
    **order by ...** 
) 
where 
    rownum <= ? 
+0

谢谢蒂埃里。 – Gibi