搜狗网站优化软件,建网站花多少钱,冠县做网站推广,宜春网站建设4.插件功能
MybatisPlus提供了很多的插件功能#xff0c;进一步拓展其功能。目前已有的插件有#xff1a;
PaginationInnerInterceptor#xff1a;自动分页TenantLineInnerInterceptor#xff1a;多租户DynamicTableNameInnerInterceptor#xff1a;动态表名OptimisticL…4.插件功能
MybatisPlus提供了很多的插件功能进一步拓展其功能。目前已有的插件有
PaginationInnerInterceptor自动分页TenantLineInnerInterceptor多租户DynamicTableNameInnerInterceptor动态表名OptimisticLockerInnerInterceptor乐观锁IllegalSQLInnerInterceptorsql 性能规范BlockAttackInnerInterceptor防止全表更新与删除 注意 使用多个分页插件的时候需要注意插件定义顺序建议使用顺序如下 多租户,动态表名分页,乐观锁sql 性能规范,防止全表更新与删除 这里我们以分页插件为里来学习插件的用法。
4.1.分页插件
在未引入分页插件的情况下MybatisPlus是不支持分页功能的IService和BaseMapper中的分页方法都无法正常起效。
所以我们必须配置分页插件。
4.1.1.配置分页插件
在项目中新建一个配置类 其代码如下
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 {Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {// 初始化核心插件MybatisPlusInterceptor interceptor new MybatisPlusInterceptor();// 添加分页插件PaginationInnerInterceptor paginationInnerInterceptor new PaginationInnerInterceptor(DbType.MYSQL);paginationInnerInterceptor.setMaxLimit(1000L);interceptor.addInnerInterceptor(paginationInnerInterceptor);return interceptor;}
}4.1.2.分页API
编写一个分页查询的测试 Testvoid testPageQuery(){int pageNo 1, pageSize 2;// 1.准备分页条件// 1.1.分页条件PageUser page Page.of(pageNo, pageSize);// 1.2.排序条件 (先按照balance 升序如果存在一致的balance 再按照 id 进行升序排序)page.addOrder(new OrderItem(balance,true));page.addOrder(new OrderItem(id,true));// 2.分页查询PageUser p userService.page(page);// 3.解析long total p.getTotal(); // 总记录数System.out.println(total total);long pages p.getPages(); // 总页数System.out.println(pages pages);ListUser users p.getRecords(); // 分页结果users.forEach(System.out::println);}运行的SQL如下
4.2.通用分页实体
现在要实现一个用户分页查询的接口接口规范如下 返回值如下
这里需要定义3个实体
UserQuery分页查询条件的实体包含分页、排序参数、过滤条件PageDTO分页结果实体包含总条数、总页数、当前页数据UserVO用户页面视图实体
4.2.1.实体
由于UserQuery之前已经定义过了并且其中已经包含了过滤条件具体代码如下
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实体 PageQuery是前端提交的查询参数一般包含四个属性
pageNo页码pageSize每页数据条数sortBy排序字段isAsc是否升序
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继承这个实体
分页实体PageDTO:
代码如下
package com.itheima.mp.domain.dto;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import java.util.List;Data
ApiModel(description 分页结果)
public class PageDTOT {ApiModelProperty(总条数)private Long total;ApiModelProperty(总页数)private Long pages;ApiModelProperty(集合)private ListT list;
}最后是UserVO,在之前有写过:
4.2.2.开发接口
在UserController中定义分页查询用户的接口 代码如下 ApiOperation(根据分页条件查询用户的接口)GetMapping(/page)public PageDTOUserVO queryUsersPage(UserQuery query){return userService.queryUsersPage(query);}然后在IUserService中创建queryUsersPage方法
PageDTOUserVO queryUsersPage(PageQuery query);接下来在UserServiceImpl中实现该方法 Overridepublic PageDTOUserVO queryUsersPage(UserQuery query) {String name query.getName();Integer status query.getStatus();Integer maxBalance query.getMaxBalance();Integer minBalance query.getMinBalance();// 1.1.分页条件PageUser page Page.of(query.getPageNo(), query.getPageSize());// 1.2.排序条件if (StrUtil.isNotBlank(query.getSortBy())) { // 排序条件不为空page.addOrder(new OrderItem(query.getSortBy(), query.getIsAsc()));} else { // 排序条件为空默认按照更新时间进行降序排序page.addOrder(new OrderItem(update_time, false));}// 2.分页查询PageUser p lambdaQuery().like(name ! null, User::getUsername, name).eq(status ! null, User::getStatus, status).ge(minBalance ! null, User::getBalance, minBalance).le(maxBalance ! null, User::getBalance, maxBalance).page(page);// 3.封装VO结果PageDTOUserVO dto new PageDTO();// 3.1.总条数dto.setTotal(p.getTotal());// 3.2.总页数dto.setPages(p.getPages());// 3.3.当前页数据ListUser records p.getRecords();if (CollUtil.isEmpty(records)) {dto.setList(Collections.emptyList());return dto;}// 3.4.拷贝user的vodto.setList(BeanUtil.copyToList(records, UserVO.class));// 4.返回return dto;}启动项目在测试效果
4.2.3.改造PageQuery实体
在刚才的代码中从PageQuery到MybatisPlus的Page之间转换的过程还是比较麻烦的。
我们完全可以在PageQuery这个实体中定义一个工具方法简化开发。 像这样 package com.itheima.mp.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 PageT toMpPage(OrderItem ... orders){// 1.分页条件PageT 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 PageT toMpPage(String defaultSortBy, boolean isAsc){return this.toMpPage(new OrderItem(defaultSortBy, isAsc));}public T PageT toMpPageDefaultSortByCreateTimeDesc() {return toMpPage(create_time, false);}public T PageT toMpPageDefaultSortByUpdateTimeDesc() {return toMpPage(update_time, false);}
}这样可以省去对从PageQuery到MybatisPlus的Page的转换,UserServiceImpl简化如下
PageUser page query.toMpPageDefaultSortByUpdateTimeDesc();4.2.4.改造PageDTO实体
在查询出分页结果后数据的非空校验数据的vo转换都是模板代码编写起来很麻烦。 我们完全可以将其封装到PageDTO的工具方法中简化整个过程 代码如下
package com.itheima.mp.domain.dto;import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
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
ApiModel(description 分页结果)
public class PageDTOT {ApiModelProperty(总条数)private Long total;ApiModelProperty(总页数)private Long pages;ApiModelProperty(集合)private ListT list;/*** 返回空分页结果* param p MybatisPlus的分页结果* param V 目标VO类型* param P 原始PO类型* return VO的分页对象*/public static V, P PageDTOV empty(PageP 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 PageDTOV of(PageP p, ClassV voClass) {// 1.非空校验ListP records p.getRecords();if (records null || records.size() 0) {// 无数据返回空结果return empty(p);}// 2.数据转换ListV 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 PageDTOV of(PageP p, FunctionP, V convertor) {// 1.非空校验ListP records p.getRecords();if (records null || records.size() 0) {// 无数据返回空结果return empty(p);}// 2.数据转换ListV vos records.stream().map(convertor).collect(Collectors.toList());// 3.封装返回return new PageDTO(p.getTotal(), p.getPages(), vos);}
}最终业务简化如下 代码如下 Overridepublic PageDTOUserVO queryUsersPage(UserQuery query) {String name query.getName();Integer status query.getStatus();Integer maxBalance query.getMaxBalance();Integer minBalance query.getMinBalance();// 1.构建分页条件PageUser page query.toMpPageDefaultSortByUpdateTimeDesc();// 2.分页查询PageUser p lambdaQuery().like(name ! null, User::getUsername, name).eq(status ! null, User::getStatus, status).ge(minBalance ! null, User::getBalance, minBalance).le(maxBalance ! null, User::getBalance, maxBalance).page(page);// 3.封装返回return PageDTO.of(page, UserVO.class);}如果是希望自定义PO到VO的转换过程可以这样做 Overridepublic PageDTOUserVO queryUsersPage(UserQuery query) {String name query.getName();Integer status query.getStatus();Integer maxBalance query.getMaxBalance();Integer minBalance query.getMinBalance();// 1.构建分页条件PageUser page query.toMpPageDefaultSortByUpdateTimeDesc();// 2.分页查询PageUser p lambdaQuery().like(name ! null, User::getUsername, name).eq(status ! null, User::getStatus, status).ge(minBalance ! null, User::getBalance, minBalance).le(maxBalance ! null, User::getBalance, maxBalance).page(page);// 3.封装返回// return PageDTO.of(page, UserVO.class);return PageDTO.of(page, user - {// 拷贝属性到VOUserVO vo BeanUtil.copyProperties(user, UserVO.class);// 用户名脱敏String username vo.getUsername();vo.setUsername(username.substring(0, username.length() - 2) **);return vo;});}查询的结果如下