在前文内容中,我们完成了Spring Boot整合MyBatis-Plus的基础实操,掌握了实体类、Mapper、Service、Controller的编写规范,以及如何调用MyBatis-Plus内置方法实现简单的CRUD操作,成功迈出了数据库操作的第一步。
但在实际基础开发中,简单的CRUD远远不够——比如查询商品时需要“分页显示”(避免数据过多加载缓慢),查询用户时需要“按条件筛选”(如按年龄、邮箱查询),这些都是零基础入门后,必须掌握的核心进阶技能。今天,我们进入Spring Boot学习MyBatis-Plus基础进阶内容:分页查询与条件查询实操。
本文全程贴合“从基础到入门”导向,完全衔接MyBatis-Plus整合项目(springboot-basic),无需重新搭建环境,摒弃复杂的底层原理,聚焦“零基础能看懂、能实操”,手把手教你配置分页插件、编写条件查询代码,每一步都搭配具体代码示例和效果验证,让你快速掌握复杂数据库操作的核心方法,进一步夯实数据库开发基础,为编写完整业务项目(如商品管理、用户管理)打下坚实基础。
学习建议:本文适合已掌握MyBatis-Plus基础CRUD操作的零基础学习者,建议结合上一篇搭建的springboot-basic项目同步实操,跟着步骤一步步配置、编写代码,重点理解“分页插件的配置逻辑”和“条件查询的用法”,无需死记硬背,实操落地就能轻松掌握,逐步实现从“简单CRUD”到“复杂查询”的跨越。
入门必懂:为什么要学分页+条件查询?实际开发刚需
很多零基础学习者会疑惑:上一篇已经掌握了CRUD,为什么还要学分页和条件查询?这两个功能在实际开发中到底有什么用?搞懂这些,能让我们更清晰地理解学习的意义,贴合实际开发需求,避免盲目学习。
1.1 分页查询:解决“数据过多”的痛点
在实际开发中,数据库表中的数据往往很多(如商品表可能有上万条数据),如果直接查询所有数据,会导致以下问题:
1. 加载缓慢:一次性加载大量数据,会占用过多的内存和网络资源,导致接口响应缓慢,影响用户体验;
2. 数据混乱:大量数据一次性展示,用户无法快速找到自己需要的内容,不符合实际使用场景。
分页查询的核心作用的是“分批次加载数据”(如每页显示10条、20条),既减轻服务器压力,又提升用户体验,是基础开发中不可或缺的功能(如电商平台的商品列表、后台管理系统的用户列表,都用到了分页)。
1.2 条件查询:解决“精准筛选”的痛点
简单的“查询所有”“查询单个”无法满足实际开发需求——比如用户需要查询“年龄大于20岁的用户”“邮箱包含163.com的用户”,管理员需要查询“特定时间段注册的用户”,这些都需要通过条件查询实现。
MyBatis-Plus提供了简洁的条件查询API(QueryWrapper),无需编写复杂SQL,就能实现多条件组合查询,大幅简化开发,适配零基础入门者的学习节奏,也是企业基础开发中高频使用的功能。
1.3 学习重点(零基础必抓)
本文聚焦MyBatis-Plus进阶的2个核心内容,无需深入底层原理,重点掌握以下3点,就能应对80%的复杂数据库查询场景:
1. 分页查询:配置MyBatis-Plus分页插件,编写分页查询代码,实现数据分批次加载;
2. 条件查询:使用QueryWrapper构建查询条件,实现多条件组合查询(如等于、大于、模糊查询);
3. 综合实操:结合分页+条件查询,实现“按条件筛选并分页显示”,贴合实际开发场景。
前置准备(衔接前文,无需重新搭建)
本次实操将完全衔接第十七个热点搭建的“springboot-basic”项目,无需重新创建项目,无需修改原有代码,只需确保以下3个前置条件满足,即可顺利开展实操:
1. 已完成Spring Boot整合MyBatis-Plus(参考第十七个热点),能正常实现CRUD操作;
2. 已创建user表,并添加多条测试数据(至少10条,方便测试分页效果,可手动插入或通过上一篇的新增接口批量添加);
3. 项目已引入MyBatis-Plus核心依赖、MySQL驱动依赖(上一篇已配置,无需重复操作)。
补充:若未添加测试数据,可通过上一篇的新增用户接口,多添加几条数据(如新增test1、test2、test3……test10),确保分页测试有足够的数据支撑。
核心实操一:配置MyBatis-Plus分页插件(必配)
MyBatis-Plus的分页功能需要通过“分页插件”实现,零基础只需编写一个简单的配置类,就能开启分页功能,全程复制代码即可,无需理解复杂逻辑。
3.1 步骤1:创建配置类(MyBatisPlusConfig)
在com.example.springbootbasic包下,创建config包,编写MyBatisPlusConfig配置类,添加分页插件的配置,代码如下(直接复制即可):
package com.example.springbootbasic.config;import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;// @Configuration:标记当前类为配置类,让Spring容器识别@Configurationpublic class MyBatisPlusConfig { // 配置分页插件(MyBatis-Plus 3.5+版本推荐写法) @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 添加分页插件,指定数据库类型(MySQL),避免分页适配异常 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(com.baomidou.mybatisplus.core.metadata.TableInfoHelper.DB_TYPE_MYSQL)); return interceptor; }}3.2 核心说明(零基础必懂)
1. @Configuration注解:标记当前类为Spring的配置类,相当于传统的XML配置文件,Spring Boot会自动扫描并加载该类中的配置;
2. MybatisPlusInterceptor:MyBatis-Plus的拦截器,用于添加分页、乐观锁等插件;
3. PaginationInnerInterceptor:分页插件核心类,指定数据库类型为MySQL(避免不同数据库分页语法差异导致的报错);
4. 配置注意:无需修改任何参数,复制上述代码,确保包路径正确,启动项目后,分页插件即可生效。
核心实操二:分页查询实操(零基础必练)
分页插件配置完成后,我们编写Service层和Controller层代码,调用MyBatis-Plus内置的分页方法,实现用户数据的分页查询,全程无需编写SQL,只需调用方法即可。
4.1 步骤1:Service层添加分页方法
打开UserService接口和UserServiceImpl实现类,添加分页查询方法。由于UserService继承了IService,IService已内置分页方法(page方法),我们无需编写实现逻辑,直接在Service接口中声明即可(规范写法)。
// UserService接口(新增分页方法声明)package com.example.springbootbasic.service;import com.baomidou.mybatisplus.core.metadata.IPage;import com.baomidou.mybatisplus.extension.service.IService;import com.example.springbootbasic.entity.User;public interface UserService extends IService { // 分页查询用户(参数:当前页码,每页显示条数) IPage getUserPage(Integer pageNum, Integer pageSize);} // UserServiceImpl实现类(实现分页方法)package com.example.springbootbasic.service.impl;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.baomidou.mybatisplus.core.metadata.IPage;import com.baomidou.mybatisplus.extension.plugins.pagination.Page;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;import com.example.springbootbasic.entity.User;import com.example.springbootbasic.mapper.UserMapper;import com.example.springbootbasic.service.UserService;import org.springframework.stereotype.Service;@Servicepublic class UserServiceImpl extends ServiceImpl implements UserService { // 实现分页查询方法 @Override public IPage getUserPage(Integer pageNum, Integer pageSize) { // 1. 创建分页对象,指定当前页码(pageNum)和每页显示条数(pageSize) IPage page = new Page<>(pageNum, pageSize); // 2. 调用IService的page方法,实现分页查询(无查询条件,查询所有数据并分页) // 第一个参数:分页对象,第二个参数:查询条件(null表示无条件) return this.page(page, null); }} 4.2 步骤2:Controller层添加分页接口
打开UserController,添加分页查询接口,接收前端传递的“当前页码”和“每页显示条数”参数,调用Service层的分页方法,返回分页结果(包含分页信息和当前页数据)。
package com.example.springbootbasic.controller;import com.baomidou.mybatisplus.core.metadata.IPage;import com.example.springbootbasic.entity.User;import com.example.springbootbasic.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController@RequestMapping("/user")public class UserController { @Autowired private UserService userService; // 原有CRUD接口不变,新增分页查询接口 // 分页查询用户(GET请求,参数:pageNum=当前页码,pageSize=每页条数) @GetMapping("/page") public IPage getUserPage( // @RequestParam:接收前端传递的参数,defaultValue表示默认值(避免参数为空报错) @RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "5") Integer pageSize) { // 调用Service层的分页方法,返回分页结果 return userService.getUserPage(pageNum, pageSize); } // 以下为上一篇的CRUD接口,无需修改 @PostMapping("/add") public String addUser(@RequestBody User user) { boolean success = userService.save(user); return success ? "新增用户成功" : "新增用户失败"; } @GetMapping("/delete/{id}") public String deleteUser(@PathVariable Integer id) { boolean success = userService.removeById(id); return success ? "删除用户成功" : "删除用户失败"; } @PostMapping("/update") public String updateUser(@RequestBody User user) { boolean success = userService.updateById(user); return success ? "修改用户成功" : "修改用户失败"; } @GetMapping("/{id}") public User getUserById(@PathVariable Integer id) { return userService.getById(id); } @GetMapping("/list") public List getAllUser() { return userService.list(); }} 4.3 步骤3:启动项目,测试分页接口(零基础必做)
启动Spring Boot项目,确保启动成功(无报错),然后通过浏览器或Postman测试分页接口,验证分页效果,测试步骤如下:
测试:分页查询用户
请求地址:http://localhost:8080/user/page?pageNum=1&pageSize=5(pageNum=1表示第一页,pageSize=5表示每页显示5条)
测试结果:返回分页JSON数据,包含以下核心信息(零基础无需纠结细节,能看到分页效果即可):
1. total:总数据条数(如10条测试数据,total=10);
2. size:每页显示条数(5条);
3. current:当前页码(1);
4. records:当前页的数据列表(5条用户数据)。
修改请求参数测试:http://localhost:8080/user/page?pageNum=2&pageSize=5,会返回第6-10条数据,说明分页功能正常。
核心实操三:条件查询实操(零基础必练)
分页查询解决了“数据过多”的问题,而条件查询解决了“精准筛选”的问题。MyBatis-Plus提供了QueryWrapper类,用于构建查询条件,无需编写SQL,通过链式调用的方式,就能实现多条件组合查询,非常适合零基础入门。
5.1 核心条件查询API(零基础必记)
无需记忆所有API,重点掌握以下5个高频条件查询方法,就能应对基础开发中的大部分场景,结合示例理解,无需死记硬背:
1. eq:等于(如查询username等于test1的用户);
2. gt:大于(如查询age大于20的用户);
3. like:模糊查询(如查询email包含163.com的用户);
4. between:范围查询(如查询age在18-25之间的用户);
5. orderByAsc/orderByDesc:排序(如按age升序/降序排列)。
5.2 步骤1:Service层添加条件查询方法
打开UserService接口和UserServiceImpl实现类,添加2个常用的条件查询方法:① 按单个条件查询(如按年龄查询);② 按多条件组合查询(如按年龄+邮箱查询)。

// UserService接口(新增条件查询方法声明)package com.example.springbootbasic.service;import com.baomidou.mybatisplus.core.metadata.IPage;import com.baomidou.mybatisplus.extension.service.IService;import com.example.springbootbasic.entity.User;import java.util.List;public interface UserService extends IService { // 分页查询用户 IPage getUserPage(Integer pageNum, Integer pageSize); // 1. 单个条件查询:按年龄查询用户(查询age大于指定值的用户) List getUserByAge(Integer age); // 2. 多条件组合查询:按年龄+邮箱模糊查询 List getUserByAgeAndEmail(Integer age, String email);} // UserServiceImpl实现类(实现条件查询方法)package com.example.springbootbasic.service.impl;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.baomidou.mybatisplus.core.metadata.IPage;import com.baomidou.mybatisplus.extension.plugins.pagination.Page;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;import com.example.springbootbasic.entity.User;import com.example.springbootbasic.mapper.UserMapper;import com.example.springbootbasic.service.UserService;import org.springframework.stereotype.Service;import java.util.List;@Servicepublic class UserServiceImpl extends ServiceImpl implements UserService { // 分页查询方法(不变) @Override public IPage getUserPage(Integer pageNum, Integer pageSize) { IPage page = new Page<>(pageNum, pageSize); return this.page(page, null); } // 1. 单个条件查询:按年龄查询(age大于指定值) @Override public List getUserByAge(Integer age) { // 创建QueryWrapper对象,用于构建查询条件 QueryWrapper queryWrapper = new QueryWrapper<>(); // 构建条件:age > 指定年龄(gt表示大于) queryWrapper.gt("age", age); // 调用list方法,传入查询条件,返回符合条件的用户列表 return this.list(queryWrapper); } // 2. 多条件组合查询:按年龄+邮箱模糊查询 @Override public List getUserByAgeAndEmail(Integer age, String email) { QueryWrapper queryWrapper = new QueryWrapper<>(); // 条件1:age > 指定年龄 queryWrapper.gt("age", age); // 条件2:email包含指定字符串(like表示模糊查询,%表示任意字符) queryWrapper.like("email", email); // 条件3:按age降序排列(可选,优化显示效果) queryWrapper.orderByDesc("age"); // 返回符合条件的用户列表 return this.list(queryWrapper); }} 5.3 步骤2:Controller层添加条件查询接口
打开UserController,添加2个条件查询接口,接收前端传递的查询条件参数,调用Service层的条件查询方法,返回查询结果。
package com.example.springbootbasic.controller;import com.baomidou.mybatisplus.core.metadata.IPage;import com.example.springbootbasic.entity.User;import com.example.springbootbasic.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController@RequestMapping("/user")public class UserController { @Autowired private UserService userService; // 分页查询接口(不变) @GetMapping("/page") public IPage getUserPage( @RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "5") Integer pageSize) { return userService.getUserPage(pageNum, pageSize); } // 新增条件查询接口1:按年龄查询(查询age大于指定值的用户) @GetMapping("/byAge") public List getUserByAge(@RequestParam Integer age) { return userService.getUserByAge(age); } // 新增条件查询接口2:按年龄+邮箱模糊查询 @GetMapping("/byAgeAndEmail") public List getUserByAgeAndEmail( @RequestParam Integer age, @RequestParam String email) { return userService.getUserByAgeAndEmail(age, email); } // 原有CRUD接口(不变) @PostMapping("/add") public String addUser(@RequestBody User user) { boolean success = userService.save(user); return success ? "新增用户成功" : "新增用户失败"; } @GetMapping("/delete/{id}") public String deleteUser(@PathVariable Integer id) { boolean success = userService.removeById(id); return success ? "删除用户成功" : "删除用户失败"; } @PostMapping("/update") public String updateUser(@RequestBody User user) { boolean success = userService.updateById(user); return success ? "修改用户成功" : "修改用户失败"; } @GetMapping("/{id}") public User getUserById(@PathVariable Integer id) { return userService.getById(id); } @GetMapping("/list") public List getAllUser() { return userService.list(); }} 5.4 步骤3:启动项目,测试条件查询接口(零基础必做)
启动Spring Boot项目,通过浏览器或Postman测试2个条件查询接口,验证条件查询效果,测试步骤如下:
测试1:按年龄查询(单个条件)
请求地址:http://localhost:8080/user/byAge?age=20(查询年龄大于20的用户)
测试结果:返回所有年龄大于20的用户列表,若测试数据中只有age=22、23的用户,会只返回这两条数据,说明条件查询正常。
测试2:按年龄+邮箱模糊查询(多条件)
请求地址:http://localhost:8080/user/byAgeAndEmail?age=18&email=163.com(查询年龄大于18、邮箱包含163.com的用户)
测试结果:返回符合两个条件的用户列表,且按年龄降序排列,说明多条件组合查询正常。
核心实操四:分页+条件查询综合实操(贴合实际开发)
在实际开发中,分页和条件查询往往是结合使用的(如“查询年龄大于20的用户,分页显示,每页5条”)。我们基于前面的代码,新增一个综合查询方法,实现“条件筛选+分页显示”,进一步贴合实际开发场景。
6.1 步骤1:Service层添加综合查询方法
// UserService接口(新增综合查询方法声明)public interface UserService extends IService { // 分页查询用户 IPage getUserPage(Integer pageNum, Integer pageSize); // 单个条件查询:按年龄查询 List getUserByAge(Integer age); // 多条件组合查询:按年龄+邮箱模糊查询 List getUserByAgeAndEmail(Integer age, String email); // 综合查询:条件+分页(查询age大于指定值的用户,分页显示) IPage getUserPageByAge(Integer pageNum, Integer pageSize, Integer age);} // UserServiceImpl实现类(实现综合查询方法)@Overridepublic IPage getUserPageByAge(Integer pageNum, Integer pageSize, Integer age) { // 1. 创建分页对象 IPage page = new Page<>(pageNum, pageSize); // 2. 创建查询条件 QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.gt("age", age); // 条件:age大于指定值 // 3. 调用page方法,结合分页和条件查询 return this.page(page, queryWrapper);} 6.2 步骤2:Controller层添加综合查询接口
// UserController新增综合查询接口@GetMapping("/pageByAge")public IPage getUserPageByAge( @RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "5") Integer pageSize, @RequestParam Integer age) { return userService.getUserPageByAge(pageNum, pageSize, age);} 6.3 步骤3:测试综合查询接口
请求地址:http://localhost:8080/user/pageByAge?pageNum=1&pageSize=5&age=18(查询年龄大于18的用户,第一页,每页5条)
测试结果:返回分页数据,且分页列表中只有年龄大于18的用户,说明“条件+分页”综合查询正常,完全贴合实际开发场景。
零基础必避坑:常见问题及解决方法
零基础学习者在实操分页和条件查询时,容易遇到以下4个常见问题,掌握解决方法,避免卡壳,高效完成学习:
7.1 坑点1:分页插件配置错误,分页失效
问题现象:调用分页接口,返回所有数据,没有分页效果(total等于records.size,current始终为1)。
解决方法:
1. 检查MyBatisPlusConfig配置类是否添加了@Configuration注解,确保Spring能扫描到;
2. 检查分页插件是否指定了数据库类型(MySQL),避免适配异常;
3. 检查分页方法是否使用了IPage和Page对象,确保调用的是MyBatis-Plus的page方法。
7.2 坑点2:条件查询无结果,或结果不符合预期
问题现象:调用条件查询接口,返回空列表,或返回的数据不符合查询条件。
解决方法:
1. 检查QueryWrapper构建的条件是否正确(如gt是大于,eq是等于,不要混淆);
2. 检查条件中的字段名称是否与数据库表字段一致(大小写敏感,如数据库字段是age,不要写成Age);
3. 检查前端传递的参数是否正确(如age参数是否为数字,email参数是否正确)。
7.3 坑点3:条件查询报错“column 'xxx' not found”
报错信息:Unknown column 'xxx' in 'where clause'(字段不存在)。
解决方法:检查QueryWrapper中指定的字段名称(如queryWrapper.gt("age", age)),确保与数据库表中的字段名称完全一致,不要写错字段名。
7.4 坑点4:分页参数为空,导致报错
报错信息:NullPointerException(空指针异常)。
解决方法:在Controller层的分页接口中,给pageNum和pageSize添加@RequestParam(defaultValue = "1")和@RequestParam(defaultValue = "5"),设置默认值,避免参数为空。
学习建议(零基础适配,稳步进阶)
本节是MyBatis-Plus的基础进阶内容,掌握分页和条件查询,就能应对大部分基础开发中的数据库查询场景,进一步夯实Spring Boot数据库开发基础,零基础学习者重点把握以下4点:
1. 重点实操,循序渐进:先掌握分页插件的配置和分页查询,再学习条件查询,最后结合两者实现综合查询,一步一个脚印,不要急于求成;
2. 理解核心用法,拒绝死记硬背:重点理解QueryWrapper的链式调用逻辑,记住5个高频条件查询API,结合实操示例,就能灵活运用,无需记忆所有API;
3. 结合实际场景练习:多尝试修改条件查询的逻辑(如新增between范围查询、eq等于查询),多测试分页参数(如pageNum=3、pageSize=10),加深对功能的理解;
4. 注重代码规范:保持“Entity→Mapper→Service→Controller”的分层写法,条件查询和分页查询的方法命名要规范(如getUserByAge、getUserPageByAge),为后续编写完整业务项目打下基础。
补充:后续我们将继续围绕“从基础到入门”的导向,基于本次的分页和条件查询,学习MyBatis-Plus的自定义SQL编写(应对复杂查询场景),同时结合前文的Redis、注解等知识点,编写一个完整的基础业务项目(如简单的用户管理系统),帮你逐步实现“能独立开发简单Spring Boot项目”的目标。