MyBatis-Plus 分页查询以及自定义sql分页

2023-05-16

一、引言

分页查询每个人程序猿几乎都使用过,但是有部分同学不懂什么是物理分页和逻辑分页。

物理分页:相当于执行了limit分页语句,返回部分数据。物理分页只返回部分数据占用内存小,能够获取数据库最新的状态,实施性比较强,一般适用于数据量比较大,数据更新比较频繁的场景。

逻辑分页:一次性把全部的数据取出来,通过程序进行筛选数据。如果数据量大的情况下会消耗大量的内存,由于逻辑分页只需要读取数据库一次,不能获取数据库最新状态,实施性比较差,适用于数据量小,数据稳定的场合。

那么MP中的物理分页怎么实现呢? 往下看往下看

二、配置

创建MybatisPlusConfig配置类。

/**
 * @Auther: IT贱男
 * @Date: 2019/6/12 15:06
 * @Description: MybatisPlus配置类
 */
@Configuration
public class MyBatisPlusConfig {
 
    /**
     * 分页插件
     * @return
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}

三、具体分页实现

MP的Wrapper提供了两种分页查询的方式,源码如下:

    /**
     * 根据 entity 条件,查询全部记录(并翻页)
     *
     * @param page         分页查询条件(可以为 RowBounds.DEFAULT)
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
 
    /**
     * 根据 Wrapper 条件,查询全部记录(并翻页)
     *
     * @param page         分页查询条件
     * @param queryWrapper 实体对象封装操作类
     */
    IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

可见两个分页方法参数都是一致的,只是返回参数略有不同,具体选择根据实际业务为准。

    /**
     * 分页查询
     */
    @Test
    public void selectByPage() {
        QueryWrapper<User> wrapper = new QueryWrapper();
        wrapper.like("name", "雨").lt("age", 40);
 
        Page<User> page = new Page<>(1,2);
 
        //IPage<User> userIPage = userMapper.selectPage(page, wrapper);
 
        IPage<Map<String, Object>> mapIPage = userMapper.selectMapsPage(page, wrapper);
 
 
        System.out.println("总页数"+mapIPage.getPages());
        System.out.println("总记录数"+mapIPage.getTotal());
        List<Map<String, Object>> records = mapIPage.getRecords();
        records.forEach(System.out::println);
    }

以上分页查询执行sql如下,先是查询了一次总记录数,然后在查询的数据。

DEBUG==>  Preparing: SELECT COUNT(1) FROM user WHERE name LIKE ? AND age < ? 
DEBUG==> Parameters: %雨%(String), 40(Integer)
TRACE<==    Columns: COUNT(1)
TRACE<==        Row: 2
DEBUG==>  Preparing: SELECT id,name,age,email,manager_id,create_time FROM user WHERE name LIKE ? AND age < ? LIMIT ?,? 
DEBUG==> Parameters: %雨%(String), 40(Integer), 0(Long), 2(Long)
TRACE<==    Columns: id, name, age, email, manager_id, create_time
TRACE<==        Row: 2, 张雨琪, 31, zjq@baomidou.com, 1088248166370832385, 2019-01-14 09:15:15
TRACE<==        Row: 3, 刘红雨, 31, lhm@baomidou.com, 1088248166370832385, 2019-01-14 09:48:16
DEBUG<==      Total: 2
总页数1
总记录数2

现在我们有需求只要查询数据即可, 不关心总记录数等,如果使用默认的方式就消耗不必要的性能。那么解决办法也是很简单的,只需要在创建page对象时传入第三个参数为false即可。

Page<User> page = new Page<>(1,2,false);

四、自定义sql分页查询

有时候查询的数据难免会出现多表连接查询,或者是一些复杂的sql语句,但是这些语句也是需要支持分页查询的,

先定义查询接口,第一个参数要是分页的参数,小编这里演示就写简单的sql。

步骤一:在mapper文件中,编写对应的分页查询接口。

步骤二:在xml中编写对应的sql语句,小编这里演示的 “${ew.customSqlSegment}”,这个是如果你想自定义的sql语句,也想使用wrapper查询条件构造器,则需要在mapper接口中添加参数,以及xml中也要有固定。 

    /**
     * 自定义sql分页
     * @param page
     * @param queryWrapper 看这里看这里,如果自定义的方法中需要用到wrapper查询条件,需要这样写
     * @return
     */
    IPage<User> selectMyPage(IPage<User> page, @Param(Constants.WRAPPER) Wrapper<User> queryWrapper);
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">
 
    <select id="selectMyPage" resultType="com.example.demo.model.User">
        SELECT * FROM user ${ew.customSqlSegment}
    </select>
 
</mapper>
   /**
     * 自定义sql分页查询
     */
    @Test
    public void selectByMyPage() {
        QueryWrapper<User> wrapper = new QueryWrapper();
        wrapper.like("name", "雨").lt("age", 40);
        Page<User> page = new Page<>(1,2);
        IPage<User> mapIPage = userMapper.selectMyPage(page, wrapper);
 
        System.out.println("总页数"+mapIPage.getPages());
        System.out.println("总记录数"+mapIPage.getTotal());
        List<User> records = mapIPage.getRecords();
        records.forEach(System.out::println);
    }

五、多表sql分页查询

多表连接查询怎么分页,其实道理都是一样的。

以简单的为主,sql如下: his_ipd_encounter、his_user 两张表

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">
 
    <select id="selectByHisName" resultType="java.lang.String">
        select u.realname from his_ipd_encounter e, his_user u where e.his_uid = u.his_uid
    </select>
    
 
</mapper>

mapepr如下:需要传入分页的参数,返回的类型也需要是分页对象

 
/**
 * <p>
 * 用户 Mapper 接口
 * </p>
 *
 * @author IT贱男
 * @since 2019-06-14
 */
public interface UserMapper extends MyMapper<User> {
 
 
    /**
     * 多表查询分页
     * @param page
     * @return
     */
    IPage<String> selectByHisName(IPage<User> page);
}

测试如下:通过查看日志,执行的sql加了分页条件的。

   @Test
    public void select(){
        // 创建分页参数
        Page<User> page = new Page<>(1,2);
        IPage<String> result = userMapper.selectByHisName(page);
        // 获取数据
        List<String> records = result.getRecords();
        records.forEach(System.out::println);
        System.out.println("总页数 = "+ result.getPages());
    }
ARNWarn: Could not find @TableId in Class: com.example.demo.model.HisUser.
INFOStarted UserMapperTest in 2.428 seconds (JVM running for 2.959)
select u.realname from his_ipd_encounter e, his_user u where e.his_uid = u.his_uid
DEBUG==>  Preparing: SELECT COUNT(1) FROM his_ipd_encounter e, his_user u WHERE e.his_uid = u.his_uid 
DEBUG==> Parameters: 
TRACE<==    Columns: COUNT(1)
TRACE<==        Row: 117
DEBUG==>  Preparing: select u.realname from his_ipd_encounter e, his_user u where e.his_uid = u.his_uid LIMIT ?,? 
DEBUG==> Parameters: 0(Long), 2(Long)
TRACE<==    Columns: realname
TRACE<==        Row: 胡伯云
TRACE<==        Row: 安元慧
DEBUG<==      Total: 2
 Time:20 ms - ID:com.example.demo.mapper.UserMapper.selectByHisName
Execute SQL:
    com.p6spy.engine.wrapper.PreparedStatementWrapper@61bcbcce
 
胡伯云
安元慧
总页数 = 59

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MyBatis-Plus 分页查询以及自定义sql分页 的相关文章

随机推荐

  • 【Week8作业 C】班长竞选【SCC缩点】

    题意 xff1a 大学班级选班长 xff0c n个同学均可以发表意见 若意见为A B xff0c 则表示A认为B合适 意见具有传递性 xff0c 即A认为B合适 xff0c B认为C合适 xff0c 则A也认为C合适 共m条意见 xff0c
  • 【Week9作业 A】咕咕东的目录管理器【模拟】

    题意 xff1a 咕咕东的雪梨电脑的操作系统在上个月受到宇宙射线的影响 xff0c 时不时发生故障 xff0c 他受不了了 xff0c 想要写一个高效易用零bug的操作系统 这工程量太大了 xff0c 所以他定了一个小目标 xff0c 从实
  • 【Week12作业 B】必做题-2【模拟】

    题意 xff1a zjm被困在一个三维的空间中 现在要寻找最短路径逃生 xff01 空间由立方体单位构成 zjm每次向上下前后左右移动一个单位需要一分钟 xff0c 且zjm不能对角线移动 空间的四周封闭 zjm的目标是走到空间的出口 是否
  • 【Week12作业 C】必做题-3【动态规划】

    题意 xff1a 东东每个学期都会去寝室接受扫楼的任务 xff0c 并清点每个寝室的人数 每个寝室里面有ai个人 1 lt 61 i lt 61 n 从第i到第j个宿舍一共有sum i j 61 a i 43 43 a j 个人 这让宿管阿
  • selenium重要功能应用

    当使用C 编写爬虫时 xff0c 以下是一些常用的爬虫框架 xff1a AngleSharp xff08 用于HTML解析 xff09 HtmlAgilityPack xff08 用于HTML解析 xff09 ScrapySharp xff
  • 【CSP201809-3】元素选择器【模拟】

    题意 思路 xff1a 用point来存储结构化文档 xff0c 里面string label string id为标签和id xff0c int c为所在层数 xff0c 两个点就为一层 读入结构化文档 xff1a 用getline读入一
  • 【Week14作业 B】Q老师与十字叉【模拟】

    题意 xff1a 思路 xff1a 存储网格图不可能开数组a 50000 50000 xff0c 发现n m lt 61 400000 xff0c 可以用a 400001 来存储 xff0c i j gt a i 1 m 43 j 读入数据
  • 【Week14作业 C】Q老师的考验【矩阵快速幂】

    题意 xff1a Q老师 对数列有一种非同一般的热爱 xff0c 尤其是优美的斐波那契数列 这一天 xff0c Q老师 为了增强大家对于斐波那契数列的理解 xff0c 决定在斐波那契的基础上创建一个新的数列 f x 来考一考大家 数列 f
  • 【Week14作业 D】Q老师染砖【矩阵快速幂优化dp】

    题意 xff1a 衣食无忧的 Q老师 有一天突发奇想 xff0c 想要去感受一下劳动人民的艰苦生活 具体工作是这样的 xff0c 有 N 块砖排成一排染色 xff0c 每一块砖需要涂上红 蓝 绿 黄这 4 种颜色中的其中 1 种 且当这 N
  • 【Week15实验 D】瑞瑞爱上字符串【模拟】

    题意 xff1a 瑞瑞最近迷上了字符串 xff0c 因此决定出一个字符串的题 给定两个正整数 N K xff0c 考虑所有由 N 2 个 a 和 2 个 b 组成的字符串 xff0c 要求输出其中字典序第 K 小的 例如当 N 61 5 时
  • 【Week15作业 C】ZJM与纸条【KMP】

    题意 xff1a ZJM 的女朋友是一个书法家 xff0c 喜欢写一些好看的英文书法 有一天 ZJM 拿到了她写的纸条 xff0c 纸条上的字暗示了 ZJM 的女朋友 想给 ZJM 送生日礼物 ZJM 想知道自己收到的礼物是不是就是她送的
  • 【Week16实验 A】TT数鸭子【模拟】

    题意 xff1a 思路 xff1a 如果k gt 10 xff0c 则每个数都可以满足条件 xff0c 答案即为n xff1b 否则依次读入每一个数 xff0c 计算不同数位的个数sum xff0c 如果sum lt k xff0c 则这个
  • 【Week16实验 B】ZJM要抵御宇宙射线【模拟】

    题意 xff1a 思路 xff1a 对每个点都求出到其余点的距离平方 xff0c 然后取该点到其他点的距离平方的最大值为半径平方 xff0c 最后对所有点的半径平方取最小值 注意有多解时将x较小 y较小的点作为答案 总结 xff1a 一道简
  • 【Week16实验 C】宇宙狗的危机【区间dp】

    题意 xff1a 思路 xff1a 这道题是区间dp xff0c 不是BST xff01 xff01 xff01 令l i j 表示以j为根 j的左子树可到i这样的BST是否存在 xff0c r i j 表示以i为根 i的右子树可到j这样的
  • Ubuntu实现远程登陆之telnet——安装telnet服务端

    telnet是一种网络通信协议 xff0c 我们可以使用它登录远程服务器 xff0c 虽然telnet有安全问题这一硬伤 xff0c 但正因如此 xff0c 它十分简洁 xff0c 非常容易地在资源受限设备上 xff08 如嵌入式环境 xf
  • week6 限时大模拟 A - 掌握魔法の东东 II

    题意 思路 创建一个pair lt int int gt 类型的数组a xff0c 用来保存一副牌的花色以及大小 运用stl的vector xff0c 来存储手牌shoupai xff0c 随后使用dfs搜索 xff0c 数组a里的牌在手牌
  • Hadoop可视化神器-Hue安装、编译、运行

    下载安装 CDH版本 xff1a http archive cloudera com cdh5 官网 xff1a http gethue com tar zxf hue 3 9 0 cdh5 15 0 tar gz C opt module
  • 电脑通过wifi连接树莓派3

    前提要求 树莓派首先要能用网线和电脑连接起来 树莓派和电脑连接的是同一个wifi 电脑的网络设置和电脑网线直连树莓派的设置是一样的 xff0c 可以参照我的上篇博文设置 树莓派必须是树莓派3型 xff0c 因为只有这个型号才内置了wifi模
  • Ubuntu更换源说明

    Ubuntu更换源说明 更换源步骤如下 xff1a 备份源列表 sudo cp etc apt sources list etc apt sources list bak 命令行打开sources list文件 sudo gedit etc
  • MyBatis-Plus 分页查询以及自定义sql分页

    一 引言 分页查询每个人程序猿几乎都使用过 xff0c 但是有部分同学不懂什么是物理分页和逻辑分页 物理分页 xff1a 相当于执行了limit分页语句 xff0c 返回部分数据 物理分页只返回部分数据占用内存小 xff0c 能够获取数据库