【Java 知识】AOP-分页处理

摘要:本篇文章主要讲解的何使用Spring boot AOP +自定义注解+PageHelper来实现无侵入式的分页。传统的分页方式需要我们手动在每个接口中使用重复性的分页代码,这显然是不够明智的选择。相关AOP的内容可参考之前的文章,本文仅介绍使用自定义注解与Spring boot AOP完成分页处理的具体步骤。

常用分页问题

使用PageHelper分页工具的一般步骤如下:

  • 编写一个查询sql,一般定义到mapper中;
  • 编写一个分页查询方法,设置PageHelper的当前页和页大小;
  • 执行查询语句;
  • 查询完成后把PageInfo的数据填充到自定义的PageBean中。

示例代码如下:

public PageBean<ReportTemplate> selectPage(PageBean<User> page) {
        // 通过PageHelper设置当前页和页大小
        PageHelper.startPage(page.getPageNo(), page.getPageSize());
        PageHelper.orderBy(page.getSortedField());
        List<User> users= userMapper.selectList(page.getKeyWords());
        PageInfo<User> pageInfo = new PageInfo<>(users);
        page.setCount(pageInfo.getTotal());
        page.setList(pageInfo.getList());
        return page;
}

分析以上步骤我们可以发现,除了第一步我们需要手动编写SQL查询语句,其他都是重复步骤。如果能将其封装成一个注解来使用,就会非常简单和优雅,因此需要结合Spring boot AOP来实现。

AOP 分页处理

实现步骤总结如下:

  • 引入相关依赖pagehelper-spring-boot-starterspring-boot-starter-aop
  • 定义@Page注解;
  • 定义PageVo分页参数;
  • 定义PageAspect分页切面。

引入相关依赖pagehelper-spring-boot-starterspring-boot-starter-aop

<!--MyBatis分页插件starter-->
<dependency>
  <groupId>com.github.pagehelper</groupId>
  <artifactId>pagehelper-spring-boot-starter</artifactId>
  <version>${pagehelper-starter.version}</version>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-aop</artifactId>
</dependency>  

定义@Page注解:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Page {
    /**
     * 用于绑定的请求参数名字
     */
    String value() default "";
}

定义PageVo分页参数:

/**
 * 分页参数
 **/

public class PageVo implements Serializable{
    private static final long serialVersionUID = -1305720016123712695L;
        // 当前页
        private String pageNum;
        // 每页显示条数
        private String pageSize;
        // 查询参数
        private Map<String, Object> parameters = new HashMap<>(10);
        // 排序参数
        private Map<String, Object> sort = new HashMap<>(10);

        public String getPageNum() {
            return pageNum;
        }
        public void setPageNum(String pageNum) {
            this.pageNum = pageNum;
        }
        public String getPageSize() {
            return pageSize;
        }
        public void setPageSize(String pageSize) {
            this.pageSize = pageSize;
        }
        public Map<String, Object> getParameters() {
            return parameters;
        }
        public void setParameters(Map<String, Object> parameters) {
            this.parameters = parameters;
        }
        public Map<String, Object> getSort() {
            return sort;
        }
        public void setSort(Map<String, Object> sort) {
            this.sort = sort;
        }
}

定义PageAspect分页切面:

/**
 * 分页处理切面
 **/
@Aspect
@Component
@Order(1)
public class PageAspect {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Pointcut("@annotation(com.xxx.annotation.Page)")
    public void page() {
    }

    @Around("page()")
    public Object processPage(ProceedingJoinPoint jp) throws java.lang.Throwable {
        // 获取目标方法原始的调用参数
        Object[] args = jp.getArgs();
        PageVo pageVo = new PageVo();
        if (args != null && args.length > 0 && args[0] instanceof PageVo) {
            // 修改目标方法的第一个参数
            pageVo = (PageVo) args[0];
            logger.info("当前页为:{},每页{}条数据", pageVo.getPageNum(), pageVo.getPageSize());
            logger.info("查询条件为:{}", pageVo.getParameters());
        }
        logger.info("执行查询===");
        // 以改变后的参数去执行目标方法,并保存目标方法执行后的返回值
        Object result = null;
        try {
            PageHelper.clearPage();
            if (pageVo != null && pageVo.getPageNum() != null) {
                PageHelper.startPage(Integer.parseInt(pageVo.getPageNum()), Integer.parseInt(pageVo.getPageSize())).setReasonable(false);
            }
            result = jp.proceed(args);
            logger.info("查询结束===");
            // 如果result的类型是list,并且参数类型为pageVo,将result初始化到分页中
            if (result != null && result instanceof List && args[0] instanceof PageVo) {
                ArrayList resultList = (ArrayList) result;
                logger.info("返回查询结果size={}", resultList.size());
                PageInfo<Object> pageInfo = new PageInfo<Object>(resultList);
                logger.info("pageInfo={},pageDataSize={}", pageInfo.getList(), pageInfo.getPageSize());
                // 将pageInfo中多余的参数去除掉
                ReturnInfo info = new ReturnInfo();
                info.setStatus(ReturnState.SUCCESS);
                info.setMessage("");
                Map<String, Object> page = Maps.newHashMap();
                page.put("totalCount", pageInfo.getTotal());
                page.put("pageSize", pageInfo.getPageSize());
                page.put("currentPage", pageInfo.getPageNum());
                page.put("totalPage", pageInfo.getPages());
                info.setReturnData(pageInfo.getList());
                info.setPageInfo(page);
                return info;
            }
            return result;
        } finally {
            logger.info("清除PageInfo的分页查询");
            PageHelper.clearPage();
        }
    }
}

使用示例:

public Object listTransferMarket(PageVo pageVo) {
        logger.info("listTransferMarket para:{}", JSON.toJSONString(pageVo));
        return this.newProductTransferRecordManager.getTransferMarketListManager(pageVo);
    }

@Page
public Object getTransferMarketListManager(PageVo pageVo) {
  List<Map<String, Object>> list = this.newProductTransferRecordMapper.getTransferMarketList(pageVo);
  return list;
}

List<Map<String,Object>> getTransferMarketList(@Param("pageVo") PageVo pageVo);

相关推荐

微信扫一扫,分享到朋友圈

【Java 知识】AOP-分页处理
返回顶部

显示

忘记密码?

显示

显示

获取验证码

Close