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是告訴攔截器說我要開始分頁了。分頁引數是這兩個。
這裡沒有接收返回值,會不會覺得奇怪?實際上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();
}