Mybatis 的分頁插件PageHelper-4.1.1的使用

1、maven

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

2、基於spring的配置(spring-config-datasource.xml)

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="mapperLocations" value="classpath*:/sqlmap/db/**/*Mapper.xml"/>
        <property name="dataSource" ref="dataSource"/>
        <property name="plugins">
            <array>
                <bean class="com.github.pagehelper.PageHelper">
                    <property name="properties">
                        <value>
                            dialect=mysql
                            offsetAsPageNum=true
                            rowBoundsWithCount=true
                            pageSizeZero=true
                            reasonable=false
                            supportMethodsArguments=false
                            returnPageInfo=none
                        </value>
                    </property>
                </bean>
            </array>
        </property>
    </bean>

這裏也可以在mybatis-config.xml裏配置,有興趣的話可以百度下。

3、使用方法
  pageHelper會使用ThreadLocal獲取到同一線程中的變量信息,各個線程之間的Threadlocal不會相互干擾,也就是Thread1中的ThreadLocal1之後獲取到Tread1中的變量的信息,不會獲取到Thread2中的信息。
  所以在多線程環境下,各個Threadlocal之間相互隔離,可以實現,不同thread使用不同的數據源或不同的Thread中執行不同的SQL語句。
  所以,PageHelper利用這一點通過攔截器獲取到同一線程中的預編譯好的SQL語句之後將SQL語句包裝成具有分頁功能的SQL語句,並將其再次賦值給下一步操作,所以實際執行的SQL語句就是有了分頁功能的SQL語句。
  PageHelper只對緊跟着的第一個SQL語句起作用
  如上:所以若一個方法中涉及到多個查詢,需要小心,避免爲不需要分頁的添加了分頁,而真正需要分頁的卻沒有被分頁。
  1)、統計總數,(將SQL語句變爲 select count(0) from xxx,只對簡單SQL語句其效果,複雜SQL語句需要自己寫)
Page<?> page = PageHelper.startPage(1,-1);
long count = page.getTotal();
2)、分頁,pageNum - 第N頁, pageSize - 每頁M條數
A、只分頁不統計(每次只執行分頁語句)
PageHelper.startPage([pageNum],[pageSize]);
List<?> pagelist = queryForList( xxx.class, “queryAll” , param);
//pagelist就是分頁之後的結果
B、分頁並統計(每次執行2條語句,一條select count語句,一條分頁語句)適用於查詢分頁時數據發生變動,需要將實時的變動信息反映到分頁結果上
Page<?> page = PageHelper.startPage([pageNum],[pageSize],[iscount]);
List<?> pagelist = queryForList( xxx.class , “queryAll” , param);
long count = page.getTotal();
//也可以 List<?> pagelist = page.getList(); 獲取分頁後的結果集
3)、使用PageHelper查全部(不分頁)
PageHelper.startPage(1,0);
List<?> alllist = queryForList( xxx.class , “queryAll” , param);
4)、PageHelper的其他API
String orderBy = PageHelper.getOrderBy(); //獲取orderBy語句
Page<?> page = PageHelper.startPage(Object params);
Page<?> page = PageHelper.startPage(int pageNum, int pageSize);
Page<?> page = PageHelper.startPage(int pageNum, int pageSize, boolean isCount);
Page<?> page = PageHelper.startPage(pageNum, pageSize, orderBy);
Page<?> page = PageHelper.startPage(pageNum, pageSize, isCount, isReasonable); //isReasonable分頁合理化,null時用默認配置
Page<?> page = PageHelper.startPage(pageNum, pageSize, isCount, isReasonable, isPageSizeZero); //isPageSizeZero是否支持PageSize爲0,true且pageSize=0時返回全部結果,false時分頁,null時用默認配置
5)、默認值
//RowBounds參數offset作爲PageNum使用 - 默認不使用
private boolean offsetAsPageNum = false;
//RowBounds是否進行count查詢 - 默認不查詢
private boolean rowBoundsWithCount = false;
//當設置爲true的時候,如果pagesize設置爲0(或RowBounds的limit=0),就不執行分頁,返回全部結果
private boolean pageSizeZero = false;
//分頁合理化
private boolean reasonable = false;
//是否支持接口參數來傳遞分頁參數,默認false
private boolean supportMethodsArguments = false;

附:count(*)和count(0)和count(列)

  之前有人說過,在使用count的時候要用count(1)而不要用count(*),因爲使用count(*)的時候會對所有的列進行掃描,相比而言count(1)不用掃描所有列,所以count(1)要快一些。
  然而實際並非如此。
  1、通過實驗測試,也就說明count(*)和count(1)的執行效率是完全一樣的,根本不存在所謂的單列掃描和多列掃描的問題。mysql底層自動做了優化。
  2、大家以爲count(*)和count(列)哪個更快些?相信很多人會以爲,肯定count(列)更快些。而事實恰恰相反,count(*)只是返回表中行數,因此在處理count(*)的時候只需要找到屬於表的數據塊塊頭,然後計算一下行數就行了,而不用去讀取裏面數據列的數據。
  而對於count(col)就不一樣了,爲了去除col列中包含的NULL行,SQL Server必須讀取該col的每一行的值,然後確認下是否爲NULL,然後在進行計數。
  因此count(*)比count(col)在大數據量時要快很多。
  3、count(*)和count(1)時統計包括null的,而只有count(有空值的列)不包含null值。(結合上一條理解)。
  

還有一些和索引相關的性能因素可參考下面文章:
http://www.cnblogs.com/sueris/p/6650301.html

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