当前位置: 首页 > news >正文

MybatisPlus-20.插件功能-通用分页实体与MP转换

一.通用分页实体与MP转换

回顾我们之前写的代码,在查询出分页结果后,数据的非空校验,数据的vo转换都是模板代码,编写起来很麻烦。我们完全可以将其封装到PageQueryDTO的工具方法中,简化整个过程:

package com.itheima.mp.domain.dto;import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.mp.domain.po.User;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;@Data
@ApiModel(description = "分页查询条件实体")
public class PageQueryDTO {@ApiModelProperty("当前页码")private Integer pageNum;@ApiModelProperty("每页记录数")private Integer pageSize;@ApiModelProperty("排序字段")private String sort;@ApiModelProperty("排序方式:asc-升序,desc-降序")private Boolean isAsc;// 封装成MyBatis Plus的Page对象public <T> Page<T> toMpPage(OrderItem ... orderItems) {// 1.创建Page对象,指定当前页码和每页记录数Page<T> page = new Page<>(pageNum, pageSize);// 2.设置排序字段和排序方式if (sort != null) {page.addOrder(new OrderItem(sort, isAsc));} else if (orderItems != null){// 没有排序字段,要传入默认排序字段是什么,按照默认的排序字段进行排序page.addOrder(orderItems);}return page;}// 封装成MyBatis Plus的Page对象,按照create_time进行排序public <T> Page<T> toMpPageOrderByCreateTime() {return toMpPage(new OrderItem("create_time", false));}// 封装成MyBatis Plus的Page对象,按照create_time进行排序public <T> Page<T> toMpPageOrderByUpdateTime() {return toMpPage(new OrderItem("update_time", false));}// 封装成MyBatis Plus的Page对象,按照指定字段进行排序。不用传入OrderItem对象,直接传入字段名和排序方式即可public <T> Page<T> toMpPage(String defaultSortBy, Boolean defaultIsAsc) {return toMpPage(new OrderItem(defaultSortBy, defaultIsAsc));}
}

首先在封装时为了封装为Page对象,我们定义一个toMpPage()方法,该方法的返回值是一个存储类型为泛型的Page对象,用来剥离实际业务进行开发。其中传入参数为可变参数,为OrderItem类型,用来指定排序字段。如果UserQueryDTO中没有排序字段,则按照指定的排序字段进行排序。用户需要创建一个OrderItem对象来指定排序字段。

我们还定义了按照create_time和update_time来排序的方法。以及如果用户不想创建OrderItem对象,但是又想进行排序的话,要求他传入排序字段defaultSortBy和排序顺序字段defaultIsAsc,我们为其创建一个OrderItem类型的对象进行排序。

改造后的代码如下:

@Overridepublic PageVO<UserVO> queryListPage(UserQueryDTO userQueryDTO) {Page<User> page = userQueryDTO.toMpPageOrderByUpdateTime();// 3.将Page查询条件封装进QueryWrapperPage<User> p = lambdaQuery().like(User::getUsername, userQueryDTO.getName()).eq(User::getStatus, userQueryDTO.getStatus()).page(page);}

二.Page<User>对象转为Page<UserVO>对象

此外,我们的代码中创建Page<UserVO>对象,并将Page<User>对象转为Page<UserVO>对象的逻辑也可以将其封装到PageVO的工具方法中:

package com.itheima.mp.domain.vo;import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.mp.domain.po.User;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;@Data
@ApiModel(description = "分页VO实体")
// 定义一个统一的分页结果
public class PageVO<T> {@ApiModelProperty("总记录数")private Long total;@ApiModelProperty("总页数")private Long pages;@ApiModelProperty("当前页数据")private List<T> records;public static <VO, PO> PageVO<VO> of(Page<PO> p, Function<PO, VO> convertor) {// 4.获取查询结果// 4.1 获取总页数Long pages = p.getPages();// 4.2 获取总记录数Long total = p.getTotal();// 4.3 获取当前页数据List<PO> records = p.getRecords();// 5.封装PageVOPageVO<VO> pageVO = new PageVO<>();pageVO.setPages(pages);pageVO.setTotal(total);if (records == null) {pageVO.setRecords(Collections.emptyList());return pageVO;}// 使用stream流和map方法以及函数式语法将当前页数据转换成UserVO,其中函数式编程满足用户特殊的转换需求(解决PO和VO属性名不一致的问题)pageVO.setRecords(records.stream().map(convertor).collect(Collectors.toList()));return pageVO;}
}

我们首先将第一步生成好的Page<PO>对象传入,并获取其属性赋值给Page<VO>对象。接下来就进行最为关键的一步。将Page<PO>对象的当前页数据集合List<PO>转换为List<VO>,并将其封装在Page<VO>对象中。

如果PO和VO的属性名称和类型一样,我们可以使用BeanUtil工具类完成。但是如果两者不一样,那么我们就要进行定制化处理。为了解决这一问题,我们提供一个函数式编程参数,让用户自己去编写转换方法。其中map方法中传入的就是一个函数式编程参数,将其结果返回并收集到List集合中。该List集合作为Page<VO>的当前页数据,将Page<VO>返回。

最终方法如下:

@Overridepublic PageVO<UserVO> queryListPage(UserQueryDTO userQueryDTO) {Page<User> page = userQueryDTO.toMpPageOrderByUpdateTime();// 3.将Page查询条件封装进QueryWrapperPage<User> p = lambdaQuery().like(User::getUsername, userQueryDTO.getName()).eq(User::getStatus, userQueryDTO.getStatus()).page(page);return PageVO.of(p, new Function<User, UserVO>() {@Overridepublic UserVO apply(User user) {UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);// 对用户名进行脱敏userVO.setUsername(user.getUsername().substring(0,user.getUsername().length() - 2) + "**");return userVO;}});}

最终查询的结果如下:

http://www.dtcms.com/a/305202.html

相关文章:

  • 推动技术的发展和创新:编程是IT行业中最为基础和核心的技能之一
  • 计算机网络五层模型
  • echarts(4.9.0)x轴标签过长,截取指定长度显示三个点,鼠标放上去显示完整标签示例
  • “影子插桩”:利用 LLVM 在二进制层面对 dlsym 调用做无痕监控(C/C++实现)
  • 前端基础之《Vue(26)—Vue3两种语法范式》
  • C++(面向对象之继承、多态)
  • C++20协程实战:高效网络库、手机终端、多媒体开发开发指南
  • 嵌入向量与向量数据库:AI时代的语义搜索革命
  • 【Git】分支
  • 前端接入DeepSeek
  • 数据结构(6)单链表算法题(下)
  • 如何使用Spring AI框架开发mcp接口并发布成微服务
  • C51 中断
  • 笔试——Day22
  • 【Android】日期选择器
  • 镁金属接骨螺钉注册检测:骨科植入安全的科学基石
  • 【面试】软件测试面试题
  • ICT模拟零件测试方法--电阻测试
  • 集成电路学习:什么是WDT看门狗定时器
  • Java中的异常判断以及文件中的常用方法及功能
  • UCLAMP0501P.TCT SEMTECH:超低电容TVS二极管 0.25pF+20kV防护!
  • Python与Spark
  • 26考研11408数据结构
  • yolo11安卓端部署检测图片
  • Docker用Web应用实例深入容器
  • Docker初学者需要了解的几个知识点(三):Docker引擎与Docker Desktop
  • prometheus_client 调用统计
  • 2025年中科院与JCR期刊分区深度对比(第一期):TON中科院分区3区不变,JCR分区升至Q1;TOSEM重回中科院1区!
  • Wan2.1
  • openEuler性能测试常用工具-fio开源压力测试工具