Mybatis collection标签配合PageHapler分页问题


一、问题现象

在mybatis的resultMap标签中使用collection或者assocation做嵌套结果映射,再配合PageHalper实现分页效果的时候,会出现两个问题:

  1. 实际查出来的数据,会部分丢失,比如传的页面大小是10条,那么有可能会返回小于10条记录。
  2. 分页对象的total总数与实际返回的数量不一致。

二、问题原因

在定位问题前,我们先了解下PageHalper的工作原理,PageHapler主要是通过拦截器实现的,在执行sql前会根据页码和页数在sql的后面加上关键字,比如limit,rownum等。

在PageHapler拦截SQL添加分页关键字成功后,由于嵌套结果集的方式会导致结果集被折叠,因此分页查询后的结果在折叠后总数会减少,所以无法保证分页结果数量正确。

在PageHapler官网的常见问题列表中也有对此问题的说明:

为什么不支持一对一和一对多结果映射的分页查询?

在一对一和一对多时,根据分页条件查询出 100 条数据时,由于一对一和一对多会去重,经过嵌套处理后数据量会减少,因此分页想要获得 100 条数据无法实现。想要支持这种情况可以使用嵌套查询。嵌套查询是要额外执行SQL,主SQL可以得到正确的结果数量,因此可以正常分页。

三、解决方法

  1. 使用mybatis的嵌套查询,在resultMap的collection标签中使用select属性额外执行SQL,如果数据量比较大的时候,可能对性能影响严重。

    <resultMap id="list" type="com.xxx.xxx.entity.xxxxxxx">
      <id column="id_" property="id"/>
      <result column="name_" property="name"/>
      <collection property="users"
                  javaType="java.util.ArrayList"
                  ofType="com.xxx.xxx.xxx.xxx"
                  select="com.xxx.xxx.xxx.xxx.xxxx"
                  column="{id=id_}"/>

    </resultMap>
  2. 在业务层service中,拿到主SQL的结果集,再传入条件去执行额外SQL获取结果集。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM