1.准备工作
mybatis-plus分页插件需要先进行配置
@Configuration public class MyBatisPlusConfig { /** * mybatis-plus分页插件 */ @Bean public PaginationInterceptor paginationInterceptor() { PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); return paginationInterceptor; } }
根据版本不同,配置方式可能稍有不同,分页的原理就是通过ibatis提供的sql拦截器进行sql拼接,如果不配置分页将失效,变成普通的列表查询
如果系统中有多个分页插件例如 pagehelper 等,如果未使用自动配置,或冲突的话,也需要进行手动配置
2.使用
测试使用到的类和数据库定义如下
学生信息类
@Data @TableName("student") public class Student { @TableId(type = IdType.AUTO) private Integer id; private String name; private Integer age; private Integer sex; private Integer classId; }
班级信息类
@Data @TableName("class") public class Class { @TableId(type = IdType.AUTO) private Integer id; private String name; private Integer grade; private Integer classIndex; }
数据库定义
create table student ( id int auto_increment primary key, name varchar(255) null, age int null, sex int(1) null, class_id int null ); create table class ( id int auto_increment primary key, name varchar(255) null, grade int null, class_index int null );
- 基础使用,使用BaseMapper 提供的分页方法
Page<Student> studentPage = new Page<Student>(1L, 2L); Page<Student> studentPage1 = studentMapper.selectPage(studentPage, null);
studentPage 和 studentPage1 是完全相同的对象,在Page<T> 类中就保存有分页和查询结果,selectPage方法定义如下
/** * 根据 entity 条件,查询全部记录(并翻页) * * @param page 分页查询条件(可以为 RowBounds.DEFAULT) * @param queryWrapper 实体对象封装操作类(可以为 null) */ <E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
可以通过 queryWrapper拼接自定义参数
- 对于一些复杂查询,连表或者自定义xml等使用
mapper接口定义
Page<StudentVO> selectStudentInfoPage(Page<StudentVO> studentVOPage, @Param("sex") Integer sex);
自定义xml如下
<select id="selectStudentInfoPage" resultType="com.school.beans.vo.StudentVO"> select s.id as id, s.name as name, s.age as age, s.sex as sex, s.class_id as classId, c.name as className, c.grade as grade, c.class_index as classIndex from student s join class c on s.class_id = c.id <where> <if test="sex != null"> s.sex = #{sex} </if> </where> </select>
调用
Page<StudentVO> studentVOPage = new Page<>(1L, 2L); Page<StudentVO> studentVOPage1 = studentMapper.selectStudentInfoPage(studentVOPage, 0);
结果
打印sql
==> Preparing: SELECT COUNT(1) FROM student s JOIN class c ON s.class_id = c.id WHERE s.sex = ? ==> Parameters: 0(Integer) <== Columns: COUNT(1) <== Row: 4 ==> Preparing: select s.id as id, s.name as name, s.age as age, s.sex as sex, s.class_id as classId, c.name as className, c.grade as grade, c.class_index as classIndex from student s join class c on s.class_id = c.id WHERE s.sex = ? LIMIT ?,? ==> Parameters: 0(Integer), 0(Long), 2(Long) <== Columns: id, name, age, sex, classId, className, grade, classIndex <== Row: 1, 喵帕斯, 5, 0, 1, 一年级一班, 1, 1 <== Row: 2, 一条萤, 8, 0, 4, 二年级二班, 2, 2 <== Total: 2 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5cbe95b1]
这种方式需要手动多传入一个page参数,如果自定义参数较多的情况下可能会比较麻烦.其实mybatis
- 使用一个参数进行分页
mapper定义
Page<StudentVO> selectStudentInfoPage2(StudentPageDTO studentPageDTO);
xml与上一种方法类似,只是这里只传入一个参数
<select id="selectStudentInfoPage2" resultType="com.school.beans.vo.StudentVO"> select s.id as id, s.name as name, s.age as age, s.sex as sex, s.class_id as classId, c.name as className, c.grade as grade, c.class_index as classIndex from student s join class c on s.class_id = c.id <where> <if test="sex != null"> s.sex = #{sex} </if> </where> </select>
调用方法
StudentPageDTO studentPageDTO = new StudentPageDTO(0); Page<StudentVO> studentVOPage2 = studentMapper.selectStudentInfoPage2(studentPageDTO);
打印sql
==> Preparing: SELECT COUNT(1) FROM student s JOIN class c ON s.class_id = c.id WHERE s.sex = ? ==> Parameters: 0(Integer) <== Columns: COUNT(1) <== Row: 4 ==> Preparing: select s.id as id, s.name as name, s.age as age, s.sex as sex, s.class_id as classId, c.name as className, c.grade as grade, c.class_index as classIndex from student s join class c on s.class_id = c.id WHERE s.sex = ? LIMIT ?,? ==> Parameters: 0(Integer), 0(Long), 10(Long) <== Columns: id, name, age, sex, classId, className, grade, classIndex <== Row: 1, 喵帕斯, 5, 0, 1, 一年级一班, 1, 1 <== Row: 2, 一条萤, 8, 0, 4, 二年级二班, 2, 2 <== Row: 3, 夏海, 9, 0, 5, 二年级三班, 2, 3 <== Row: 4, 鞠, 10, 0, 10, 五年级一班, 5, 1 <== Total: 4 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@118fbaf0]
结果
可以看到参数和返回结果是同一对象,可以使用该方式进行分页的原因很简单,参数DTO继承了分页对象
@Data @AllArgsConstructor public class StudentPageDTO extends Page { private Integer sex; }
本质上和第一种分页没有区别
总结三种分页本质上都是一样的,通过拦截器拦截分页参数,拼接参数
总结下本人知道的三种方式:
1. 使用mp自带的分页方法分页,优点是方便,缺点是不可以自定义xml对于复杂查询不是很友好
2.自定义xml,传入多个参数,其中包括一个page对象作为分页参数
3.自定义参数DTO继承page对象,传入该对象也可以作为分页参数
3可以看成对于2的一种改造,具体使用看取舍