2021-01-12

自定义注解,更优雅的使用MP分页功能

分页功能使用

MP的分页功能是通过MyBatis的插件实现的,使用起来也非常简单。下面先介绍下使用方式。

step1:配置分页插件

@Configuration@EnableTransactionManagement@MapperScan("com.csx.demo.spring.boot.dao")public class MyBatisPlusConfig { private static final Logger log = LoggerFactory.getLogger(MyBatisPlusConfig.class); @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() {  MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();  // 如果是单数据源的话,最好制定数据库类型,不然的话MP需要根据数据库连接来推断数据库类型  // 性能上略有损失  interceptor.addInnerInterceptor(new PaginationInnerInterceptor());  interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());  return interceptor; }}

需要注意的是:MP提供了很多开箱即用的插件,这些插件的使用顺序有讲究。官方文档建议的配置顺序是:

目前已有的功能:

  • 自动分页: PaginationInnerInterceptor
  • 多租户: TenantLineInnerInterceptor
  • 动态表名: DynamicTableNameInnerInterceptor
  • 乐观锁: OptimisticLockerInnerInterceptor
  • sql性能规范: IllegalSQLInnerInterceptor
  • 防止全表更新与删除: BlockAttackInnerInterceptor

注意:
使用多个功能需要注意顺序关系,建议使用如下顺序
多租户,动态表名
分页,乐观锁
sql性能规范,防止全表更新与删除
总结: 对sql进行单次改造的优先放入,不对sql进行改造的最后放入

step2:写分页代码

IPage<User> page = new Page<>(1,10);((Page<User>) page).addOrder(OrderItem.desc("user_id"));IPage<User> userIPage = userDAO.selectPage(page, null);

自定义注解,更优雅的使用MP分页功能

我们发现:虽然MP的分页插件使用起来非常简单,但是还是需要每次从参数中拿分页参数、排序参数等,代码看起来还是略微显得冗余。

这边定义了一个自定义注解,可以简化上面的这些操作。下面是实现的代码。

step1:定义自己的PageInfo

说明下:这边的PageInfo是可以不定义的,你可以直接使用MP的IPage实现。但是个人具有洁癖,有些信息不想返回前端,所以定义了一个精简的PageInfo.

/** * 自定义的PageInfo * 内容比MP中的IPage精简 * @param <T> */public class PageInfo<T> { private Integer pageNo; private Integer pageSize; private String sortColumn;  private Long total; private List<T> rows;  public PageInfo(Integer pageNo, Integer pageSize, String sortColumn) {  this.pageNo = pageNo;  this.pageSize = pageSize;  this.sortColumn = sortColumn; } // 省略get和set方法}

step2:定义分页注解

@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Pagination { // 可以自定义分页字段名称,当前页字段名称默认是pageNO String pageNoField() default "pageNo"; // 可以自定义分页字段名称,每页数量名称默认是pageNO String pageSizeField() default "pageSize"; // 可以自定义分页字段名称,排序字段名称默认是pageNO String sortField() default "sort"; // 也可以通过注解指定排序字段 String sortItem() default "";}

step3:注解处理类

@Aspect@Componentpublic class PaginationHandler { private static final Logger log = LoggerFactory.getLogger(PaginationHandler.class); private static final int DEFAULT_PAGE_NO = 1; private static final int DEFAULT_PAGE_SIZE = 10; @Around("@annotation(pagination)&&args(pageParam)") public Object handlePagination(ProceedingJoinPoint point,         Pagination pagination,         Object pageParam) throws Throwable {  int pageNo = DEFAULT_PAGE_NO;  int pageSize = DEFAULT_PAGE_SIZE;  String sortCols;  String pageNoField = pagination.pageNoField();  String pageSizeField = pagination.pageSizeField();  String sortField = pagination.sortField();  sortCols = pagination.sortItem();  if (pageParam == null) {   PageInfo pageInfo = new PageInfo(pageNo, pageSize, sortCols);   PageUtil.setPageInfo(pageInfo);  } else {   if (pageParam instanceof Map) {    Map<String, Object> param = (Map<String, Object>) pageParam;    JSONObject json = new JSONObject(param);    if (json.getInteger(pageNoField) != null) {     pageNo = json.getIntValue(pageNoField);    }    if (json.getInteger(pageSizeField) != null) {     pageSize = json.getIntValue(pageSizeField);    }    if (json.getInteger(sortField) != null) {     sortCols = json.getString(sortField);    }    PageInfo pageInfo = new PageInfo(pageNo, pageSize, sortCols);    PageUtil.setPageInfo(pageInfo);   } else {    // 暂时只支持Map类型的参数    // 如果需要支持其他类型的参数,可以在这边添加    PageInfo pageInfo = new PageInfo(pageNo, pageSize, sortCols);    PageUtil.setPageInfo(pageInfo);   }  }  try {   Object result = point.proceed();   if (result instanceof Response) {    Object data = ((Response) result).getData();    if(data instanceof IPage){     long total = ((IPage) data).getTotal();     List records = ((IPage) data).getRecords();     PageInfo pageInfo = PageUtil.getPageInfo();     pageInfo.setTotal(total);     pageInfo.setRows(records);     ((Response) result).setData(pageInfo);    }    return result;   } else {    // Todo 暂时没想到好的处理方法    return result;   }  } finally {   PageUtil.removePageInfo();  } }}

step4:分页工具

public class PageUtil { private static final String ASC = "asc"; private static final String DESC = "desc"; private static final Logger log = LoggerFactory.getLogger(PageUtil.class); private static final ThreadLocal<PageInfo> pageInfoHolder = new ThreadLocal<>(); public static void setPageInfo(PageInfo pageInfo) {  pageInfoHolder.set(pageInfo); } public static void removePageInfo() {  pageInfoHolder.remove(); } public static PageInfo getPageInfo() {  return pageInfoHolder.get(); } public static <T> IPage<T> page() {  PageInfo pageInfo = getPageInfo();  Integer pageNo = pageInfo.getPageNo();  Integer pageSize = pageInfo.getPageSize();  //col1:aes,col2:des形式  String sortCols = pageInfo.getSortColumn();  IPage<T> iPage = new Page<>(pageNo, pageSize);  if (!StringUtils.isEmpty(sortCols)) {   String[] split = sortCols.split(",");   for (String s : split) {    try {     int index = s.lastIndexOf(':');     String col = s.substring(0, index);     String sortType = s.substring(index, s.length());     if(ASC.equalsIgnoreCase(sortCols)){      ((Page<T>) iPage).addOrder(OrderItem.asc(col));     } else if (DESC.equalsIgnoreCase(sortType)){      ((Page<T>) iPage).addOrder(OrderItem.desc(col));     } else {      log.warn("sort col {} is invalid, ignore it...",s);      continue;     }    } catch (Exception e) {     log.warn("sort col {} is invalid, ignore it...",s);    }   }  }  return iPage; }}

step5:使用

 @PostMapping("/page") @Pagination public Object info(@RequestBody Map param) {  IPage<User> page = userService.page(PageUtil.page(), null);  Response response = new Response();  response.success().success().setData(page);  return response; }

上面的代码比较简单,具体就不分析了。









原文转载:http://www.shaoqun.com/a/508505.html

跨境电商:https://www.ikjzd.com/

数魔跨境:https://www.ikjzd.com/w/1425.html

递四方:https://www.ikjzd.com/w/1066


分页功能使用MP的分页功能是通过MyBatis的插件实现的,使用起来也非常简单。下面先介绍下使用方式。step1:配置分页插件@Configuration@EnableTransactionManagement@MapperScan("com.csx.demo.spring.boot.dao")publicclassMyBatisPlusConfig{privatestatic
虚拟信用卡:虚拟信用卡
网络星期一:网络星期一
三水南丹山端午节有包粽子比赛?佛山三水南丹山端午节有比赛看:三水南丹山端午节有包粽子比赛?佛山三水南丹山端午节有比赛看
亚马逊史上最全【批量表格上传】教学!合并 修改 恢复 解除 添加 父子变体+填写方法!!:亚马逊史上最全【批量表格上传】教学!合并 修改 恢复 解除 添加 父子变体+填写方法!!
亚马逊类目审核所需要的FDA认证报告:亚马逊类目审核所需要的FDA认证报告

No comments:

Post a Comment