使用AOP+mybatis+分页插件PageHelper分批查询数据库

有时候,数据库中的内容太多,无法一次查询出来,这时候就需要分批查询。如果在每个需要分批查询的地方,都去修改原来的代码,实现分批,这样会很麻烦。而Mybatis的分页插件,正好可以配合AOP来进行无侵入式分页,不需要修改原有的代码。下面介绍一下实现步骤:

环境:springBoot+mybatis

1.在工程中引入mybatis的分页插件

compile("com.baomidou:mybatis-plus-boot-starter:2.3")
compile group: 'com.github.pagehelper', name: 'pagehelper', version: '5.1.11'

2.把分页插件传入SqlSessionFactoryBean

@Configuration
@MapperScan("demo.dao")
public class MybatisConfig {

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource)
            throws Exception{
        SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
        fb.setDataSource(dataSource);
        fb.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath:demo/dao/*.xml"));
        Interceptor[] plugins = new Interceptor[1];
        plugins[0] = paginationInterceptor();
        fb.setPlugins(plugins);
        return fb.getObject();
    }


    /**
     * mybatis分页插件,因为我使用oracle数据库,所以这里传入了oracle
     * @return
     */
    public Interceptor paginationInterceptor() {
        PageInterceptor pageInterceptor = new PageInterceptor();
        Properties properties = new Properties();
        properties.setProperty("helperDialect","Oracle");
        pageInterceptor.setProperties(properties);
        return pageInterceptor;
    }

}

3.自定义一个注解@PageDao,这里有3个变量,value代表分页操作的名称,size表示分页大小,returnValue表示是否需要一次返回所有批次的值

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PageDao {
    /**
     * 分批操作名称
     */
    String value() default "";
    /**
     * 分页大小,默认100
     */
    int size() default 100;

    /**
     * 分批查询方法是否需要返回值,默认不返回
     * 如果需要返回所有批次的值,可能分批就没有意义,分批是为了解决内存溢出的问题
     */
    boolean returnValue() default false;

}

4.定义一个切面,使用@PageDao作为切面

@Aspect
@Component
public class PageDaoAop {
    @Around("@annotation(pageDao)")
    public Object around(ProceedingJoinPoint joinPoint, PageDao pageDao) throws Throwable{
        int page = 1;
        int size = pageDao.size();
        if(size<=0)
            size = 100;

        boolean returnValue = pageDao.returnValue();
        List<Object> totalResult = new ArrayList<>();
        while(true){
            Page pageInfo = PageHelper.startPage(page, size);
            Object result = joinPoint.proceed();
            System.out.println(pageDao.value()
                    +" 当前页数["+page
                    +"],页大小["+pageInfo.getPageSize()
                    +"],当页大小["+(pageInfo.getResult().size())
                    +"],总页数["+pageInfo.getPages()
                    +"],总记录数["+pageInfo.getTotal()+"]"
            );
            if(returnValue) {
                if (result instanceof Collection) {
                    Collection<?> collection = (Collection<?>) result;
                    totalResult.addAll(collection);
                } else {
                    totalResult.add(result);
                }
            }

            if(pageInfo.getPageNum()>=pageInfo.getPages()){
                break;
            }
            page++;
            pageInfo.setCount(false);
        }
        if(returnValue)
            return totalResult;
        return null;
    }

}

5.使用。我们在service的方法上注解上@PageDao,其余代码不需要变

    @PageDao(value = "网元参数迁移", size = 10000)
    public void doTask() {

        List<String> results = mapper.selectAll();    //直接调用mybatis的mapper的列表全查方法即可

        //查询结果以追加方式写入文件,所以不需要一次返回所有批次的结果
        //FileUtils是自己写的类
        FileUtils.writeFile(results ,"dist\\test.sql", true);
    }

6.效果

网元参数迁移 当前页数[1],页大小[10000],当页大小[10000],总页数[105],总记录数[1040376]
网元参数迁移 当前页数[2],页大小[10000],当页大小[10000],总页数[105],总记录数[1040376]
网元参数迁移 当前页数[3],页大小[10000],当页大小[10000],总页数[105],总记录数[1040376]
网元参数迁移 当前页数[4],页大小[10000],当页大小[10000],总页数[105],总记录数[1040376]
网元参数迁移 当前页数[5],页大小[10000],当页大小[10000],总页数[105],总记录数[1040376]
网元参数迁移 当前页数[6],页大小[10000],当页大小[10000],总页数[105],总记录数[1040376]
网元参数迁移 当前页数[7],页大小[10000],当页大小[10000],总页数[105],总记录数[1040376]
网元参数迁移 当前页数[8],页大小[10000],当页大小[10000],总页数[105],总记录数[1040376]
网元参数迁移 当前页数[9],页大小[10000],当页大小[10000],总页数[105],总记录数[1040376]
网元参数迁移 当前页数[10],页大小[10000],当页大小[10000],总页数[105],总记录数[1040376]
...
网元参数迁移 当前页数[100],页大小[10000],当页大小[10000],总页数[105],总记录数[1040376]
网元参数迁移 当前页数[101],页大小[10000],当页大小[10000],总页数[105],总记录数[1040376]
网元参数迁移 当前页数[102],页大小[10000],当页大小[10000],总页数[105],总记录数[1040376]
网元参数迁移 当前页数[103],页大小[10000],当页大小[10000],总页数[105],总记录数[1040376]
网元参数迁移 当前页数[104],页大小[10000],当页大小[10000],总页数[105],总记录数[1040376]
网元参数迁移 当前页数[105],页大小[10000],当页大小[376],总页数[105],总记录数[1040376]

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值