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的一種改造,具體使用看取舍