1. 程式人生 > >springboot中bean形式配置mybatis的分頁外掛

springboot中bean形式配置mybatis的分頁外掛

mybatis的分頁外掛在開發中往往必不可少,使用起來也非常簡單。以往我們的配置都是在xml中進行的,springboot推薦使用bean的形式進行配置。所以,今天就來看看使用java bean的形式配置mybatis的分頁外掛。

1、新增依賴

首先引入必要的依賴:分頁外掛的依賴

<dependency>
	<groupId>com.github.pagehelper</groupId>
	<artifactId>pagehelper</artifactId>
	<version>5.1.7</version>
</dependency>

2、配置攔截器

既然是一個外掛,我們就應該知道它配置在什麼地方。

在SqlSessionFactoryBean中有一個屬性plugins,就是用來配置外掛的:

可以看到,這是一個數組,意思很清楚,就是說我們可以配置多個攔截器(其實就是多個外掛)。

Interceptor介面

我們有必要看看這個介面:

public interface Interceptor {

  Object intercept(Invocation invocation) throws Throwable;

  Object plugin(Object target);

  void setProperties(Properties properties);

}

這個接口裡有三個方法。並且有2個預設的實現類:

(看名字你也大概猜到是幹嘛的啦)

intercept方法:攔截器攔截時執行的,進行相關的邏輯處理。

plugin方法:處理外掛的,這個我們不需要關注。

setProperties方法:這個就是設定引數的,我們通常需要用到這個方法。

如何配置

如上,我們看到Interceptor有2個預設的實現類,第一個PageInterceptor就是用來分頁的。

先說說它配置在哪裡吧:

和mybatis的其他配置一樣,我們需要把它加到sqlSessionFactoryBean裡,其實就是把這個攔截器加入plugins。

@Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) 
        throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources(mapperLocations));
        // 新增分頁外掛
        bean.setPlugins(new Interceptor[]{pageInterceptor()});
        return bean.getObject();
    }

說說分頁引數的配置

上面說到我們需要用到 setProperties方法,接下來就說說這個方法的妙用:

上面我們將pageInterceptor加入到sqlSessionFactoryBean裡,可以看到我寫了個pageInterceptor方法:

    // 分頁攔截器
    private PageInterceptor pageInterceptor(){
        PageInterceptor pageInterceptor = new PageInterceptor();
        // 詳見 com.github.pagehelper.page.PageParams
        Properties p = new Properties();
//        p.setProperty("offsetAsPageNum", "false");
//        p.setProperty("rowBoundsWithCount", "false");
//        p.setProperty("reasonable", "false");
        // 設定資料庫方言 , 也可以不設定,會動態獲取
        p.setProperty("helperDialect", "mysql");
        pageInterceptor.setProperties(p);
        return pageInterceptor;
    }

簡單來看,這個方法就是建立了一個PageInterceptor物件,然後返回。(其實我們可以不做任何配置,就返回這個物件就可以的,但是某些情況下你可能需要做一些自己的配置,而不使用預設的)

可以看到,這裡使用了setProperties方法,在這裡Propertie放的就是配置,是一個鍵值對的。那麼自然不是瞎寫的了。

我們需要知道這些屬性(或者說配置更好理解)都在哪裡用到。就需要由setProperties這個方法往下追程式碼:

(具體這個就不多說了,如果時間允許,你可以自己跟下程式碼的)

我們繼續進入到 上面圈出的方法裡:

此時你會發現,這個方法有多個實現的。既然是分頁,那麼自然就是使用PageHelper這個實現了(其實,上面的default_dialect_class就是這個類)。

繼續進入該方法:

    @Override
    public void setProperties(Properties properties) {
        setStaticProperties(properties);
        pageParams = new PageParams();
        autoDialect = new PageAutoDialect();
        pageParams.setProperties(properties);
        autoDialect.setProperties(properties);
        //20180902新增 aggregateFunctions, 允許手動新增聚合函式(影響行數)
        CountSqlParser.addAggregateFunctions(properties.getProperty("aggregateFunctions"));
    }

在這裡就有你需要的所有的配置:  pageParams 和 autoDialect  (分別是分頁和資料庫方言相關設定)。因為這兩個類裡的註釋寫的很是詳細,我就不多說了,貼出部分程式碼。



package com.github.pagehelper.page;

import com.github.pagehelper.IPage;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageRowBounds;
import com.github.pagehelper.util.PageObjectUtil;
import com.github.pagehelper.util.StringUtil;
import org.apache.ibatis.session.RowBounds;

import java.util.Properties;

/**
 * Page 引數資訊
 *
 * @author liuzh
 */
public class PageParams {
    //RowBounds引數offset作為PageNum使用 - 預設不使用
    protected boolean offsetAsPageNum = false;
    //RowBounds是否進行count查詢 - 預設不查詢
    protected boolean rowBoundsWithCount = false;
    //當設定為true的時候,如果pagesize設定為0(或RowBounds的limit=0),就不執行分頁,返回全部結果
    protected boolean pageSizeZero = false;
    //分頁合理化
    protected boolean reasonable = false;
    //是否支援介面引數來傳遞分頁引數,預設false
    protected boolean supportMethodsArguments = false;
    //預設count(0)
    protected String countColumn = "0";

    /**
     * 獲取分頁引數
     *
     * @param parameterObject
     * @param rowBounds
     * @return
     */
    public Page getPage(Object parameterObject, RowBounds rowBounds) {
        Page page = PageHelper.getLocalPage();
        if (page == null) {
            if (rowBounds != RowBounds.DEFAULT) {
                if (offsetAsPageNum) {
                    page = new Page(rowBounds.getOffset(), rowBounds.getLimit(), rowBoundsWithCount);
                } else {
                    page = new Page(new int[]{rowBounds.getOffset(), rowBounds.getLimit()}, rowBoundsWithCount);
                    //offsetAsPageNum=false的時候,由於PageNum問題,不能使用reasonable,這裡會強制為false
                    page.setReasonable(false);
                }
                if(rowBounds instanceof PageRowBounds){
                    PageRowBounds pageRowBounds = (PageRowBounds)rowBounds;
                    page.setCount(pageRowBounds.getCount() == null || pageRowBounds.getCount());
                }
            } else if(parameterObject instanceof IPage || supportMethodsArguments){
                try {
                    page = PageObjectUtil.getPageFromObject(parameterObject, false);
                } catch (Exception e) {
                    return null;
                }
            }
            if(page == null){
                return null;
            }
            PageHelper.setLocalPage(page);
        }
        //分頁合理化
        if (page.getReasonable() == null) {
            page.setReasonable(reasonable);
        }
        //當設定為true的時候,如果pagesize設定為0(或RowBounds的limit=0),就不執行分頁,返回全部結果
        if (page.getPageSizeZero() == null) {
            page.setPageSizeZero(pageSizeZero);
        }
        return page;
    }

    public void setProperties(Properties properties) {
        //offset作為PageNum使用
        String offsetAsPageNum = properties.getProperty("offsetAsPageNum");
        this.offsetAsPageNum = Boolean.parseBoolean(offsetAsPageNum);
        //RowBounds方式是否做count查詢
        String rowBoundsWithCount = properties.getProperty("rowBoundsWithCount");
        this.rowBoundsWithCount = Boolean.parseBoolean(rowBoundsWithCount);
        //當設定為true的時候,如果pagesize設定為0(或RowBounds的limit=0),就不執行分頁
        String pageSizeZero = properties.getProperty("pageSizeZero");
        this.pageSizeZero = Boolean.parseBoolean(pageSizeZero);
        //分頁合理化,true開啟,如果分頁引數不合理會自動修正。預設false不啟用
        String reasonable = properties.getProperty("reasonable");
        this.reasonable = Boolean.parseBoolean(reasonable);
        //是否支援介面引數來傳遞分頁引數,預設false
        String supportMethodsArguments = properties.getProperty("supportMethodsArguments");
        this.supportMethodsArguments = Boolean.parseBoolean(supportMethodsArguments);
        //預設count列
        String countColumn = properties.getProperty("countColumn");
        if(StringUtil.isNotEmpty(countColumn)){
            this.countColumn = countColumn;
        }
        //當offsetAsPageNum=false的時候,不能
        //引數對映
        PageObjectUtil.setParams(properties.getProperty("params"));
    }

    public boolean isOffsetAsPageNum() {
        return offsetAsPageNum;
    }

    public boolean isRowBoundsWithCount() {
        return rowBoundsWithCount;
    }

    public boolean isPageSizeZero() {
        return pageSizeZero;
    }

    public boolean isReasonable() {
        return reasonable;
    }

    public boolean isSupportMethodsArguments() {
        return supportMethodsArguments;
    }

    public String getCountColumn() {
        return countColumn;
    }
}

小結

在不知不覺中,已經配置完成了。其實配置很簡單,但是我們有必要知道其中的實現流程。

關於分頁如何使用就不多說了,在PageHelper中的很多方法大家一看就懂了。

 

轉載請務必保留此出處(原作者):https://blog.csdn.net/zhuzhezhuzhe1

 

版權宣告:本文為原創文章,允許轉載,轉載時請務必以超連結形式標明文章 原始出處 、作者資訊和本宣告。

https://blog.csdn.net/zhuzhezhuzhe1/article/details/84832400