1. 程式人生 > >mybatis框架---分頁外掛PageHelper的使用方法

mybatis框架---分頁外掛PageHelper的使用方法

以前自己寫分頁時,需要自己寫sql語句,並且進行分頁判斷之後才可以實現分頁

目前Mybatis提供了分頁外掛,使用起來非常簡便,適合於各類資料庫分頁,只需要在配置檔案中配置資料庫名即可,那麼mybatis的外掛作用在哪一環節呢?它主要作用在Executor執行器與mappedeStatement之間,也就是說mybatis可以在外掛中獲得要執行的sql語句,在sql語句中新增limit語句,然後再去對sql進行封裝,從而可以實現分頁處理

一:首先需要引入PageHelper的jar包。

如果使用了maven,那麼只要在pom.xml中引入該外掛即可,引入如下:

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

二:在mybatis的全域性配置檔案SqlMapConfig.xml中配置該外掛spring-mybatis.xml是這樣配置:(資料來源,分頁攔截器)

順便說說資料來源的配置:

對於單資料來源:

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/pem"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>


多資料來源:

<!--動態資料來源配置 -->
	<bean class="com.ixinnuo.credit.common.datasource.DynamicDataSource" id="dataSource">
		<property name="targetDataSources">  //spring-jdbc-3.2.13.RELEASE.jar 依賴於spring對jdbc的支援
			<map key-type="java.lang.String">
				<entry value-ref="c_dataSource" key="c_ds"></entry>
				<entry value-ref="r_dataSource" key="r_ds"></entry>
				<entry value-ref="impalaDataSource" key="impala_ds"></entry>
				<entry value-ref="sjcjDataSource" key="sjcj_ds"></entry>
			</map>
		</property>
		<property name="defaultTargetDataSource" ref="c_dataSource">
		</property>
	</bean>


<!--配置資料庫會話工廠-->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource"></property>
		<property name="mapperLocations">  //定義mapper檔案位置
			<array>
				<value>classpath*:com/ixinnuo/credit/**/mapping/**/*.xml</value>
			</array>
		</property>
		<property name="typeAliasesPackage" value="com.ixinnuo.credit" />  //預設包的位置
		<property name="plugins">
			<array>
				<!-- 效能攔截器,用於輸出每條 SQL 語句及其執行時間 -->
				<bean class="com.ixinnuo.credit.common.util.interceptor.PerformanceInterceptor"></bean>
				<!-- MyBatis分頁外掛 -->
				<bean class="com.github.pagehelper.PageHelper">
					<property name="properties">
						<value>
							dialect=mysql或者為oracle
							reasonable=true
          				</value>
					</property>
				</bean>
				<!-- MyBatis通用Mapper 攔截器 -->   
				<bean class="tk.mybatis.mapper.mapperhelper.MapperInterceptor">
			        <property name="properties">
			          <value>
			          	mappers=tk.mybatis.mapper.common.Mapper
			          </value>
			        </property>
			    </bean>
			</array>
		</property>
	</bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

我是在spring裡配置的,還可以在mybatis-config.xml裡配置,有興趣的話可以百度下。

三:在執行sql前新增外掛,完成分頁功能  (在查詢的sql語句執行之前,新增一行程式碼PageHelper.startPage(1, 10);

   /**
     * 開始分頁  其中前兩個引數是必須給的。
     *
     * @param pageNum      頁碼
     * @param pageSize     每頁顯示數量
     * @param count        是否進行count查詢
     * @param reasonable   分頁合理化,null時用預設配置
     * @param pageSizeZero true且pageSize=0時返回全部結果,false時分頁,null時用預設配置
     */
    public static Page startPage(int pageNum, int pageSize, boolean count, Boolean reasonable, Boolean pageSizeZero) {
        Page page = new Page(pageNum, pageSize, count);
        page.setReasonable(reasonable);
        page.setPageSizeZero(pageSizeZero);
        SqlUtil.setLocalPage(page);
        return page;
    }

   第一個引數表示第幾頁,第二個引數表示每頁顯示的記錄數。這樣在執行sql後就會將記錄按照語句中設定的那樣進行分頁。

     如果需要獲取總記錄數的話,需要PageInfo類的物件,這個物件可以獲取總記錄數、

下面看下後臺實現程式碼,最重要的只要兩句話

即在資料庫查詢之前告訴PageHelper開時分頁:PageHelper.startPage(1, 10);)以及查詢完成得到totalPage返回

mapResult.put("totalPage", ((Page)resultList).getPages());,下面為一個完整方法程式碼:

@RequestMapping("getAllDetail")
public void getAllDetail(HttpServletRequest req,HttpServletResponse resp,Integer pageNum){
try {
ObjectMapper mapper = new ObjectMapper();
Map<String,Object> mapResult = new HashMap<String,Object>();

Integer pageSize = 8;
if (pageNum==null) {
pageNum = 1;
}

PageHelper.startPage(pageNum, pageSize,true);

List<DetailRecord> resultList = recordService.getDetail();
mapResult.put("totalPage", ((Page)resultList).getPages());

int count =  recordService.getCount();
mapResult.put("TOTAL_COUNT",count);
mapResult.put("result", "success");
mapResult.put("detail", resultList);

                       mapper.writeValue(resp.getWriter(), mapResult);

         }

前臺實現程式碼(自動顯示分頁樣式):

HtML部分

                     <div class="box-body">
<table id="datatable1" cellpadding="0" cellspacing="0" border="0" class="datatable table table-striped table-bordered table-hover">
<thead>
<tr style="height:35px;border-bottom:1px solid #555;">
 <th>序號</th>
<th>企業名稱</th>
<th>納稅人識別號</th>
<th>查詢時間</th>
<th>報告編號</th>
<th>歷史報告</th>
</tr>
</thead>
<tbody id="lsmx-table">

//可以直接寫<tr>標籤或者在<script>標籤編寫handlebars模板動態渲染資料

</tbody>

</table>
<div class="pull-right"><a href="<%=basePath %>account/getDetailExcel">匯出歷史查詢明細</a></div>
<!-- 分頁 -->
<input type="hidden" id="pageNum" name="pageNum" />
<div class="text-center">
<div id="pagination" class="pagination" ></div>
</div>
<!-- 分頁結束 -->

JS部分(整個完整的js頁面)

(function($) {
//其中goPageNum初始傳入1,隨後會動態根據頁數的跳轉而變化,所以ajax中需要將該引數提交至後臺。

window.lsmx = $.fn.qyzhkb = {
currentPage: 1,

recordDetail: function(goPageNum) {
$.ajax({
url: basePath + "account/getAllDetail?" + new Date().getTime(),
data:{
pageNum:goPageNum
},
dataType: "json",
type: "post",
success:function(data){
var result = data.result;
if(result === "success") {
var detail=data.detail
console.log(data.detail);
$("#total_count").text(data.TOTAL_COUNT);

var script=$("#template-lsmx").html();
var template=Handlebars.compile(script);

var result=template({items:detail});
$("#lsmx-table").html(result);
lsmx.bindDownload();     //資料渲染完成後觸發bindDownload()函式
//分頁開始
var totalPage = data.totalPage;
 //分頁顯示
if (totalPage === 0) {
totalPage = 1;
}

if (0 != totalPage) {
if (parseInt(totalPage) > 0) {
$("#
pagination").unbind();
$("#
pagination").bootpag({
total: parseInt(totalPage),
page: goPageNum,
maxVisible: 10,
leaps: true
}).bind("page", function(event, goPageNum) {
// 記錄當前頁
lsmx.currentPage = goPageNum;
lsmx.recordDetail(goPageNum);
});
}
}
   //分頁結束


}
},
error:function(data){
console.log(data);
}
});
},

bindDownload:function(){
$(".download").on("click", function (){
var qymc = $(this).attr("title");
var idNum = $(this).attr("idNum");

$.ajax({ 
url:basePath+'account/downloadLog?'+ new Date().getTime(), 
data:{
qymc:qymc,
id:idNum,

},
type:'post',
success:function(data){
console.log(data);
console.log(data.address);
var jsonObj = JSON.parse( data ); 
var result = jsonObj.result;
var address = jsonObj.address;
console.log(result);
console.log(address);
if(result === "success") {
//$("<a style='disploy:none;' id='downfile_a' download href='"+address+"' />").click();
window.open(address); 
//window.location.href = address;

}else{
alert("沒有歷史報告可以下載。");
}
},
error:function(data){
console.log(data);
}

});
 });
}

}
})(jQuery);


/*頁面初始化的時候呼叫方法*/
$(document).ready(function($){
lsmx.recordDetail(1);

});

Mybatis分頁外掛的優點:

現在來講講用了PageHelper之後的好處: 
那就是查詢語句可以不用limit,但是就一點好處嗎?自然不是。請接著往下看。

  • 1
  • 1
  • startPage是告訴攔截器說我要開始分頁了。分頁引數是這兩個。
  •     startPage是告訴攔截器說我要開始分頁了。分頁引數是這兩個。
後呼叫原來的Mybatis程式碼:

這裡沒有接收返回值,會不會覺得奇怪?實際上PageHelper已經自動接收了返回值。通過下面的程式碼可以取出返回值:

?
1 PageHelper.endPage();

同時endPage告訴攔截器說我結束分頁了,不需要你了。

注意在你需要進行分頁的Mybatis方法前呼叫PageHelper.startPage靜態方法即可,緊跟在這個方法後的第一個Mybatis查詢方法會被進行分頁。


PageInfo這個類是外掛裡的類,這個類裡面的屬性還是值得看一看:

    //當前頁
    private int pageNum;
    //每頁的數量
    private int pageSize;
    //當前頁的數量
    private int size;
    //排序
    private String orderBy;

    //由於startRow和endRow不常用,這裡說個具體的用法
    //可以在頁面中"顯示startRow到endRow 共size條資料"

    //當前頁面第一個元素在資料庫中的行號
    private int startRow;
    //當前頁面最後一個元素在資料庫中的行號
    private int endRow;
    //總記錄數
    private long total;
    //總頁數
    private int pages;
    //結果集
    private List<T> list;

    //第一頁
    private int firstPage;
    //前一頁
    private int prePage;
    //下一頁
    private int nextPage;
    //最後一頁
    private int lastPage;

    //是否為第一頁
    private boolean isFirstPage = false;
    //是否為最後一頁
    private boolean isLastPage = false;
    //是否有前一頁
    private boolean hasPreviousPage = false;
    //是否有下一頁
    private boolean hasNextPage = false;
    //導航頁碼數
    private int navigatePages;
    //所有導航頁號
    private int[] navigatepageNums;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

使用PageInfo這個類,你需要將查詢出來的list放進去:

PageInfo<CityList> p=new PageInfo<CityList>(list);
  • 1
  • 1

然後mv.addObject("page", p); 
這樣在頁面中就可以通過${page.nextPage}翻到下一頁, 
${page.prePage}翻到上一頁,  

2). PageHelper.startPage靜態方法呼叫

例一:
SqlSession sqlSession = MybatisHelper.getSqlSession();
CountryMapper countryMapper = sqlSession.getMapper(CountryMapper.class);
try {
    //獲取第1頁,10條內容,預設查詢總數count
    PageHelper.startPage(1, 10);

    //緊跟著的第一個select方法會被分頁List<Country> list = countryMapper.selectIf(1);

 //後面的不會被分頁,除非再次呼叫PageHelper.startPageList<Country> list2 = countryMapper.selectIf(null);
    //list1
    assertEquals(2, list.get(0).getId());
    assertEquals(10, list.size());
    //分頁時,實際返回的結果list型別是Page<E>,如果想取出分頁資訊,需要強制轉換為Page<E>,
    //或者使用PageInfo類(下面的例子有介紹)assertEquals(182, ((Page) list).getTotal());
    //list2
    assertEquals(1, list2.get(0).getId());
    assertEquals(182, list2.size());
} finally {
    sqlSession.close();
}