使用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]

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章