MyBatis中的RowBounds

转载自  MyBatis中的RowBounds

一、如何分页查询

Mybatis如何分页查询?Mysql中可以使用limit语句,但limit并不是标准SQL中的,如果是其它的数据库,则需要使用其它语句。MyBatis提供了RowBounds类,用于实现分页查询。RowBounds中有两个数字,offset和limit。

 

二、MyBatis如何利用RowBounds实现通用分页

在查询数据库时,如果没有limit语句,则ResultSet中会包含所有满足条件的数据,


RowBounds在处理分页时,只是简单的把offset之前的数据都skip掉,超过limit之后的数据不取出,上图中的代码取自MyBatis中的DefaultResultSetHandler类。跳过offset之前的数据是由方法skipRows处理,判断数据是否超过了limit则是由shouldProcessMoreRows方法进行判断。简单点说道,就是先把数据全部查询到ResultSet,然后从ResultSet中取出offset和limit之间的数据,这就实现了分页查询。

从两种场景下说明RowBounds的使用

    SqlSession,使用SqlSession时,selectList有一个重载的方法,带有RowBounds参数,这种情况下,DAO层的实现了,可以对外界隐藏RowBounds类。如下图,Page是自定义的一个接口,用于表示分页信息,不直接使用RowBounds源于自己的一个习惯,不喜欢在Service层中侵入持久层所使用的持久化技术的类或接口。如果在Service中使用了RowBounds,Service与MyBatis就耦合了,当然,如果不要求这一点,直接要Service里写RowBounds对象也是可以的。

    1.映射接口,MyBatis提供了映射接口的形式,这种情况下,可以不写DAO接口的实现即可完成DAO层,这种情况下,DAO接口写成List<User> vip(RowBounds page),这种情况下,mybatis会完成分页查询。

回到Page接口,如果类与接口之间的关系如右类图,DAO中的方法还是vip(Page page),而调用的时候,工厂返回了一个MyBatisPage类的对象给DAO,因为MyBatisPage类继承自RowBounds类,所以此时传给DAO的Page对象也是一个RowBounds类的对象,但这种情况下却不会有分页查询的效果。

MyBatisPage类相当于一个适配器,用于适配Page接口与RowBounds,但为何给DAO一个RowBounds对象时,却没有实现分页效果,原因是MyBatis判断方法的参数中有没有RowBounds参数是在产生接口的代理时,而不是在方法调用的时候。根据DefaultSqlSession类的getMapper方法可以很快找到MapperProxyFactory类,此类的作用就是创建接口的动态代理,所以方法的调用逻辑应该要看代理的InvocationHandler对象,它是MapperProxy类,这里的处理调用比较深,在MapperProxy类中可以发现,每一个DAO接口上的方法都会对应一个MapperMethod类的对象,MapperMethod类中有一个内部类MethodSignature,这是关键的地方,每一个MapperMethod对象都依赖于一个MethodSignature对象,看看此类的构造器:

rowBoundsIndex,这个属性是用于记录MapperMthod对应的方法的参数中,RowBounds是第几个参数,getUniqueParamIndex方法的实现中,如果发现没有Rowbounds参数,则返回null,由此可见,如果DAO的方法签名为vip(Page page),则rowBoundsIndex为null,所以在调用的时候,即使Page接口的实例也是一个RowBounds的实例,也不会有分页效果。

    如果想要解决这个限制,付出的代价有点大。与Spring框架不同的是,Spring中,类与类之间依赖的是接口而不是具体类。而MyBatis从DefaultSqlSesison到MethodProx,全部依赖的是具体类,这些类没有接口,如果要想解决这个限制,需要子类化DefaultSqlSession,Configuration,MapperRegistry,MapperProxyFactory,MapperProxy,MapperMethod和MethodSignature,这些类都没有实现某个可扩展的接口,甚至没有实现接口,全部是依赖具体的类,无法从其中某个点进行扩展。至于MapperProxyFactory,它无法替换成其它工厂类,它仅仅只是隐藏了接口的代理的创建方式。

 

RowBounds没有覆盖equals和hashCode方法


    如果RowBounds在Service中直接new了,则在测试Service时,在mock时使用了when这样的方法,如:when(userDao.vip(rowBounds)).xxx,那么就会发生错误,因为在Service中也会new一个RowBounds,即使Service中new的那个RowBounds和单元测试中的RowBoumds的offset和limit两个数都一样,rowBounds.equals(row)也不会返回true,当然,可以使用when(userDao.vip(anyObject()))。

如何解决这个问题?有两种方式,一种是RowBounds作为参数传入Service,另一种是使用适配器,这个适配器很简单,写个RowBounds的子类,在子类中覆盖hashCode&equals方法,在Service中使用新的类。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/322681.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vscode插件以及配置

插件&#xff1a; Auto Rename Tag indent-rainbow 好看多彩的缩进空格 Dracula Officila 吸血鬼主题 Rainbow Brackets 彩虹括号&#xff0c;强烈推荐 快捷键&#xff1a; 代码折叠&#xff1a; 1、Ctrl键 Shift键 [键 折叠 2、Ctrl键 Shift键 ]键 展开 多行选中 &#x…

使用 MQTTnet 快速实现 MQTT 通信

1 什么是 MQTT &#xff1f; MQTT&#xff08;Message Queuing Telemetry Transport&#xff0c;消息队列遥测传输&#xff09;是 IBM 开发的一个即时通讯协议&#xff0c;有可能成为物联网的重要组成部分。MQTT 是基于二进制消息的发布/订阅编程模式的消息协议&#xff0c;如今…

P1726-上白泽慧音【tarjan,图论】

正题 题目链接:https://www.luogu.org/problemnew/show/P1726 题目大意 求最大的强联通分量和包含的点 解题思路 tarjantarjantarjan模板不解释。 codecodecode #include<cstdio> #include<algorithm> #include<stack> using namespace std; const int N5…

Maven的pom.xml文件详解------Build Settings

转载自 Maven的pom.xml文件详解------Build Settings 根据POM 4.0.0 XSD&#xff0c;build元素概念性的划分为两个部分&#xff1a;BaseBuild&#xff08;包含poject build和profile build的公共部分&#xff0c;见下&#xff09;和poject build包含的一些高级特性。 <p…

git代码合并冲突与撤回提交

查看版本 切回到某一个版本 git log --graph --abbrev-commit --decorate --prettyoneline git reset --hard a07cefe git有一种情况会造成代码被冲掉&#xff1a; 这里有A端和B端&#xff1a; 相同文本基础之上 A端写了大量代码&#xff0c;提交推送 B端拉取&#xff0c;改了代…

Asp.net Core中SignalR Core预览版的一些新特性前瞻,附源码(消息订阅与发送二进制数据)

前言 一晃一个月又过去了,上个月有个比较大的项目要验收上线.所以忙的脚不沾地.现在终于可以忙里偷闲,写一篇关于SignalR Core的文章了. 先介绍一下SignalR吧,如下: ASP.NET SignalR是ASP.NET开发人员的一个库&#xff0c;它简化了向Web应用程序添加即时通讯功能的过程。 它可以…

P3225-[HNOI2012]矿场搭建【tarjan,图论】

正题 题目链接:https://www.luogu.org/problemnew/show/P3225 题目大意 nnn个点的无向图&#xff0c;要求设置逃生点使得任意一个点去掉后每联通分量内都有一个逃生点。求至少多少个逃生点和方案数。 解题思路 首先tarjantarjantarjan求出割点&#xff0c;然后对于一个分量内…

Maven的pom.xml文件详解------Environment Settings

转载自 Maven的pom.xml文件详解------Environment Settings Issue Management 使用的缺陷跟踪系统&#xff08;Bugzilla&#xff0c;TestTrack&#xff0c;ClearQuest&#xff0c;等&#xff09;信息&#xff0c;主要用于产生项目文档。 <issueManagement><system…

大二暑假工作三个月后辞职,总体感悟

本人是个大二的学生&#xff0c;因为疫情影响&#xff0c;学校放了很长时间的假。当时对自己的前端技术很自信&#xff0c;大概在五月底的时候决定去上海闯一下&#xff0c;找个工作&#xff0c;不管能不能找到&#xff0c;就是尝试一下&#xff0c;失败了也没关系&#xff0c;…

P5004-专心OI - 跳房子【dp,矩阵乘法】

正题 题目链接:https://www.luogu.org/problemnew/show/P5004 题目大意 把NNN个无色格子排成一行&#xff0c;可以把某些格子染成黑色&#xff0c;但两个黑色格子之间必须至少有MMM个无色格子&#xff0c;求方案数 解题思路 首先很明显 fn∑i0n−m−1fif_n\sum_{i0}^{n-m-1}…

35年编程史沉淀下来的8条宝贵经

01 1. 时刻提醒自己&#xff1a;学习 学习某件事的第一步是承认你不知道。这听起来很正常&#xff0c;但经验丰富的程序员还记得要真正让自己承认这一点需要花多长时间。很多计算机科学专业的学生毕业的时候&#xff0c;都有一种很傲慢的态度&#xff0c;就是“我知道最好的”&…

Maven的pom.xml文件详解------The Basics

转载自 Maven的pom.xml文件详解------The Basics Maven坐标 GroupId、artifactId和version构成了Maven的坐标&#xff08;groupId和version可以从parent继承&#xff09;&#xff0c;指定了组件在Maven仓库中的位置。Maven中的每个组件都有一个坐标&#xff0c;通过这个坐标…

php artisan快捷命令

远程启动laravel&#xff1a; php artisan serve --host 0.0.0.0 创建新的Controller php artisan make:controller loginController 创建快捷资源Controller php artisan make:controller ArticlesController --resource 对应的创建快捷路由 Route::resource(‘articles’,…

P1407-[国家集训队]稳定婚姻【tarjan,强连通分量】

正题 题目链接:https://www.luogu.org/problemnew/show/P1407 题目大意 若干对夫妻&#xff0c;和若干对绿色关系&#xff0c;求每对夫妻离婚后&#xff0c;绿色关系是否可以重新让每个人两两配对。 解题思路 我们可以让 夫妻女的连男的 交往男的连女的 然后跑tarjantarjan…

基于Emgu CV+百度人脸识别,实现视频动态 人脸抓取与识别

背景 目前AI 处于风口浪尖&#xff0c;作为 公司的CTO&#xff0c;也作为自己的技术专研&#xff0c;开始了AI之旅&#xff0c;在朋友圈中也咨询 一些大牛对于AI 机器学习框架的看法&#xff0c;目前自己的研究方向主要开源的 AI 库&#xff0c;如&#xff1a;Emgu CV、TensorF…

Lombok的@Data生成的hashCode和equals方法坑

一、场景复现 创建两个lombok的Data注解的类Pig实例&#xff0c;放进HashMap当key&#xff0c;map里面的数据居然被覆盖了。 package com.mk;import lombok.Data; Data public class Pig extends Animal{private String sex; }package com.mk;import java.util.HashMap; impo…

vscode多行选中

shiftalt移动光标&#xff0c;可以连续同时编辑多行内容

jzoj4671-World Tour【图论,bfs】

正题 luogu题目链接:https://www.luogu.org/problemnew/show/CF666B 题目大意 求4个点&#xff0c;使得这4个点按顺序最短路到达的长度最远。 解题思路 用bfsbfsbfs求出每个点之间的最短路&#xff0c;然后对于每个点求出最远点&#xff0c;次远点&#xff0c;反最远点和反次…

vue-cli2、vue-cli3脚手架详细讲解

转载自 vue-cli2、vue-cli3脚手架详细讲解 前言&#xff1a; vue脚手架指的是vue-cli它是vue官方提供的一个快速构建单页面&#xff08;SPA&#xff09;环境配置的工具&#xff0c;cli 就是(command-line-interface ) 命令行界面 。vue-cli是基于node环境利用webpack对文件进…

微软为.NET程序员带来了最优的跨平台开发体验-WSL

前言 在前几个Visual Studio Code更新中发现有一个重要得特性&#xff0c;就是nodejs可以使用VS Code在WSL中进行Debug了&#xff08;WSL是指Win10中的Linux子系统&#xff09;,之前写过一篇文章是使用SSH对Linux环境进行Debug&#xff0c;此时的想法就是如果可以在WSL中直接对…