MyBatis进阶之分页和延迟加载

在这里插入图片描述

文章目录

  • 分页
    • 1. RowBounds 分页
    • 2. PageHelper 分页
    • 3. PageInfo 对象属性描述
  • 延迟加载
    • 立即加载
    • 激进式延迟加载
    • 真-延迟加载

分页

Mybatis 中实现分页功能有 3 种途径:

  • RowBounds 分页(不建议使用)
  • Example 分页(简单情况可用)
  • PageHelper 分页(推荐 )

1. RowBounds 分页

MyBatis 本身通过 RowBounds 对象提供了分页功能,你仅需为你的 dao 的查询方法多添加 RowBounds 类型的一个参数,并且不需要对配置文件做任何调整。

RowBounds 也称原生分页、逻辑分页。
RowBounds bounds = new RowBounds(0, 4);
List<Employee> list = dao.select(bounds);

但是这种分页是一种 逻辑分页,MyBatis 并未使用 limit 子句,查询的仍是 所有数据,只是它仅给你「看」到了所有数据中的一部分,逻辑分页虽然完成了分页功能,但是它并未通过分页功能的对性能问题有所提升。

2. PageHelper 分页

PageHelper 是一款被广泛使用的 MyBatis 插件。它通过 Mybatis 的插件机制,巧妙地通过机制,在不需要配置文件(不需要写 limit 子句)的情况下,动态去修改你所执行的 SQL,在其后动态添加 limit 子句。

为了使用 PageHelper 需要引入相应的包:

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.1.8</version>
</dependency>

PageHelper 是一款 MyBaits 插件,使用它需要向 Mybatis 注册 PageHelper,并对它作出相关配置(mybatis-config.xml)。

<plugins>
  <!-- com.github.pagehelper 为 PageHelper 类所在包名 -->
  <plugin interceptor="com.github.pagehelper.PageInterceptor">
    <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
    <property name="helperDialect" value="mysql" />
    <property name="..." value="..."/>
  </plugin>
</plugins>

警告
pagehelper 有 4.x 和 5.x 两个版本,用法有所不同,并不是向下兼容,同样的配置在使用 4.x 或 5.x 版本中可能会报错。例如,上面的 helperDialect 就是 5.x 中的配置,在 4.x 中使用的是 dialect

如果 Mybatis 整合进了 Spring,除了上述这样配置外,还可以将相应的注册-配置工作就在 Spring 的配置文件中进行:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  <property .../>

  <property name="plugins">
    <array>
      <bean class="com.github.pagehelper.PageInterceptor">
        <property name="properties">
          <!--使用下面的方式配置参数,一行配置一个 -->
          <value>
            param1=value1
            param2=value2
            ...
          </value>
        </property>
      </bean>
    </array>
  </property>
</bean>

插件的属性配置

  • helperDialect

    用于指明底层数据库类型:oracle, mysql, mariadb, sqlite, hsqldb, postgresql, db2, sqlserver, informix, h2, sqlserver2012, derby

  • reasonable

    是否启用『合理化』功能

    启用(true)时,如果 pageNum < 1,会返回第一页内容;如果 pageNum > pages,会返回查询最后一页。

    禁用(false)时,超出合理的范围会直接返回空数据。

在使用 PageHelper 时,PageHelper 提供了 2 种风格来描述分页:

  • pageNum / pageSize 组合

插件作者建议推荐方式

PageHelper.startPage(1, 10);

这种风格实际上是在模拟「人的语气」。

  • offset / limit 组合
PageHelper.offsetPage(0, 3);

很显然,这种风格就是 SQL 语句的分页写法

在你调用查询方法之前,调用 PageHelper 的上述两个方法中的任意一个,都可激活 PageHelper 插件的分页功能,使其动态地『帮』你修改SQL语句(添加 limit 子句)。而 Mybatis 的 select 返回的结果就返回的是一页数据。

PageHelper.startPage(4, 2);
List<Employee> list = empDao.selectByExample(null);
PageInfo<Employee> info = new PageInfo<>(list, 5);

System.out.println(info);

注意
由于 PageHelper 插件的实现涉及到 ThreadLocal 原理,这导致一旦 PageHelper 生产了一个分页参数(一个内部使用的 Page 对象),但是没有被消费,这个参数就会一直保留在这个线程的 ThreadLocal 中。当这个线程再次被使用时,就可能导致不该分页的方法去消费这个分页参数,这就产生了莫名其妙的分页。所以,分页参数的创建代码,和查询方法的调用代码,必须「紧密的在一起」。

PageHelper 插件流行的原因在于,它不仅仅能实现分页功能,而且还进一步封装了页面上的『分页导航条』所需要的所有相关信息。

在使用 PageHelper 的过程中,我们已经提供了 4 个关键数据:

PageHelper.startPage(4, 2); // 当前页的页号, 每页显示的数据量
...
PageInfo<Employee> info = new PageInfo<>(list, 5); // 查询结果, 导航栏上导航数字的个数

在创建了 PageInfo 之后便可以使用它:

// << < 2 3 [4] 5 6 > >>

log.info("是否有下一页:{}", pageInfo.isHasNextPage());
log.info("是否有上一页:{}", pageInfo.isHasPreviousPage());
log.info("导航栏上第一个页号:{}", pageInfo.getNavigateFirstPage());
log.info("导航栏上最后一个页号:{}", pageInfo.getNavigateLastPage());
log.info("导航栏上的五个导航数字:{}", Arrays.toString(pageInfo.getNavigatepageNums()));
log.info("共有 {} 页", pageInfo.getPages());
log.info("{} / {} ", pageInfo.getPageNum(), pageInfo.getPages());
log.info("共有 {} 条数据", info.getTotal());

3. PageInfo 对象属性描述

属性说明举例
int pageNum当前页比如,当前为第 5
int pageSize每页的数量比如,每页(计划/预期)显示 10 条数据
int size当前页的数量比如,以 98 条总数据为例,每页最多显示 10 条(最后一页显示 8 条数据)
int startRow当前页面第一个元素在数据库中的行号比如,以 98 条总数据的最后一页为例,第一条数据是第 91
int endRow当前页面最后一个元素在数据库中的行号比如,以 98 条总数据的最后一页为例,最后一条数据是第 98
int pages总页数比如,以 98 条总数据为例,每页显示 10 条(其中最后一页 8 条),因此共 10
int prePage前一页比如,当前是第 5 页,所以前一页为 4
int nextPage下一页比如,当前是第 5 页,所以下一页为 6
boolean isFirstPage是否为第一页比如,当前是第 5 页,不是第 1 页,所以为 false
boolean isLastPage是否为最后一页比如,当前是第 5 页,不是最后 1 页,所以为 false
boolean hasPreviousPage是否有前一页比如,当前是第 5 页,有前一页,所以为 true
boolean hasNextPage是否有下一页比如,当前是第 5 页,有后一页,所以为 true
int navigatePages导航页码数比如,页面导航栏显示 [3 4 5 6 7] 共 5 个数字
int[] navigatepageNums所有导航页号比如,页面导航栏显示 [3 4 5 6 7] 这 5 个数字
int navigateFirstPage导航条上的第一页比如,页面导航栏显示 [3 4 5 6 7] 时,第一页是第 3
int navigateLastPage导航条上的最后一页比如,页面导航栏显示 [3 4 5 6 7] 时,第一页是第 7

延迟加载

如果一个对象关联另一个对象,那么在查询 A 对象的时候,会去关联查询 B 对象。

何时查询(加载)B 对象分为三种时机:

  • 立即加载
  • 激进式延迟加载
  • 延迟加载

立即加载

MyBaits 默认是立即加载,即在查询 A 对象的时候,会立即查询其关联的 B 对象。如果,B 对象也有关联对象,例如 C 对象,那么还会立即查询 C 对象,… 因此类推,直到把所有有关联关系的数据全部查询出来。

激进式延迟加载

通过设置,可以启用延迟加载:

<settings>
  <setting name="lazyLoadingEnabled" value="true"/>
</settings>

启用延迟加载之后,Mybatis 又是默认的激进地延迟加载。

Mybatis 内部会进行某种规则判断,从而使得激进式的延迟加载,有时候等同于立即加载,有时候等同于普通的延迟加载。

真-延迟加载

可以再通过配置关闭掉激进地延迟加载,从而进入普通的延迟加载:

<settings>
  <setting name="lazyLoadingEnabled" value="true"/>
  <setting name="aggressiveLazyLoading" value="false"/>
</settings>

普通的延迟加载只会在你真正用到 A 对象的 B 属性时,再去查询/加载 B 对象。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一个适用于搭建企业内部培训平台的开源系统

大家好&#xff0c;我是 Java陈序员。 问君能有几多愁&#xff0c;唯有开源项目解千愁&#xff01; 最近领导给了个任务&#xff0c;搭建一个企业内部培训平台&#xff01;好不容易刚完成上个任务&#xff0c;又来一个活&#xff0c;这不又得加班了&#xff01; 还好&#x…

Oracle(2-14)User-Managed Incomplete Recovery

文章目录 一、基础知识1、Incomplete Recovery Overview 不完全恢复概述2、Situations Requiring IR 需要不完全恢复的情况3、Types of IR 不完全恢复的类型4、IR Guidelines 不完全恢复指南5、User-Managed Procedures 用户管理程序6、RECOVER Command Overview 恢复命令概述7…

基于Java的高校教学业绩信息管理系统论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本高校教学业绩信息管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的…

使用Git进行版本控制

参考&#xff1a;《Python编程从入门到实践》 前言1、安装、配置 Git1.1 在Linux系统中安装Git1.2 在OS X系统中安装Git1.3 在Windows系统中安装Git1.4 配置Git 2、创建项目3、忽略文件4、初始化仓库5、检查状态6、将文件加入到仓库中7、执行提交8、查看提交历史 前言 版本控制…

GridBagLayout GridBagConstraints 笔记231130

实例化使用模板 GridBagLayout gbl new GridBagLayout(); // gbl.columnWidths new int[]{200,200,200}; // 用数组设置列 // gbl.rowHeights new int[]{100,100,100,100,100}; // 用数组设置行GridBagConstraints gbc new GridBagConstraints();/*** gridBagConstrain…

2023,还不知道什么是iPaaS的企业要亏大了!

iPaaS是一种基于云的工具&#xff0c;用于将现有的应用程序和数据流链接到新的服务当中。本文就来介绍关于iPaaS的诞生历程和优势。 2023年&#xff0c;还不知道iPaaS是什么的企业亏大了&#xff01; iPaaS是什么 iPaaS是Intergration Platform as a Service&#xff08;集成平…

经典目标检测YOLO系列(一)引言_目标检测架构

经典目标检测YOLO系列(一)引言_目标检测架构 一个常见的目标检测网络&#xff0c;其本身往往可以分为一下三大块&#xff1a; Backbone network&#xff0c;即主干网络&#xff0c;是目标检测网络最为核心的部分&#xff0c;backbone选择的好坏&#xff0c;对检测性能影响是十…

阿里云服务器租用价格分享,阿里云服务器热门配置最新活动价格汇总

在我们购买阿里云服务器的时候&#xff0c;1核2G、2核2G、2核4G、2核8G、4核8G、8核16G、8核32G等配置属于用户购买最多的热门配置&#xff0c;1核2G、2核2G、2核4G这些配置低一点的云服务器基本上能够满足绝大部分个人建站和普通企业用户建站需求&#xff0c;而4核8G、8核16G、…

html通过CDN引入Vue使用Vuex以及Computed、Watch监听

html通过CDN引入Vue使用Vuex以及Computed、Watch监听 近期遇到个需求&#xff0c;就是需要在.net MVC的项目中&#xff0c;对已有的项目的首页进行优化&#xff0c;也就是写原生html和js。但是咱是一个写前端的&#xff0c;写html还可以&#xff0c;.net的话&#xff0c;开发也…

【小白专用】php执行sql脚本 更新23.12.10

可以使用 PHP 的 mysqli 扩展来执行 SQL 脚本。具体步骤如下&#xff1a; 连接到数据库&#xff1b;打开 SQL 脚本文件并读取其中的 SQL 语句&#xff1b;逐条执行 SQL 语句&#xff1b;关闭 SQL 脚本文件&#xff1b;关闭数据库连接。 以下是通过 mysqli 执行 SQL 脚本的示例…

nginx中Include使用

1.include介绍 自己的理解&#xff1a;如果学过C语言的话&#xff0c;感觉和C语言中的Include引入是一样的&#xff0c;引入的文件中可以写任何东西&#xff0c;比如server相关信息&#xff0c;相当于替换的作用&#xff0c;一般情况下server是写在nginx.conf配置文件中的&…

springboot+ssm+java植物养护花卉花圃管理系统

花圃管理系统&#xff0c;主要的模块包括查看个人中心、游客管理、员工管理、植物种类管理、植物信息管理、植物绿化管理、花圃园区管理、商品服务管理、系统管理等功能。系统中管理员主要是为了安全有效地存储和管理各类信息&#xff0c;还可以对系统进行管理与更新维护等操作…

LabVIEW与Tektronix示波器实现电源测试自动化

LabVIEW与Tektronix示波器实现电源测试自动化 在现代电子测试与测量领域&#xff0c;自动化测试系统的构建是提高效率和精确度的关键。本案例介绍了如何利用LabVIEW软件结合Tektronix MDO MSO DPO2000/3000/4000系列示波器&#xff0c;开发一个自动化测试项目。该项目旨在自动…

winError 123错误的解决

在卸载重载anaconda后&#xff0c;打开anaconda prompt窗口运行conda命令会报错&#xff0c;错误如下所示&#xff1a; 百度了一下是自己环境变量有问题&#xff0c;所以我打开环境变量&#xff1a; 然后打开系统的环境变量之后&#xff0c;查看到我上诉错误的那个环境变量…

ISP IC/FPGA设计-第一部分-MT9V034摄像头分析(0)

MT9V034为CMOS图像传感器&#xff0c;有着极其优秀的图像成像性能&#xff0c;同时支持丰富的功能用于isp的开发&#xff1b;MT9V034 的HDR宽动态、10bit数据深度、RAW格式&#xff08;bayer阵列&#xff09;图像、dvp和lvds接口、60fps正是学习isp开发的理想传感器&#xff1b…

LainChain 原理解析:结合 RAG 技术提升大型语言模型能力

摘要&#xff1a;本文将详细介绍 LainChain 的工作原理&#xff0c;以及如何通过结合 RAG&#xff08;Retrieval-Aggregated Generation&#xff09;技术来增强大型语言模型&#xff08;如 GPT 和 ChatGPT 等&#xff09;的性能。我们将探讨 COT、TOT、RAG 以及 LangChain 的概…

通过虚拟机安装Open5GS 和UERANSIM记录

目录 wsl虚拟环境尝试失败 step1 安装wsl: step2下载Ubuntu 20.04.6 LTS: step3升级wsl&#xff1a; step4生成用户: step5 linux下安装软件需要的镜像&#xff1a; step6 安装图形界面xfce和浏览器&#xff1a; step6 安装chrome virtual box安装ubuntu step7&#xf…

C/C++ 题目:给定字符串s1和s2,判断s1是否是s2的子序列

判断子序列一个字符串是否是另一个字符串的子序列 解释&#xff1a;字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&#xff09;字符&#xff0c;不改变剩余字符相对位置形成的新字符串。 如&#xff0c;"ace"是"abcde"的一个子序…

【js】数字字符串的比较

今天排查一个日历组件的bug&#xff0c;month打印出来是9&#xff0c;month1打印出来为12&#xff0c;比较month和month1大小进入if或者else&#xff0c;奇怪的是每次都是进入的month>month1语句里面 打印typeOf&#xff08;a&#xff09;和typeOf&#xff08;b&#xff09…

数据链路层的作用和三个基本问题

目录 一. 数据链路层的作用二. 数据链路层解决的三个问题2.1 数据链路和帧2.2 三个基本问题(重要)2.2.1 封装成帧2.2.2 透明传输2.2.3 差错检测 \quad 一. 数据链路层的作用 \quad \quad \quad 光有链路不能传输数据, 还要加上协议, 这样才是数据链路 数据链路层的作用就是负责…