mybatis中的动态sql表现为_MybatisPlus

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

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

如何分页查询

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

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

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

mybatis中的动态sql表现为_MybatisPlus

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

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

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

mybatis中的动态sql表现为_MybatisPlus

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

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

mybatis中的动态sql表现为_MybatisPlus

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

mybatis中的动态sql表现为_MybatisPlus

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

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

RowBounds没有覆盖equalshashCode方法

mybatis中的动态sql表现为_MybatisPlus

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/190672.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • C++实现二叉树层序遍历

    C++实现二叉树层序遍历层序遍历图示实现二叉树的层次遍历,要利用到队列。基本思想:1.先将根节点放到队列中2.根节点弹出队列,然后将根节点的左、右儿子入队3.弹出左儿子,放入左儿子的左右儿子4.弹出右儿子,放入右儿子的左右儿子5.重复3、4步图示过程:所用的二叉树如下队列的操作:将根节点弹出,放入左右儿子:将B节点弹出,放入左右儿子(只有右儿子):把D节点弹出,放入左右儿子:C、E、F都没有儿子节点,所以直接弹出队列即可: C++代码实现1.利用前序遍历思想输入二叉树。(前序

    2022年5月21日
    28
  • Tensorflow2.0使用Resnet18进行数据训练[通俗易懂]

    Tensorflow2.0使用Resnet18进行数据训练[通俗易懂]在今年的3月7号,谷歌在TensorflowDeveloperSummit2019大会上发布TensorFlow2.0Alpha版,随后又发布的了Beta版本。Resnet18结构Tensorflow搭建Resnet18导入第三方库importtensorflowastffromtensorflowimportkerasfromtensorflo…

    2022年5月9日
    156
  • 本地服务器跟本地工作目录同步的路径

    本地服务器跟本地工作目录同步的路径

    2022年2月23日
    37
  • pycharm需要安装哪些包_用于引入包的关键字

    pycharm需要安装哪些包_用于引入包的关键字在学习python的时候,被推荐了使用PyCharm这款IDE,但是在import包的时候却发生了问题–无法引入,但是明明通过了pip进行模块的加载,百度之后,了解到,在这款IDE中,要导入包,需要手动进行引入。如下图所示首先在file中找到settings顺带一下,如果有的同学是第一次接触这款IDE,可能对与皮肤颜色不太了解,其实也是在settings中进行设置的,而且该公司旗下的其他产品如…

    2022年8月28日
    3
  • 2021年Spring面试题70道「建议收藏」

    2021年Spring面试题70道「建议收藏」文章目录2021年Spring面试题70道前言Spring面试题内容1.谈谈你对Spring的理解?2.Spring的特点是什么?3.Spring的优缺点是什么?4.Spring由哪些模块组成?5.详细讲解一下核心容器(springcontext应用上下文)模块6.解释AOP模块7.解释JDBC抽象和DAO模块8.解释对象/关系映射集成(ORM)模块9.解释WEB模块10.Spring配置文件11.什么是SpringIoC容器。12.控制反转(IoC)有什么作用13.控制反转

    2022年10月9日
    2
  • linux命令export什么意思_shell脚本执行oracle语句

    linux命令export什么意思_shell脚本执行oracle语句Linuxexport命令用法Linuxexport命令用于设置或显示环境变量。在shell中执行程序时,shell会提供一组环境变量。export可新增,修改或删除环境变量,供后续执行的程序使用。export的效力仅限于该次登陆操作。export[-fnp][变量名称]=[变量设置值]参数说明:-f 代表[变量名称]中为函数名称。-n 删除指定的变量。变量实际上并未删除,只是不会输出到后续指令的执行环境中。-p 列出所有的shell赋予程序的环境变量。示例

    2025年9月30日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号