zoukankan      html  css  js  c++  java
  • Ibatis的分页机制的缺陷

    我们知道,Ibatis为我们提供了可以直接实现分页的方法

    queryForList(String statementName, Object parameterObject, int skipResults, int maxResults)

    参数:

    statementName :要调用的statement

    parameterObject: 参数对象

    skipResults    :要查询的起始记录   ((page.getPageNo()-1)*page.getPageSize())

    maxResults:   返回的最大记录条数   (page.getPageSize())

      private void handleResults(RequestScope request, ResultSet rs, int skipResults, int maxResults, RowHandlerCallback callback) throws SQLException {
        try {
          request.setResultSet(rs);
          ResultMap resultMap = request.getResultMap();
          if (resultMap != null) {
            // Skip Results
            if (rs.getType() != ResultSet.TYPE_FORWARD_ONLY) {
              if (skipResults > 0) {
                rs.absolute(skipResults);
              }
            } else {
              for (int i = 0; i < skipResults; i++) {
                if (!rs.next()) {
                  break;
                }
              }
            }
    
            // Get Results
            int resultsFetched = 0;
            while ((maxResults == SqlExecutor.NO_MAXIMUM_RESULTS || resultsFetched < maxResults) && rs.next()) {
              Object[] columnValues = resultMap.resolveSubMap(request, rs).getResults(request, rs);
              callback.handleResultObject(request, columnValues, rs);
              resultsFetched++;
            }
          }
        } finally {
          request.setResultSet(null);
        }
      }


    这个方法是翻阅ibatis源代码中找到的它实现分页查询的方法。

    首先rs  是传过来的参数,rs在上级方法中是执行我们写的sql语句,将数据库中符合条件的所有数据查询出来得到的结果集

    ResultSet.TYPE_FORWARD_ONLY是java.sql.ResultSet接口的方法,指的是数据库中的结果集只支持向前滚动。

    rs.absolute(skipResults)   将游标移到相对第一行的指定行  为负数的话就是相对最后一行

    下面的while就是取出我们最终要的分页结果放到某个对象中,返回给我们的查询方法。


    通过分析源代码可知,ibatis分页有着很大的缺陷,首先将数据库中的所有数据取出来占用内存,其二采取游标滚动的方式取出我们所要的记录效率太低。我通过实际的例子测试,数据库中有300万条数据,每页显示10条,通过调用ibatis的分页方法和oracle 的sql两种方式实现分页查询。

    结果表明,在前几页的查询两者效率相差不大,因为oracle的sql实现的分页也是将所有的数据查出来然后通过rownum属性取出我们所需要的。

    越往后翻页ibatis分页的弱势(游标需要逐行滚动到2999990条)就越大,点击"尾页"链接进行查询后ibatis的分页查询已经比oracle sql的分页查询慢了5倍以上。



    附  oracle sql分页的实现方法:

    	<sql id="pageStart">
    		<![CDATA[   select * from (select row_.*, rownum rownum_ from (	  ]]>
    	</sql>
    	<sql id="pageEnd">
    		<![CDATA[   )row_ where rownum<=#end# ) where rownum_>=#start#  ]]>
    	</sql>
    	<!-- sql语句 -->
    	<sql id="queryXsSql">
    		SELECT XS_ID,
    		       XS_NAME,
    		       XS.ZY_ID,
    		       XS_NUM,
    		       XS_SFZ,
    		       XS_TEL,
    		       XS_EMAIL,
    		       XS_ADDRESS,
    		       XS_DATE,
    		       XS_SEX,
    		       ZY.ZY_NAME,
    		       XY.XY_NAME
    		  FROM XS XS
    		 INNER JOIN ZY ZY
    		    ON XS.ZY_ID = ZY.ZY_ID
    		 INNER JOIN XY
    		    ON XY.XY_ID = ZY.XY_ID
    		 <dynamic prepend="where">
    		 	<isNotEmpty prepend="and"  property="xs_name"  >
    		 		xs.xs_name like '%'||#xs_name#||'%'
    		 	</isNotEmpty>
    		 	<isNotEmpty prepend="and"  property="xs_num"  >
    		 		xs.xs_num like '%'||#xs_num#||'%'
    		 	</isNotEmpty>		 	
    		 	<isEqual prepend="and"  property="xs_sex"  compareValue="0"  >
    		 		xs.xs_sex='0'
    		 	</isEqual>
    		 	<isEqual prepend="and"  property="xs_sex"  compareValue="1" >
    		 		xs.xs_sex='1'
    		 	</isEqual>
    		 	<isNotEmpty prepend="and" property="dateFrom" >
    		 		<![CDATA[	
    		 		to_date(xs.xs_date,'yyyy-MM-dd')>=to_date(#dateFrom#,'yyyy-MM-dd')
    		 		]]>
    		 	</isNotEmpty>
    		 	<isNotEmpty prepend="and" property="dateTo" >
    		 		<![CDATA[	
    		 		to_date(xs.xs_date,'yyyy-MM-dd')<=to_date(#dateTo#,'yyyy-MM-dd')
    		 		]]>
    		 	</isNotEmpty>	
    		 	
    		 </dynamic>
     			order by  xs.xs_id  desc	 	
    	</sql>
    	<select id="queryByOrclPage"  parameterClass="com.bh.chc.manager.xs.XueShengPage"  resultClass="xuesheng">
    		<include refid="pageStart"/>
    		<include refid="queryXsSql"/>
    		<include refid="pageEnd"/>
    	</select>
    	
    	<select id="queryByOrclPageCount" resultClass="java.lang.Integer" parameterClass="com.bh.chc.manager.xs.XueShengPage">
    		select count(*)
    		from 
    		(
    			<include refid="queryXsSql"/>
    		)
    	</select>



  • 相关阅读:
    java入门经验分享——记面向对象先导课程学习感想
    HashCode方法整理
    Java中vector用法整理
    Java中Iterator用法整理
    org.springframework.data.redis.RedisConnectionFailureException
    dubbo服务启动正常,但是访问不到服务,在监测中心也找不服务的原因之一
    【转】Elasticsearch Java Rest Client 指南
    【转】mybatis根据mapper执行sql的过程
    转:IDEA异常解决: org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
    ES的常用查询与聚合
  • 原文地址:https://www.cnblogs.com/riasky/p/3476501.html
Copyright © 2011-2022 走看看