
目录一. MyBatis-Plus 分页插件介绍二. 准备工作-创建项目配置环境2.1 创建数据库表Product商品表2.2 创建Maven项目创建包接口类2.3 添加MyBatisPlus依赖和 Lombok 插件2.4 编写 Configuration 分页插件配置文件2.5 编写 application.properties 配置文件2.6 实体类代码接口代码三. IPage 分页的使用方式四. 自定义分页查询五. QueryWrapper 条件构造器的使用一. MyBatis-Plus 分页插件介绍1MyBatis-Plus 自带有分页插件功能能够帮助我们在查询的时候自动实现分页功能并返回给我们详细的分页相关数据2使用了分页插件之后我们在编写 xxxMapper.xml SQL语句文件语句时就不需要在SQL语句中自己手动书写分页关键字分页插件会自动帮助我们添加3下面我创建一个小demo帮助小白同学书写项目代码这里是为小白入门准备的入门环境配置如果有基础的同学只是忘记如何使用前来复习可直接跳过配置环境流程跳转至下文第三第四二. 准备工作-创建项目配置环境2.1 创建数据库表Product商品表执行如下SQL语句生成Product商品表如下图SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0; -- ---------------------------- -- Table structure for product -- ---------------------------- DROP TABLE IF EXISTS product; CREATE TABLE product ( id int NOT NULL, name varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL, price decimal(10, 2) NULL DEFAULT NULL, color varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL, production_date datetime NULL DEFAULT NULL, PRIMARY KEY (id) USING BTREE ) ENGINE InnoDB CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci ROW_FORMAT Dynamic; -- ---------------------------- -- Records of product -- ---------------------------- INSERT INTO product VALUES (1, HuaWei P30, 6800.00, red, 2024-04-08 21:57:26); INSERT INTO product VALUES (2, IPhone 10, 8800.00, blue, 2024-04-27 21:57:31); INSERT INTO product VALUES (3, IPad Pro, 5800.00, black, 2024-06-20 21:57:35); INSERT INTO product VALUES (4, XiaoMi 10, 3800.00, purple, 2024-04-01 21:57:42); INSERT INTO product VALUES (5, Vivo 20, 5800.00, white, 2024-04-30 21:57:48); INSERT INTO product VALUES (6, HuaWei MatePad11, 2600.00, white, 2024-04-04 16:40:19); INSERT INTO product VALUES (7, IPhone 20 ProMax, 11000.00, red, 2024-04-29 16:41:07); INSERT INTO product VALUES (8, Red Mi K60, 3100.00, purple, 2024-04-14 16:41:43); INSERT INTO product VALUES (9, HuaWei Mate 40, 5999.00, blue, 2024-04-17 10:20:14); INSERT INTO product VALUES (10, HuaWei Mate 60 Pro, 6999.00, purple, 2024-04-03 10:21:18); SET FOREIGN_KEY_CHECKS 1;2.2 创建Maven项目创建包接口类项目结构如下所示config包存放Configuration配置类controller包存放Controler层类entity包存放数据库实体映射类mapper包存放数据库访问接口Interfaceservice包存放业务层接口Interfaceimpl包存放service层接口实现类resource存放项目properties文件bootstrap文件mapper.xml 配置文件2.3 添加MyBatisPlus依赖和 Lombok 插件想要使用MyBatisPlus分页插件首先要添加依赖如下Lombok 插件非必须是我在项目中展示会用到方便实体类的书写dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.1/version /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId version1.18.22/version scopecompile/scope /dependency2.4 编写 Configuration 分页插件配置文件使用分页插件功能第二步就是配置分页插件拦截器在工作时不需要我们配置项目中肯定是已经配好的这里我们自己动手书写小demo就简单做一下配置// Configuration 注释标注当前类是一个Spring Boot配置类项目在启动时自动读取加载配置文件中我们定义的Bean对象 Configuration // MapperScam 定义实体类的扫描路径在本项目中路径为 com.haust.mapper MapperScan(com.haust.mapper) public class MyBatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor(){ // 创建一个拦截器对象 MybatisPlusInterceptor mybatisPlusInterceptor new MybatisPlusInterceptor(); /** * 我们将 new 一个分页插件拦截器 PaginationInnerInterceptor 参数为数据库类型 MySQL,当然也可以写其他数据库类型根据自己的数据库类型而定 * 然后将此拦截器add添加到拦截器对象中即可生效 * (这里演示MyBatis-Plus分页插件拦截器其实还可以继续添加其他拦截器,我们可以继续 new 继续add添加到拦截器对象中哦) */ mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return mybatisPlusInterceptor; } }2.5 编写 application.properties 配置文件MySQL驱动为5.7的driver-class-name为com.mysql.jdbc.DriverMySQL驱动为8.0以上的driver-class-name为com.mysql.cj.jdbc.Driver多了一个 cj用户名密码自行更改spring.datasource.driver-class-name com.mysql.cj.jdbc.Driver spring.datasource.url jdbc:mysql://localhost:3306/patent?useUnicodetruecharacterEncodingutf-8tinyInt1isBitfalseuseSSLfalseserverTimezoneAsia/Shanghai spring.datasource.username root spring.datasource.password 1234562.6 实体类代码接口代码Product 实体类代码// Data Lombok插件提供的注释方便实体类的书写 // 只要注释在当前实体类会自动为我们生成GetterSettertoStringequalshashCode方法 Data // TableName(product)指定对应的数据库表名 product TableName(product) public class Product { // TableId(id) 指定数据主键为 id TableId(id) private Long id; // TableField(name) 标注当前String字段 name 对应product表中的字段name下方同理 TableField(name) private String name; TableField(price) private Double price; TableField(color) private String color; TableField(production_date) private Date productionDate; }ProductMapper 接口代码如下// Mapper 注释标注当前类为数据访问层接口 Mapper // 继承BaseMapper接口泛型为 Product 实体类 public interface ProductMapper extends BaseMapperProduct { }ProductService 接口代码Service // ProductService接口继承MyBatisplus提供的现有接口IService并填写泛型为Product public interface ProductService extends IServiceProduct { }ProductServiceImpl 业务层接口实现类方法// 实现类继承MyBatisPlus提供的ServiceImpl业务层实现类 // 泛型有两个第一个是Mapper接口第二个是Mapper对应的实体类 // 只要继承了ServiceImpl就不需要重写IService中的方法了因为继承的ServiceImpl类中已经帮我们重写过了 public class ProductServiceImpl extends ServiceImplProductMapper, Product implements ProductService { }三. IPage 分页的使用方式IPage 是MyBatis-Plus 提供的一个分页相关的接口它有一个实现类为 Page类中定义了分页相关的多个参数。最重要的一点需要记住Page 对象既作为分页查询的条件参数也是分页查询的结果接收参数这一点在下方代码中会有所体现size (每页显示条数)此参数通常由前端传给我们然后再封装到Page对象中进行分页查询current (要展示哪一页数据)此参数通常由前端传给我们然后再封装到Page对象中进行分页查询orders(排序规则集合)按照哪些字段进行排序可以为多个例如希望通过时间进行排序如果时间相同就根据用户ID降序排序可以添加多个字段total (总记录数)指查询完毕后返回的数据库中总记录数注意不包含已被逻辑删除的数据records查询到的分页结果集数据分页查询得到的多条数据会存储在 records 中可以看出该对象是一个集合可以传递一个泛型泛型就是查询到的数据对应的实体泛型还有其它的参数但上面五个最为常用因此简单说一下public class PageT implements IPageT { private static final long serialVersionUID 8545996863226528798L; protected ListT records; protected long total; protected long size; protected long current; protected ListOrderItem orders; protected boolean optimizeCountSql; protected boolean searchCount; protected boolean optimizeJoinOfCountSql; protected String countId; protected Long maxLimit;Page对象使用方式如下代码SpringBootTest public class ProductMapperTest { // 自动注入 productMapper 接口对应的实现类对象 Autowired private ProductMapper productMapper; Test public void testPageQuery(){ // 创建分页查询相关参数 page泛型为 Product表示查询到的结果对应的实体类为Product PageProduct page new Page(); // 设置分页查询显示第二页的数据实际开发过程中该参数有前端传递 page.setCurrent(2); // 设置分页查询每页显示四条数据实际开发过程中该参数有前端传递 page.setSize(4); // 创建排序字段集合不想排序不加即可实际开发过程中一般都会要求按照时间降序排序 ListOrderItem orders new ArrayList(); // 按照价格排序排序方式为降序ASC为True表示升序false表示降序第一个参数表示数据库中的列名 orders.add(new OrderItem(price,false)); // 按照生产时间排序排序方式为降序 orders.add(new OrderItem(production_date,false)); // 将排序对象集合加入分页查询对象Page中 page.setOrders(orders); // 执行分页查询可以创建一个Page对象接受查询结果 // 也可以用查询条件参数page但其实最后结果都是同一个 page productMapper.selectPage(page, null); // 可以新创建一个Page对象就像下面这样 PageProduct productPage productMapper.selectPage(page,null); // 输出分页查询结果显示当前的哪一页 System.out.println(page.getCurrent()); // 输出分页查询结果的总数据条数 System.out.println(page.getTotal()); // 输出分页查询结果的数据集合 System.out.println(page.getRecords()); // 输出分页查询结果的每页显示条数 System.out.println(page.getSize()); // 判断刚才分页查询的两个结果对象是否为同一个 System.out.println(page productPage); // 输出第一个分页查询对象内存地址 System.out.println(page); // 输出第二个分页查询对象内存地址 System.out.println(productPage); } }运行测试类在控制台可以看到输出结果我将其复制到下面// 此处2表示当前显示第二页的数据就是我们传入的参数current 2 // 此处10表示数据库中一共查询到十条记录不包含逻辑删除的数据 10 // 下方表示分页查询到的四条数据排序规则就是按照时间降序进行排序的 Product { id 9, name HuaWei Mate 40, price 5999.0, color blue, productionDate Wed Apr 17 10: 20: 14 CST 2024 }, Product { id 3, name IPad Pro, price 5800.0, color black, productionDate Thu Jun 20 21: 57: 35 CST 2024 }, Product { id 5, name Vivo 20, price 5800.0, color white, productionDate Tue Apr 30 21: 57: 48 CST 2024 }, Product { id 6, name HuaWei MatePad11, price 3800.0, color white, productionDate Thu Apr 04 16: 40: 19 CST 2024 } // 4表示当前页显示4条数据就是我们传入的参数 size 4四. 自定义分页查询自定义分页查询也不难实现首先再 xxxMapper 类中定义接口方法使用Page实现自定义分页查询只需要在接口参数列表中添加 Page 参数对象泛型填写对应查询的实体类泛型。小编这里建议小伙伴们将 Page 参数对象放在参数列表的第一个位置防止忘记我们后面在业务测试方法中也先对 Page 查询参数对象进行封装然后再在 Page 对象之后添加其它查询条件参数。public interface ProductMapper extends BaseMapperProduct { // 自定义一个分页查询接口,通过Product实体传参使用 Param 注释标注参数名称 PageProduct selectPageByColor(Param(page) PageProduct page, Param(product) Product product); }编写 selectPageByColor 接口方法的测试类Test public void testPageQueryByColor(){ // 创建分页查询相关参数 page泛型为 Product表示查询到的结果对应的实体类为Product PageProduct page new Page(); // 设置分页查询显示第二页的数据 page.setCurrent(1); // 设置分页查询每页显示四条数据 page.setSize(2); // 创建排序字段集合如果不想排序不加即可 ListOrderItem orders new ArrayList(); // 按照价格排序排序方式为降序ASC为True表示 orders.add(new OrderItem(price,false)); // 将排序对象集合加入分页查询对象Page中 page.setOrders(orders); Product product new Product(); product.setColor(purple); // 执行分页查询 page productMapper.selectPageByColor(page, product); // 输出分页查询结果的数据集合 System.out.println(page.getRecords()); // 输出分页查询结果的总数据条数 System.out.println(page.getTotal()); }运行此方法控制台得到查询结果// 分页查询获取到两条结果并且是按照价格降序排序颜色都为purple符合查询预期 [Product { id 10, name HuaWei Mate 60 Pro, price 6999.0, color purple, productionDate Wed Apr 03 10: 21: 18 CST 2024 }, Product { id 4, name XiaoMi 10, price 3800.0, color purple, productionDate Mon Apr 01 21: 57: 42 CST 2024 }] // 3表示一共有三条数据但我们只显示了第一页的两条数据 3五. QueryWrapper 条件构造器的使用细心的小伙伴或许已经注意到了在第一个测试方法中MyBatis-Plus 提供的分页查询方法 selectPage 需要传递两个参数第一个是分页查询对象Page第二个其实是查询条件可以看到它是 Wrapper 类型的Wrapper 是一个接口它有一个实现类 LambdaQueryWrapper通过这个 LambdaQueryWrapper我们就可以在对象中添加我们查询数据是的过滤条件不需要再 mapper.xml 配置文件中再去自定义书写MP中没有提供的查询接口LambdaQueryWrapper 的使用方式也不难首先创建一个LambdaQueryWrapper对象就可以通过 . 的方式链式调用方法也是见名知意between 就是数据库中的 between...and...orderByDesc 就是数据库中的降序排序orderByAsc 就是数据库中的升序排序数据库中的查询条件这里都有都可以说是见名知意括号内传递约束的数据库字段通过 xxx(实体类名)::getxxx 的方式获取即可例如要获取Product商品表的主键ID写法就是 Product::getIdTest public void testPageQueryByCondition(){ PageProduct page new Page(); page.setCurrent(1); page.setSize(2); LambdaQueryWrapperProduct wrapper new LambdaQueryWrapper(); // 查询ID在 1~5 之间的商品数据再将它们按照价格降序排序若价格相同再将它们按照生产日期升序排序 wrapper.between(Product::getId, 1, 5) .orderByDesc(Product::getPrice) .orderByAsc(Product::getProductionDate); productMapper.selectPage(page,wrapper); System.out.println(page.getRecords()); }写法极其简单只有有条件就一直通过 . 的方式进行链式添加添加完毕后将 wrapper 对象做法查询条件传递给查询接口就可以了执行上述代码在控制台中查询到三条数据我给它粘贴出来方便查看可以看到三条数据按照价格降序排序与预期结果一致完美[ Product{id2, nameIPhone 10, price8800.0, colorblue, productionDateSat Apr 27 21:57:31 CST 2024}, Product{id1, nameHuaWei P30, price6800.0, colorred, productionDateMon Apr 08 21:57:26 CST 2024}, Product{id5, nameVivo 20, price5800.0, colorwhite, productionDateTue Apr 30 21:57:48 CST 2024} ]