2016-06-01 64 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