MyBatis-Plus 实战教程四 idea插件(一)https://developer.aliyun.com/article/1391864
开发接口
我们在UserController中定义分页查询用户的接口:
package com.onenewcode.mpdemo.controller; import com.onenewcode.mpdemo.domain.dto.PageDTO; import com.onenewcode.mpdemo.domain.query.PageQuery; import com.onenewcode.mpdemo.domain.vo.UserVO; import com.onenewcode.mpdemo.service.UserService; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("users") @RequiredArgsConstructor public class UserController { private final UserService userService; @GetMapping("/page") public PageDTO<UserVO> queryUsersPage(UserQuery query){ return userService.queryUsersPage(query); } // 。。。 略 }
然后在IUserService中创建queryUsersPage方法:
PageDTO<UserVO> queryUsersPage(PageQuery query);
接下来,在UserServiceImpl中实现该方法:
@Override public PageDTO<UserVO> queryUsersPage(PageQuery query) { // 1.构建条件 // 1.1.分页条件 Page<User> page = Page.of(query.getPageNo(), query.getPageSize()); // 1.2.排序条件 if (query.getSortBy() != null) { page.addOrder(new OrderItem(query.getSortBy(), query.getIsAsc())); }else{ // 默认按照更新时间排序 page.addOrder(new OrderItem("update_time", false)); } // 2.查询 page(page); // 3.数据非空校验 List<User> records = page.getRecords(); if (records == null || records.size() <= 0) { // 无数据,返回空结果 return new PageDTO<>(page.getTotal(), page.getPages(), Collections.emptyList()); } // 4.有数据,转换 List<UserVO> list = BeanUtil.copyToList(records, UserVO.class); // 5.封装返回 return new PageDTO<UserVO>(page.getTotal(), page.getPages(), list); }
改造PageQuery实体
在刚才的代码中,从PageQuery到MybatisPlus的Page之间转换的过程还是比较麻烦的。
我们完全可以在PageQuery这个实体中定义一个工具方法,简化开发。
像这样:
package com.onenewcode.mpdemo.domain.query; import com.baomidou.mybatisplus.core.metadata.OrderItem; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.Data; @Data public class PageQuery { private Integer pageNo; private Integer pageSize; private String sortBy; private Boolean isAsc; public <T> Page<T> toMpPage(OrderItem ... orders){ // 1.分页条件 Page<T> p = Page.of(pageNo, pageSize); // 2.排序条件 // 2.1.先看前端有没有传排序字段 if (sortBy != null) { p.addOrder(new OrderItem(sortBy, isAsc)); return p; } // 2.2.再看有没有手动指定排序字段 if(orders != null){ p.addOrder(orders); } return p; } 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); } }
这样我们在开发也时就可以省去对从PageQuery到Page的的转换:
// 1.构建条件
Page<User> page = query.toMpPageDefaultSortByCreateTimeDesc();
改造PageDTO实体
在查询出分页结果后,数据的非空校验,数据的vo转换都是模板代码,编写起来很麻烦。
我们完全可以将其封装到PageDTO的工具方法中,简化整个过程:
package com.onenewcode.mpdemo.domain.dto; import cn.hutool.core.bean.BeanUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.Collections; import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; @Data @NoArgsConstructor @AllArgsConstructor public class PageDTO<V> { private Long total; private Long pages; private List<V> list; /** * 返回空分页结果 * @param p MybatisPlus的分页结果 * @param <V> 目标VO类型 * @param <P> 原始PO类型 * @return VO的分页对象 */ public static <V, P> PageDTO<V> empty(Page<P> p){ return new PageDTO<>(p.getTotal(), p.getPages(), Collections.emptyList()); } /** * 将MybatisPlus分页结果转为 VO分页结果 * @param p MybatisPlus的分页结果 * @param voClass 目标VO类型的字节码 * @param <V> 目标VO类型 * @param <P> 原始PO类型 * @return VO的分页对象 */ public static <V, P> PageDTO<V> of(Page<P> p, Class<V> voClass) { // 1.非空校验 List<P> records = p.getRecords(); if (records == null || records.size() <= 0) { // 无数据,返回空结果 return empty(p); } // 2.数据转换 List<V> vos = BeanUtil.copyToList(records, voClass); // 3.封装返回 return new PageDTO<>(p.getTotal(), p.getPages(), vos); } /** * 将MybatisPlus分页结果转为 VO分页结果,允许用户自定义PO到VO的转换方式 * @param p MybatisPlus的分页结果 * @param convertor PO到VO的转换函数 * @param <V> 目标VO类型 * @param <P> 原始PO类型 * @return VO的分页对象 */ public static <V, P> PageDTO<V> of(Page<P> p, Function<P, V> convertor) { // 1.非空校验 List<P> records = p.getRecords(); if (records == null || records.size() <= 0) { // 无数据,返回空结果 return empty(p); } // 2.数据转换 List<V> vos = records.stream().map(convertor).collect(Collectors.toList()); // 3.封装返回 return new PageDTO<>(p.getTotal(), p.getPages(), vos); } }
最终,业务层的代码可以简化为:
@Override public PageDTO<UserVO> queryUserByPage(PageQuery query) { // 1.构建条件 Page<User> page = query.toMpPageDefaultSortByCreateTimeDesc(); // 2.查询 page(page); // 3.封装返回 return PageDTO.of(page, UserVO.class); }
如果是希望自定义PO到VO的转换过程,可以这样做:
@Override public PageDTO<UserVO> queryUserByPage(PageQuery query) { // 1.构建条件 Page<User> page = query.toMpPageDefaultSortByCreateTimeDesc(); // 2.查询 page(page); // 3.封装返回 return PageDTO.of(page, user -> { // 拷贝属性到VO UserVO vo = BeanUtil.copyProperties(user, UserVO.class); // 用户名脱敏 String username = vo.getUsername(); vo.setUsername(username.substring(0, username.length() - 2) + "**"); return vo; }); }
仓库地址
https://github.com/onenewcode/mp-demo.git