簡(jiǎn)單看看PageHelper的配置

在java代碼中對(duì)于PageHelper的配置

    @Bean
    public SqlSessionFactory sqlSessionFactoryBean(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        factory.setDataSource(dataSource);
        factory.setTypeAliasesPackage(MODEL_PACKAGE);

        // 配置分頁(yè)插件,詳情請(qǐng)查閱官方文檔
        CustomPageHelper customPageHelper = new CustomPageHelper();
        Properties properties = new Properties();
        properties.setProperty("pageSizeZero", "true");//分頁(yè)尺寸為0時(shí)查詢所有紀(jì)錄不再執(zhí)行分頁(yè)
        properties.setProperty("reasonable", "true");//頁(yè)碼<=0 查詢第一頁(yè),頁(yè)碼>=總頁(yè)數(shù)查詢最后一頁(yè)
        properties.setProperty("supportMethodsArguments", "true");//支持通過(guò) Mapper 接口參數(shù)來(lái)傳遞分頁(yè)參數(shù)
        customPageHelper.setProperties(properties);

        // 添加插件
        factory.setPlugins(new Interceptor[]{customPageHelper});

        // 添加X(jué)ML目錄
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        factory.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
        return factory.getObject();
    }

在xml中配置 Interceptor ==> PageHelper

 6 <configuration>
 7     <plugins>
 8         <plugin interceptor="com.github.pagehelper.PageHelper">
 9             <!--指明數(shù)據(jù)庫(kù) 4.0.0以后不需要設(shè)置此屬性-->
10             <property name="dialect" value="mysql"/>
11             <!-- 該參數(shù)默認(rèn)為false -->
12             <!-- 設(shè)置為true時(shí),會(huì)將RowBounds第一個(gè)參數(shù)offset當(dāng)成pageNum頁(yè)碼使用 -->
13             <!-- 和startPage中的pageNum效果一樣-->
14             <property name="offsetAsPageNum" value="true"/>
15             <!-- 該參數(shù)默認(rèn)為false -->
16             <!-- 設(shè)置為true時(shí),使用RowBounds分頁(yè)會(huì)進(jìn)行count查詢 -->
17             <property name="rowBoundsWithCount" value="true"/>
18             <!-- 設(shè)置為true時(shí),如果pageSize=0或者RowBounds.limit = 0就會(huì)查詢出全部的結(jié)果 -->
19             <!-- (相當(dāng)于沒(méi)有執(zhí)行分頁(yè)查詢,但是返回結(jié)果仍然是Page類型)-->
20             <property name="pageSizeZero" value="true"/>
21             <!-- 3.3.0版本可用 - 分頁(yè)參數(shù)合理化,默認(rèn)false禁用 -->
22             <!-- 啟用合理化時(shí),如果pageNum<1會(huì)查詢第一頁(yè),如果pageNum>pages會(huì)查詢最后一頁(yè) -->
23             <!-- 禁用合理化時(shí),如果pageNum<1或pageNum>pages會(huì)返回空數(shù)據(jù) -->
24             <property name="reasonable" value="true"/>
25             <!-- 3.5.0版本可用 - 為了支持startPage(Object params)方法 -->
26             <!-- 增加了一個(gè)`params`參數(shù)來(lái)配置參數(shù)映射,用于從Map或ServletRequest中取值 -->
27             <!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,orderBy,不配置映射的用默認(rèn)值 -->
28             <!-- 不理解該含義的前提下,不要隨便復(fù)制該配置 -->
29             <property name="params" value="pageNum=start;pageSize=limit;"/>
30             <!-- 支持通過(guò)Mapper接口參數(shù)來(lái)傳遞分頁(yè)參數(shù) -->
31             <property name="supportMethodsArguments" value="true"/>
32             <!-- always總是返回PageInfo類型,check檢查返回類型是否為PageInfo,none返回Page -->
33             <property name="returnPageInfo" value="check"/>
34         </plugin>
35     </plugins>
36 </configuration>

配置SqlSessionFactory,主要是配置mapper映射與pageHelper

1     <!-- SqlSessionFactory -->
2     <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
3         <!--設(shè)置數(shù)據(jù)源-->
4         <property name="dataSource" ref="dataSource"></property>
5         <!--設(shè)置映射文件-->
6         <property name="mapperLocations" value="classpath:mybatis/sqlmap/mapper/*.xml"></property>
7         <!--設(shè)置pageHelper-->
8         <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"></property>
9     </bean>

xml配置參考自在流云的博客

正題部分


實(shí)際上,這些配置都是在進(jìn)行Mybatis插件(plugins)的配置。
Mybatis允許你在已映射語(yǔ)句執(zhí)行過(guò)程中的某一點(diǎn)進(jìn)行攔截調(diào)用,默認(rèn)情況下,MyBatis允許使用插件來(lái)攔截的方法包括:

  • Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
  • ParameterHandler (getParameterObject, setParameters)
  • ResultSetHandler (handleResultSets, handleOutputParameters)
  • StatementHandler (prepare, parameterize, batch, update, query)

這些類中方法的細(xì)節(jié)可以通過(guò)查看每個(gè)方法的簽名來(lái)發(fā)現(xiàn),或者直接查看 MyBatis 的發(fā)行包中的源代碼。 假設(shè)你想做的不僅僅是監(jiān)控方法的調(diào)用,那么你應(yīng)該很好的了解正在重寫的方法的行為。 因?yàn)槿绻谠噲D修改或重寫已有方法的行為的時(shí)候,你很可能在破壞 MyBatis 的核心模塊。 這些都是更低層的類和方法,所以使用插件的時(shí)候要特別當(dāng)心。

通過(guò) MyBatis 提供的強(qiáng)大機(jī)制,使用插件是非常簡(jiǎn)單的,只需實(shí)現(xiàn) Interceptor 接口,并指定了想要攔截的方法簽名即可。


第一個(gè)方法,顧名思義,配置攔截器,攔截器的參數(shù) Invocation 中帶有以下屬性:

  • Object target
  • Method method
  • Object[] args

在PageHelper中,使用了sqlUtil.intercept進(jìn)行了一次轉(zhuǎn)發(fā),將 Invocation 賦值給了SqlUtil的intercept方法
在這個(gè)方法中,調(diào)用了真正的攔截器方法。

第二個(gè)方法,plugin,返回了自身

第三個(gè)方法,用于配置中定義屬性

@SuppressWarnings("rawtypes")
@Intercepts(@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}))
public class CustomPageHelper extends PageHelper{
    private final CustomSqlUtil sqlUtil = new CustomSqlUtil();

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        return sqlUtil.intercept(invocation);
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        sqlUtil.setProperties(properties);
    }
}

這個(gè)時(shí)候反過(guò)來(lái)看,

    // 配置分頁(yè)插件,詳情請(qǐng)查閱官方文檔
    CustomPageHelper customPageHelper = new CustomPageHelper();
    Properties properties = new Properties();
    properties.setProperty("pageSizeZero", "true");//分頁(yè)尺寸為0時(shí)查詢所有紀(jì)錄不再執(zhí)行分頁(yè)
    properties.setProperty("reasonable", "true");//頁(yè)碼<=0 查詢第一頁(yè),頁(yè)碼>=總頁(yè)數(shù)查詢最后一頁(yè)
    properties.setProperty("supportMethodsArguments", "true");//支持通過(guò) Mapper 接口參數(shù)來(lái)傳遞分頁(yè)參數(shù)
    customPageHelper.setProperties(properties);

這些屬性,在PageHelper中,都是需要通過(guò)SqlUtil去處理的。

public void setProperties(Properties properties) {
        super.setProperties(properties);
        //多數(shù)據(jù)源時(shí),獲取jdbcurl后是否關(guān)閉數(shù)據(jù)源
        String closeConn = properties.getProperty("closeConn");
        //解決#97
        if(StringUtil.isNotEmpty(closeConn)){
            this.closeConn = Boolean.parseBoolean(closeConn);
        }
        //數(shù)據(jù)庫(kù)方言
        String dialect = properties.getProperty("dialect");
        String runtimeDialect = properties.getProperty("autoRuntimeDialect");
        if (StringUtil.isNotEmpty(runtimeDialect) && runtimeDialect.equalsIgnoreCase("TRUE")) {
            this.autoRuntimeDialect = true;
            this.autoDialect = false;
            this.properties = properties;
        } else if (StringUtil.isEmpty(dialect)) {
            autoDialect = true;
            this.properties = properties;
        } else {
            autoDialect = false;
            this.dialect = initDialect(dialect, properties);
        }
        try {
            //反射獲取 BoundSql 中的 additionalParameters 屬性
            additionalParametersField = BoundSql.class.getDeclaredField("additionalParameters");
            additionalParametersField.setAccessible(true);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
    }

另外的,同樣重要的是攔截器上的注解

@Intercepts(
@Signature(
type = Executor.class, 
method = "query", 
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}))

@Intercepts表明當(dāng)前對(duì)象是一個(gè)Interceptor
@Signature則表明要攔截的接口、方法以及對(duì)應(yīng)的參數(shù)類型
上面的注解表明,在查詢時(shí),type = Executor.class(暫時(shí)沒(méi)弄明白),字面意思應(yīng)該是在查詢執(zhí)行的時(shí)候,攔截了MappedStatement,Object,RowBounds,ResultHandler。


MappedStatement:對(duì)應(yīng)mapper配置文件中一個(gè)節(jié)點(diǎn),主要描述的是一條SQL語(yǔ)句。
其中有許多屬性,包括使用了哪個(gè)mapper,使用了dao的哪個(gè)方法之類的。


Object:主要指的是參數(shù)
例如使用了condition進(jìn)行查詢,object將帶有Criteria對(duì)象,entityClass,orderBy之類的屬性。


RowBounds:主要指的偏移量,可以用它來(lái)進(jìn)行分頁(yè)(pageHelper好像并不使用它)


ResultHandler:暫時(shí)不知道是干什么的,百度說(shuō):
有些sql查詢會(huì)返回一些復(fù)雜類型,這些復(fù)雜類型沒(méi)有辦法簡(jiǎn)單的通過(guò)xml或者注解配置來(lái)實(shí)現(xiàn),這種時(shí)候我們需要實(shí)現(xiàn)mybatis 的ResultHandler接口,來(lái)做自定義的對(duì)象屬性映射。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. 簡(jiǎn)介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存儲(chǔ)過(guò)程以及高級(jí)映射的優(yōu)秀的...
    笨鳥慢飛閱讀 6,248評(píng)論 0 4
  • MyBatis提供了一種插件(plugin)的功能,雖然叫做插件,但其實(shí)這是攔截器功能。那么攔截器攔截MyBati...
    七寸知架構(gòu)閱讀 3,320評(píng)論 3 54
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,569評(píng)論 19 139
  • 笨分兩種。一種是真笨。一種是懶得聰明。 選擇單身。要么是遇到喜歡的人了,套路都設(shè)好了,唉,太麻煩了。還是干正事吧。...
    君曉墨閱讀 195評(píng)論 0 0
  • 話說(shuō)這李眠花從北至南,帶著九娘一路馬不停蹄,終于在數(shù)月后奔至閩北福州府長(zhǎng)安山山下。這長(zhǎng)安山樹木叢生,蛇毒獸...
    萌萌的飛兒閱讀 407評(píng)論 0 0

友情鏈接更多精彩內(nèi)容