mybatis(7) - 分页

在处理sql分页的场景,可与选择在内存中对所有数据进行sublist,或在写sql时指定limit。那如何利用mybatis的特性在处理分页呢?java

 

物理分页-sql语句指定limit

适用于数据量大的状况下。sql

limit的效能越到后面越慢,以LIMIT N,M为基础:LIMIT首先要找查N+M行,而后从N行处,取M行;因此在大数量作分页查询时,越日后分页,LIMIT语句的偏移量就越大,速度也明显变慢 。对于LIMIT这类的优化:数组

  1. 第一个目标就是让N变的尽量的小或是不用。
  2. 尽量的明确好查询的限制条件,精确缩小数据范围。
  1. 第一种: 在真正执行sql以前,经过对StatementHandler的拦截,对原有的sql (statementHandler.getBoundSql().getSql)拼接limit语句。
    自定义插件Interceptor 方式: @Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class})})
  2. 第二种: 直接在sql.xml中的sql语句中显示申明limit语句。

RowBounds对于limit的处理

数据量小时可用。mybatis

用起来极为方便,先给接口增长一个RowBounds参数。app

public List<RoleBean> queryRolesByPage(String roleName, int start, int limit) {
        return roleDao.queryRolesByPage(roleName, new RowBounds(start, limit));
    }

MyBatis在初始化每一个Mapper的代理对象MapperProxy时,会经过MethodSignature来标记每个mapper方法中的RowBounds在方法argument数组的位置。优化

MapperMethod.execute 选择分支方法executeWithResultHandler 里会获取到RowBounds传递到构建的StatementHandler 对象中(内部成员变量ResultSetHandler 也绑定该RowBounds)。 由ResultSetHandler.handleResultSets 最终调用handleRowValues方法解析数据时根据RowBounds参数进行分页。spa

RowBounds中有两个数字,offset和limit。在处理分页时,在DefaultResultSetHandler中,只是简单的把offset以前的数据都skip掉,超过limit以后的数据不取出。 就是先把数据所有查询到ResultSet,而后从ResultSet中取出offset和limit之间的数据。插件

相关文章
相关标签/搜索