簡易版 DataTable.js 服務端分頁(Java)
引入 js 和 css 文件
可以直接到官網首頁,找到下面圖片的位置,點擊右邊的小箭頭按鈕,你會看到對應的 css 和 js 源碼,然後 ctrl+A 把源碼複製下來,自己新建個文件存放,再引入到 html 中就行。
實現原理
dataTable 實現服務端的分頁,主要是通過 AJAX 異步請求。先在 js 配置中開啓了服務端分頁的功能 “serverSide: true”,然後 dataTable 會傳指定參數給後臺去進行分頁操作,然後返回指定參數給前臺的 dataTable,dataTable 就會自動渲染表格數據並實現分頁。
dataTable 傳給服務端的三個必須分頁參數:
sEcho:dataTable 用於本身計算次數的,接收等會直接返回即可,不需要作處理。
iDisplayStart:表示從第幾行開始查詢,比如第一頁的話,標識從第 0 行開始查數據,與 mysql 的 limit 的第一個參數吻合,可直接使用,在 Java 代碼會介紹到。
iDisplayLength:表示查詢多少條,dataTable 默認最少是查詢 10 條。
服務端返回給 dataTable 的三個必須分頁參數:
draw:將 dataTable 傳過來的 sEcho 原封不動賦值給他就行。
recordsTotal:總數據量
recordsFiltered:總數據量
data:返回的數據列表
導入對應的文件
html 代碼
<table class="table-sort" >
<thead>
<tr class="text-c">
<th width="25"><input type="checkbox" name="" value="" id="allCheck"></th>
<th>標題</th>
<th>標題</th>
<th>標題</th>
<th>標題</th>
<th>標題</th>
<th>標題</th>
<th>標題</th>
<th>標題</th>
</tr>
</thead>
<tbody></tbody>
</table>
js 代碼
代碼比較清晰簡單,該有的註釋都有了。比較需要注意的是:fnServerParams
,這個參數。是用來設置自定義參數的,比如:你實現了搜索框,搜索框內輸入的值要傳到後臺,就得再 fnServerParams
裏面設置過去。
注意:
fnServerParams 參數是用來添加自定義傳給後臺的參數的。
比如:我們實現搜索功能的時候,也希望將搜索的信息列表能夠分頁展示出來,這時就需要將 “搜索條件” 通過 fnServerParams 來 push 進去 aoData 中,然後傳給後臺。
<script type="text/javascript">
$(function(){
$('.table-sort').dataTable({
bProcessing: true, //DataTables 載入數據時,是否顯示‘進度’提示
bAutoWidth: false, //自動寬度
bSort: false, //排序功能
bInfo: true, //頁腳信息,默認爲 true
bStateSave: true, //狀態保存
sPaginationType: "full_numbers", //分頁顯示樣式
serverSide: true, //啓用服務器分頁
sAjaxSource: "http://localhost:8080/user/list", //服務端請求數據接口
searching: false, //關閉 datatables 的搜索框
destroy: true, //解決重新渲染問題
iDisplayLength: 10, //每頁顯示數量
// 自定義參數
fnServerParams: function(aoData){
aoData.push(
{
name: "nickname",
value: "dongdong"
}
);
},
// post 方法提交
fnServerData: function(sSource,aoData,fnCallback){
$.ajax({
type: 'post',
url: sSource,
dataType: 'json',
data: aoData,
success: function (res) {
fnCallback(res);
}
});
},
aoColumns:[
// mDataProp:綁定數據屬性
// sDefaultContent:設置默認值
// sClass:添加 class 屬性,不懂的直接去掉
// sTtile:設置列標題
// sWidth:設置列寬度
// mRender:添加 html 代碼或者自定義的值
// 更多關於 aoColumns 的參數請查看下面的附件
{
mDataProp:"id",
mRender: function(mDataProp,type,row){
var html = '<td width="25" class="text-c"><input type="checkbox" value="' + mDataProp + '"></td> ';
return html;
}
},
// sTtile 設置的內容,會替換到 html thead 中的“標題”
{mDataProp:"id", sDefaultContent:"", sClass:"text-c", sTitle:"編號"},
{mDataProp:"city", sDefaultContent:"", sClass:"text-c", sTitle:"城市"},
{mDataProp:"avatarUrl", sDefaultContent:"", sClass:"text-c", sTitle:"頭像",sWidth:200},
{mDataProp:"jobIntention", sDefaultContent:"", sClass:"text-c", sTitle:"標籤"},
{mDataProp:"nickName",sDefaultContent:"", sClass:"text-c", sTitle:"微信暱稱"},
{mDataProp:"openid",sDefaultContent:"", sClass:"text-c", sTitle:"openID"},
{mDataProp:"province",sDefaultContent:"", sClass:"text-c", sTitle:"省份"},
{mDataProp:"state",sDefaultContent:"", sClass:"text-c", sTitle:"狀態"}
],
oLanguage: { //國際化配置
sProcessing : "正在獲取數據,請稍後...",
sLengthMenu : "顯示 _MENU_ 條",
sZeroRecords : "沒有您要搜索的內容",
sInfo : "從 _START_ 到 _END_ 條記錄 總記錄數爲 _TOTAL_ 條",
sInfoEmpty : "記錄數爲0",
sInfoFiltered : "(全部記錄數 _MAX_ 條)",
sInfoPostFix : "",
sSearch : "從當前數據中檢索: ",
sUrl : "",
oPaginate: {
sFirst : "首頁",
sPrevious : "上一頁",
sNext : "下一頁",
sLast : "尾頁"
}
}
});
});
</script>
Java 代碼
import com.google.gson.Gson;
@RequestMapping(value = "/user/list")
@ResponseBody
public String userList(Integer sEcho, Integer iDisplayStart, Integer iDisplayLength,
String nickname, ModelMap modelMap){
User query = new User();
List<User> list = userService.queryUser(query,PageParams.build(iDisplayStart,iDisplayLength));
Integer count = userService.getPageCount();
System.out.println(nickname);
modelMap.put("draw",sEcho);
modelMap.put("recordsTotal",5);
modelMap.put("recordsFiltered",50);
modelMap.put("data", list); //返回查詢的數據列表
Gosn gson = new Gson();
return gson.toJson(modelMap);
// return JsonUtils.Object2Json(sEcho,count,list);
//這是我自己對數據進行了封裝,封裝的類放在後面的附錄,如果看不懂可以不用,直接用上面 modelMap 這種形式返回也一樣
}
sEcho,iDisplayStart,iDisplayLength:前臺傳過來的分頁參數。
nickname:前臺傳過來的自定義參數
iDisplayStart 表示從第幾行開始查,iDisplayLength 表示查詢多少條,dataTable 傳過來的分頁參數,跟 mysql 的 limit 需要的分頁參數是完全吻合的。我們不需要進行數據處理,直接使用即可。如下面:
select *
from user
limit iDisplayStart,iDisplayLength
draw,recordsTotal,recordsFiltered,data:這幾個返回給前端的數據名稱不能寫錯,不然會對接不上。還有,dataTable 要求返回的是 json 格式的數據,這裏不採用原生的 JsonObject 寫,而是使用 Google 的一個工具類 Gson 來將數據轉成 Json 格式的數據。使用方法如下,注意:com.google.gson 包是要自己導入的。
select *
from user
limit iDisplayStart,iDisplayLength
後臺返回的 json 數據格式爲:
頁面效果圖:
另外一種寫法:
上面介紹的是用 fnServerData
進行異步獲取數據,我們也能直接使用 ajax 來開發。把下面的這段代碼刪掉。
// 自定義參數
fnServerParams: function(aoData){
aoData.push(
{
name: "nickname",
value: "dongdong"
}
);
},
// post 方法提交
fnServerData: function(sSource,aoData,fnCallback){
$.ajax({
type: 'post',
url: sSource,
dataType: 'json',
data: aoData,
success: function (res) {
fnCallback(res);
}
});
},
換成下面這段代碼:
ajax:{
url: "http://localhost:8080/user/list",
type: "POST",
contentType: "application/x-www-form-urlencoded",
async: false,
dataType: "json",
data: function(data){
data.name = "dongdong";
}
dataFilter: function(json){
return json;
}
}
兩種寫法的區別在於:直接使用 ajax ,dataTables 傳遞給後臺的參數不一樣。
fnServerData 傳給後臺的參數:sEcho、iDisplayStart、iDisplayLength
ajax 傳給後臺的參數:draw、start、length
後臺接收的參數如下:
@RequestMapping(value = "/user/list")
public String userList(Integer draw,Integer start, Integer length,String name){
System.out.println("draw:"+draw);
System.out.println("start:"+start);
System.out.println("length:"+length);
System.out.println("name:"+name);
}
附錄(個人筆記)
JsonUtils.java
import com.google.gson.Gson;
import com.zwd.house.common.page.PageData;
import java.util.List;
public class JsonUtils<T> {
private static Gson gson = new Gson();
public static <T> String Object2Json(Integer sEcho, Integer count, List<T> list) {
PageData<T> pageData = PageData.buildPage(sEcho,count,list);
return gson.toJson(pageData);
}
}
PageParams.java
public class PageParams {
private static final Integer PAGE_SIZE = 0;
private Integer offset; // 從第 offset+1 行開始檢索
private Integer limit; // 檢索條數
public static PageParams build(Integer offset, Integer limit){
if (offset == null){
offset = 0;
}
if (limit == null){
limit = PAGE_SIZE;
}
return new PageParams(offset, limit);
}
public PageParams(){
this(PAGE_SIZE, 1);
}
public PageParams(Integer offset, Integer limit){
this.offset = offset;
this.limit = limit;
}
// get and set
}
PageData.java
import java.util.List;
public class PageData<T> {
// 下面的用來封裝數據的參數名都不能變,需要與 dataTables 對應
private Integer draw; //前臺傳過來的 sEcho 原封返回
private Integer recordsTotal; //存放總條數
private Integer recordsFiltered; //存放總條數
private List<T> data;
public PageData(Integer draw,Integer recordsTotal,Integer recordsFiltered,List<T> data){
this.draw = draw;
this.recordsTotal = recordsTotal;
this.recordsFiltered = recordsFiltered;
this.data = data;
}
public static <T> PageData<T> buildPage(Integer draw, Integer total,List<T> data){
return new PageData<>(draw,total,total,data);
}
//get adn set
}