Mybatis Plus 分页查询数据(图解)
更新时间 -01-01 11:58:32大家好,我是小哈。
本小节中,我们将学习如何通过 Mybatis Plus 分页查询数据库表中的数据。
什么是分页查询?
下图是小哈从京东上查询关键词「手机」,展示的手机数据就是分页查询,共有 91 页:
京东商城的分页查询
分页查询就是把需要查询的数据集进行分批展示,比如商品表中有 1万 条手机数据,每页按固定数量展示。
为什么需要分页查询?
前端页面能够展示的内容有限;
当数据库中数据量太多,比如 100W 条,一次性全部返回,查询速度慢,而且内存也顶不住;
表结构
了解到分页查询相关概念后,我们来上手 Mybatis Plus 的分页查询功能,还是之前小节中定义好的用户测试表, 执行脚本如下:
DROP TABLE IF EXISTS user; CREATE TABLE `user` ( `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID', `name` varchar(30) NOT NULL DEFAULT '' COMMENT '姓名', `age` int(11) NULL DEFAULT NULL COMMENT '年龄', `gender` tinyint(2) NOT NULL DEFAULT 0 COMMENT '性别,0:女 1:男', PRIMARY KEY (`id`) ) COMMENT = '用户表';
定义实体类
定义一个名为User
实体类:
@TableName("user")public class User {/** * 主键 ID, @TableId 注解定义字段为表的主键,type 表示主键类型,IdType.AUTO 表示随着数据库 ID 自增 */ @TableId(type = IdType.AUTO) private Long id; /** * 姓名 */ private String name; /** * 年龄 */ private Integer age; /** * 性别 */ private Integer gender; }
不明白 Mybatis Plus 实体类注解的小伙伴,可参考前面小节, 有详细解释。
新增测试数据
分页查询前,先通过代码插入一些测试数据,执行代码如下:
// 循环插入 100 条测试数据for (int i = 0; i < 100; i++) { User user = new User(); user.setName("犬小哈" + i); user.setAge(i); user.setGender(1); userMapper.insert(user); }
TIP : 不清楚如何插入数据可翻阅前面《新增数据》小节;
添加分页插件
接着,在MybatisPlusConfig
配置类中,添加分页插件PaginationInnerInterceptor
:
/*** @Author: 犬小哈* @From: 公众号:小哈学Java, 网站:* @Date: -12-15 18:29* @Version: v1.0.0 * @Description: TODO **/ @Configuration @MapperScan("com.quanxiaoha.mybatisplusdemo.mapper") public class MybatisPlusConfig { /** * 分页插件 * @return */ @Bean public MybatisPlusInterceptor mybatisPlusInterceptor(){ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return interceptor; } }
开始分页查询数据
Mybatis Plus 对 Mapper 层和 Service 层都将常见的增删改查操作封装好了,只需简单的继承,即可轻松搞定对数据的增删改查,本文重点讲解分页查询相关的部分。
Mapper 层
定义一个UserMapper
, 让其继承自BaseMapper
:
public interface UserMapper extends BaseMapper<User> { }
然后,注入 Mapper :
@Autowiredprivate UserMapper userMapper;
BaseMapper
提供的分页查询相关的方法如下:
解释一下每个方法的作用:
// 分页查询,page 用于设置需要查询的页数,以及每页展示数据量,wrapper 用于组装查询条件IPage<T> selectPage(IPage<T> page, Wrapper<T> queryWrapper);// 同上,区别是用 map 来接受查询的数据IPage<Map<String, Object>> selectMapsPage(IPage<T> page, Wrapper<T> queryWrapper);
参数说明:
示例代码
接下来,小哈来演示一些示例代码以便你快速了解如何使用分页查询:
// 组装查询条件QueryWrapper<User> queryWrapper = new QueryWrapper<>();// where age = 30queryWrapper.eq("age", 30); // 查询第 2 页数据,每页 10 条 Page<User> page = new Page<>(2, 10); page = userMapper.selectPage(page, queryWrapper); System.out.println("总记录数:" + page.getTotal()); System.out.println("总共多少页:" + page.getPages()); System.out.println("当前页码:" + page.getCurrent()); // 当前页数据 List<User> users = page.getRecords();
执行上面的代码,实际上执行了两条 SQL : 先执行COUNT(*)
查询出记录总数,然后才是分页语句LIMIT
:
Page 类说明
该类继承了
IPage
类,实现了简单分页模型,如果你要实现自己的分页模型可以继承Page
类或者实现IPage
类
Service 层
Mybatis Plus 同样也封装了通用的 Service 层 CRUD 操作,并且提供了更丰富的方法。接下来,我们上手看 Service 层的代码结构,如下图:
定义 Service 层
先定义UserService
接口 ,让其继承自IService
:
public interface UserService extends IService<User> { }
再定义实现类UserServiceImpl
,让其继承自ServiceImpl
, 同时实现UserService
接口,这样就可以让UserService
拥有了基础通用的 CRUD 功能,当然,实际开发中,业务会更加复杂,就需要向IService
接口自定义方法并实现:
@Servicepublic class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService { }
注入UserService
:
@Autowiredprivate UserService userService;
Service 层封装的分页相关方法如下:
// 无条件分页查询IPage<T> page(IPage<T> page);// 条件分页查询IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);// 无条件分页查询IPage<Map<String, Object>> pageMaps(IPage<T> page); // 条件分页查询 IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);
示例代码
Service 层的分页方法入参和 Mapper 差不多:
// 组装查询条件QueryWrapper<User> queryWrapper = new QueryWrapper<>();// where age = 30queryWrapper.eq("age", 30); // 查询第 2 页数据,每页 10 条 Page<User> page = new Page<>(2, 10); page = userService.page(page, queryWrapper); System.out.println("总记录数:" + page.getTotal()); System.out.println("总共多少页:" + page.getPages()); System.out.println("当前页码:" + page.getCurrent()); // 当前页数据 List<User> users = page.getRecords();