使用rownum时选择sub select(Java Hibernate Persistence)

时间:2016-06-01 05:29:56

标签: hibernate

在我的代码中,我有这个通用的hibernate查询,其中条件投影列表列出了选择字段,并设置了第一个/最大结果来限制行号。

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 个答案:

答案 0 :(得分:1)

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

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

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

order by子句将放在生成的子选择hibernate中(在限制到页面之前对完整的结果集进行排序):

 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 <= ?
相关问题