4.1.分页插件
在未引入分页插件的情况下,MybatisPlus是不支持分页功能的,IService和BaseMapper中分页方法都无法正常起效。
所以必须配置分页插件。
4.1.1.配置分页插件
在项目中新建配置类:
java
package com.itheima.mp.config;
import com.baomidou.mybatisplus.annotation.DbType;
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
public class MybatisConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
//初始化核心插件
MybatisPlusInterceptor interceptor=new MybatisPlusInterceptor();
//添加分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}4.1.2.分页API
编写一个分页查询的测试:
java
@Test
void testPageQuery() {
//1.分页查询,new Page()的两个参数分别是:页码、每页大小
Page<User> page = userService.page(new Page<>(2, 2));
//2.总条数
System.out.println("total=" + page.getTotal());
//3.总页数
System.out.println("pages=" + page.getPages());
//4.数据
List<User> records = page.getRecords();
records.forEach(System.out::println);
}测试:
常见api如下:
Java
int pageNo = 1, pageSize = 5;
// 分页参数
Page<User> page = Page.of(pageNo, pageSize);
// 排序参数, 通过OrderItem来指定
page.addOrder(new OrderItem("balance", false));
userService.page(page);4.2.通用分页实体
现在要实现一个用户分页查询的接口,接口规范如下: 
这里定义三个实体:
UserQuery:分页查询条件的实体,包含分页、排序参数、过滤条件PageDTO:分页结果实体,包含总条数、总页数、当前页数据UserVO:用户页面视图实体
4.2.1.实体
UserQuery代码如下:
java
package com.itheima.mp.domain.query;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(description = "用户查询条件实体")
public class UserQuery {
@ApiModelProperty("用户名关键字")
private String name;
@ApiModelProperty("用户状态:1-正常,2-冻结")
private Integer status;
@ApiModelProperty("余额最小值")
private Integer minBalance;
@ApiModelProperty("余额最大值")
private Integer maxBalance;
}其中缺少分页条件,而其他业务也有分页查询的需求,所以将分页查询条件单独定义为一个PageQuery实体:
java
package com.itheima.mp.domain.query;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(description = "分页查询实体")
public class PageQuery {
@ApiModelProperty("页码")
private Long pageNo;
@ApiModelProperty("每页数据条数")
private Long pageSize;
@ApiModelProperty("排序字段")
private String sortBy;
@ApiModelProperty("是否升序")
private Boolean isAsc;
}然后让UserQuery继承这个实体,这样UserQuery也就有这些属性了:
java
package com.itheima.mp.domain.query;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true) //lombok生成equals和hashcode时,把父类里的字段也算进去
@Data
@ApiModel(description = "用户查询条件实体")
public class UserQuery extends PageQuery {
@ApiModelProperty("用户名关键字")
private String name;
@ApiModelProperty("用户状态:1-正常,2-冻结")
private Integer status;
@ApiModelProperty("余额最小值")
private Integer minBalance;
@ApiModelProperty("余额最大值")
private Integer maxBalance;
}返回值的用户实体沿用UserVO实体,同时定义分页实体PageDTO:
java
package com.itheima.mp.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
@ApiModel(description = "分页结果")
public class PageDTO<T> {
@ApiModelProperty("总条数")
private Long total;
@ApiModelProperty("总页数")
private Long pages;
@ApiModelProperty("集合")
private List<T> list;
}4.2.2.开发接口
接下来在UserController中定义分页查询用户接口:
java
@GetMapping("/page")
public PageDTO<UserVO> queryUserPage(UserQuery query){
return userService.queryUsersPage(query);
}在UserService创建方法,同时UserServiceImpl实现方法:
java
@Override
public PageDTO<UserVO> queryUsersPage(UserQuery query) {
//1.构建条件
//1.1.分页条件
Page<User> pageParam=Page.of(query.getPageNo(),query.getPageSize());
//1.2.排序条件
if(StrUtil.isNotBlank(query.getSortBy())){
pageParam.addOrder(new OrderItem(query.getSortBy(), query.getIsAsc()));
}else {
//默认按照更新时间顺序排序
pageParam.addOrder(new OrderItem("update_Time", false));
}
//2.查询
Page<User> page=lambdaQuery().eq(query.getStatus()!=null,User::getStatus,query.getStatus())
.like(query.getName()!=null,User::getUsername,query.getName())
.page(pageParam);
//3.数据非空校验
if(CollUtil.isEmpty(page.getRecords())){
//无数据,返回空结果
return new PageDTO<>(page.getTotal(),page.getPages(),Collections.emptyList());
}
//4.有数据,转换
List<UserVO> list=BeanUtil.copyToList(page.getRecords(), UserVO.class);
//5.封装返回
return new PageDTO<UserVO>(page.getTotal(),page.getPages(),list);
}测试效果: 
4.2.3.改造PageQuery实体
从PageQuery到MybatisPlus的Page转换过程是比较麻烦的。
因此在PageQuery实体中定义一个工具方法,简化开发。
pageQuery代码如下:
java
package com.itheima.mp.domain.query;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(description = "分页查询实体")
public class PageQuery {
@ApiModelProperty("页码")
private Long pageNo;
@ApiModelProperty("每页数据条数")
private Long pageSize;
@ApiModelProperty("排序字段")
private String sortBy;
@ApiModelProperty("是否升序")
private Boolean isAsc;
public <T>Page<T> toMpPage(OrderItem ... items) {
//1.分页条件
Page<T> page = new Page<>(pageNo, pageSize);
//2.排序条件
if(StrUtil.isNotBlank(sortBy)){
//不为空
page.addOrder(new OrderItem(sortBy,isAsc));
}else if(items!=null){
//为空,默认排序
page.addOrder(items);
}
return page;
}
public <T> Page<T> toMpPage(String defaultSortBy, boolean isAsc){
return this.toMpPage(new OrderItem(defaultSortBy, isAsc));
}
public <T> Page<T> toMpPageDefaultSortByCreateTimeDesc() {
return toMpPage("create_time", false);
}
public <T> Page<T> toMpPageDefaultSortByUpdateTimeDesc() {
return toMpPage("update_time", false);
}
}修改实现方法中的转换:
java
@Override
public PageDTO<UserVO> queryUsersPage(UserQuery query) {
//1.构建条件
//1.1.分页条件
Page<User> pageParam= query.toMpPageDefaultSortByUpdateTimeDesc();
//2.查询
Page<User> page=lambdaQuery().eq(query.getStatus()!=null,User::getStatus,query.getStatus())
.like(query.getName()!=null,User::getUsername,query.getName())
.page(pageParam);
//3.数据非空校验
if(CollUtil.isEmpty(page.getRecords())){
//无数据,返回空结果
return new PageDTO<>(page.getTotal(),page.getPages(),Collections.emptyList());
}
//4.有数据,转换
List<UserVO> list=BeanUtil.copyToList(page.getRecords(), UserVO.class);
//5.封装返回
return new PageDTO<UserVO>(page.getTotal(),page.getPages(),list);
}4.2.4.改造PageDTO实体
查询出分页结果后,数据非空校验,数据vo转换都是模板代码,也可以封装到PageDTO工具方法中,代码如下:
java
public static <PO,VO>PageDTO<VO> of(Page<PO> p,Class<VO> voClass){ //构建当前类对象
PageDTO<VO> dto=new PageDTO<>();
//1.总条数
dto.setTotal(p.getTotal());
//2.总页数
dto.setPages(p.getPages());
//3.当前页数据
List<PO> records=p.getRecords();
if(CollUtil.isEmpty(records)){
dto.setList(Collections.emptyList());
return dto;
}
//4.拷贝user的VO
dto.setList(BeanUtil.copyToList(records, voClass));
//5.返回
return dto;
}最终,业务层到吗简化为:
java
@Override
public PageDTO<UserVO> queryUsersPage(UserQuery query) {
//1.构建条件
//1.1.分页条件
//Page<User> pageParam=Page.of(query.getPageNo(),query.getPageSize());
Page<User> pageParam= query.toMpPageDefaultSortByUpdateTimeDesc();
//1.2.排序条件
if(StrUtil.isNotBlank(query.getSortBy())){
pageParam.addOrder(new OrderItem(query.getSortBy(), query.getIsAsc()));
}else {
//默认按照更新时间顺序排序
pageParam.addOrder(new OrderItem("update_Time", false));
}
//2.查询
Page<User> page=lambdaQuery().eq(query.getStatus()!=null,User::getStatus,query.getStatus())
.like(query.getName()!=null,User::getUsername,query.getName())
.page(pageParam);
//3.封装VO结果
return PageDTO.of(page,UserVO.class);
}如果希望自定义PO到VO的转换过程,修改PageDTO代码如下:
java
public static <PO,VO>PageDTO<VO> of(Page<PO> p, Function<PO,VO> convertor){ //构建当前类对象
PageDTO<VO> dto=new PageDTO<>();
//1.总条数
dto.setTotal(p.getTotal());
//2.总页数
dto.setPages(p.getPages());
//3.当前页数据
List<PO> records=p.getRecords();
if(CollUtil.isEmpty(records)){
dto.setList(Collections.emptyList());
return dto;
}
//4.拷贝user的VO
dto.setList(records.stream().map(convertor).collect(Collectors.toList()));
//5.返回
return dto;
}dto.setList(records.stream().map(convertor).collect(Collectors.toList())); 说明:
遍历records里的每一个PO对象
把每个PO对象交给convertor转换
转换后的结果收集成List
设置到dto.list里修改业务层代码:
java
@Override
@Override
public PageDTO<UserVO> queryUsersPage(UserQuery query) {
//1.构建条件
//1.1.分页条件
Page<User> pageParam= query.toMpPageDefaultSortByUpdateTimeDesc();
//2.查询
Page<User> page=lambdaQuery().eq(query.getStatus()!=null,User::getStatus,query.getStatus())
.like(query.getName()!=null,User::getUsername,query.getName())
.page(pageParam);
//3.封装VO结果
return PageDTO.of(page,user->{
//1.拷贝基础属性
UserVO vo=BeanUtil.copyProperties(user,UserVO.class);
//2.处理特殊逻辑
vo.setUsername(vo.getUsername().substring(0,vo.getUsername().length()-2)+"**");
return vo;
});
}测试: 