Mybatis逻辑分页原理解析RowBounds
Mybatis提供了一个简单的逻辑分页使用类RowBounds(物理分页当然就是我们在sql语句中指定limit和offset值),在DefaultSqlSession提供的某些查询接口中我们可以看到RowBounds是作为参数用来进行分页的,如下接口:
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds)
RowBounds源码如下:
public class RowBounds {
/* 默认offset是0**/
public static final int NO_ROW_OFFSET = 0;
/* 默认Limit是int的最大值,因此它使用的是逻辑分页**/
public static final int NO_ROW_LIMIT = Integer.MAX_VALUE;
public static final RowBounds DEFAULT = new RowBounds();
private int offset;
private int limit;
public RowBounds() {
this.offset = NO_ROW_OFFSET;
this.limit = NO_ROW_LIMIT;
}
public RowBounds(int offset, int limit) {
this.offset = offset;
this.limit = limit;
}
public int getOffset() {
return offset;
}
public int getLimit() {
return limit;
}
}
逻辑分页的实现原理:
在DefaultResultSetHandler中,逻辑分页会将所有的结果都查询到,然后根据RowBounds中提供的offset和limit值来获取最后的结果,DefaultResultSetHandler实现如下:
private void handleRowValuesForSimpleResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping)
throws SQLException {
DefaultResultContext<Object> resultContext = new DefaultResultContext<Object>();
//跳过RowBounds设置的offset值
skipRows(rsw.getResultSet(), rowBounds);
//判断数据是否小于limit,如果小于limit的话就不断的循环取值
while (shouldProcessMoreRows(resultContext, rowBounds) && rsw.getResultSet().next()) {
ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(rsw.getResultSet(), resultMap, null);
Object rowValue = getRowValue(rsw, discriminatedResultMap);
storeObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet());
}
}
private boolean shouldProcessMoreRows(ResultContext<?> context, RowBounds rowBounds) throws SQLException {
//判断数据是否小于limit,小于返回true
return !context.isStopped() && context.getResultCount() < rowBounds.getLimit();
}
//跳过不需要的行,应该就是rowbounds设置的limit和offset
private void skipRows(ResultSet rs, RowBounds rowBounds) throws SQLException {
if (rs.getType() != ResultSet.TYPE_FORWARD_ONLY) {
if (rowBounds.getOffset() != RowBounds.NO_ROW_OFFSET) {
rs.absolute(rowBounds.getOffset());
}
} else {
//跳过RowBounds中设置的offset条数据
for (int i = 0; i < rowBounds.getOffset(); i++) {
rs.next();
}
}
}
总结:Mybatis的逻辑分页比较简单,简单来说就是取出所有满足条件的数据,然后舍弃掉前面offset条数据,然后再取剩下的数据的limit条
Mybatis逻辑分页原理解析RowBounds的更多相关文章
- Mybatis 插件原理解析
SqlSessionFactory 是 MyBatis 核心类之一,其重要功能是创建 MyBatis 的核心接口 SqlSession.MyBatis 通过 SqlSessionFactoryBuil ...
- Mybatis(四):MyBatis核心组件介绍原理解析和源码解读
Mybatis核心成员 Configuration MyBatis所有的配置信息都保存在Configuration对象之中,配置文件中的大部分配置都会存储到该类中 SqlSession ...
- Mybatis插件原理分析(二)
在上一篇中Mybatis插件原理分析(一)中我们主要介绍了一下Mybatis插件相关的几个类的源码,并对源码进行了一些解释,接下来我们通过一个简单的插件实现来对Mybatis插件的运行流程进行分析. ...
- 面试官:你分析过mybatis工作原理吗?
Mybatis工作原理也是面试的一大考点,必须要对其非常清晰,这样才能怼回去.本文建立在Spring+SpringMVC+Mybatis整合的项目之上. 我将其工作原理分为六个部分: 读取核心配置文件 ...
- 【转】MaBatis学习---源码分析MyBatis缓存原理
[原文]https://www.toutiao.com/i6594029178964673027/ 源码分析MyBatis缓存原理 1.简介 在 Web 应用中,缓存是必不可少的组件.通常我们都会用 ...
- MyBatis实战之解析与运行
本次所谈的原理仅仅只涉及基本的框架和核心代码,并不会全部都说到,比如关于MyBatis是如何解析XML文件和其他配置文件从而的到内容,还有就是JDBC如何使用,关于JDBC如何使用,可以参考我的这篇博 ...
- MyBatis 原码解析(version:3.2.7)
mybatis-plus 实践及架构原理.pdf mybatis-plus思维导图 首先,我们看使用原生的JDBC来操作数据库的方式: // 1. 获取JDBC Connection Connecti ...
- Mybatis架构原理(二)-二级缓存源码剖析
Mybatis架构原理(二)-二级缓存源码剖析 二级缓存构建在一级缓存之上,在收到查询请求时,Mybatis首先会查询二级缓存,若二级缓存没有命中,再去查询一级缓存,一级缓存没有,在查询数据库; 二级 ...
- 【MyBatis源码解析】MyBatis一二级缓存
MyBatis缓存 我们知道,频繁的数据库操作是非常耗费性能的(主要是因为对于DB而言,数据是持久化在磁盘中的,因此查询操作需要通过IO,IO操作速度相比内存操作速度慢了好几个量级),尤其是对于一些相 ...
随机推荐
- Echarts 中国地图各个省市自治区自定义颜色
前言 最近接了一个外包的项目,其中有个需求是这样的, 需要展示一个中国的统计地图,要求每个省市区都是不一样的颜色,必须特别区分开.以及隐藏南海部分. 看了Echats相关文档,发现有类似的demo,但 ...
- MySQL查看数据库信息
使用MySQL时,需要了解当前数据库的情况,例如当前的数据库大小.字符集.用户等等.下面总结了一些查看数据库相关信息的命令 1:查看显示所有数据库 mysql> show databases; ...
- day05 Servlet 开发和 ServletConfig 与 ServletContext 对象
day05 Servlet 开发和 ServletConfig 与 ServletContext 对象 1. Servlet 开发入门 - hello world 2. Servlet 的调用过程和生 ...
- ECC公钥格式详解
本文首先介绍公钥格式相关的若干概念/技术,随后以示例的方式剖析DER格式的ECC公钥,最后介绍如何使用Java生成.解析和使用ECC公钥. ASN.1 Abstract Syntax Notation ...
- ftp:connect:未知错误号
Linux下使用ftp命令时,提示:ftp: connect :未知错误号解决方法:service iptables stop或/etc/rc.d/init.d/iptables stop
- LintCode题解之统计数字
直接硬搜就可以了,只是需要考虑k为0的情况. public class Solution { /* * @param : An integer * @param : An integer * @ret ...
- Launcher3 HotSeat显示名称
今天闲的无聊,研究了下launcher代码,看到Hotseat.java的时候,想起来以前有做过显示hotseat中应用名称,因为换了公司代码都没拿出来,就想在试着修改,看了很久发现无从下手,记得ho ...
- linux 防火墙操作
root/12345 (只能用ROOT操作)iptables -I INPUT -s x.x.x.x -p tcp --dport 8091 -j ACCEPT #允许x.x.x.x访问本机的80 ...
- Android的Ui层次
UI 概览 Android 应用中的所有用户界面元素都是使用 View 和 ViewGroup 对象构建而成.View 对象用于在屏幕上绘制可供用户交互的内容.ViewGroup 对象用于储存其他 V ...
- ROS(indigo) 用于机器人控制的图形化编程工具--code_it robot_blockly
0 简介: 编程语言有汇编,高级语言,解释语言等,现在图形化编程也越来越流行.图形化编程简单易学.8年前,微软推出了VPL用于机器人程序设计,如Python和JavaScript都可以用图形化框图实现 ...