目標:html
使用jQuery Datatable構造數據列表,而且增長或者隱藏相應的列,已達到數據顯示要求。同時,jQuery Datatable強大的功能支持:排序,分頁,搜索等。前端
Query Datatable能良好支持數據徹底加載到本地後構建數據列表,排序、分頁、搜索等功能就會自帶,不須要咱們去關心,在此主要說明經過後臺動態的加載數據,已達到在大數據面前提升效率的效果。java
1. 經過後臺進行分頁web
2. 經過後臺進行排序ajax
3. 經過後臺進行搜索sql
具體使用方法:數組
1. 首先構建咱們須要的數據列表,以及頁面顯示錶格。app
<table id="datatable" width="100%" border="1"> <thead> <tr> <th>ID</th> <th>First Name</th> <th>Last Name</th> <th>Operation</th> </tr> <thead> </table>
表格創建很簡單,只需用將表格定義好id,以及表頭定義好。ide
2. 咱們能夠到jQuery Datatable官網上去下載一份jQuery和jQuery Datatable的js庫。https://datatables.net/examples/server_side/simple.html。大數據
3. 而後將這兩個文件引入到頁面文件中,注意jQuery的庫必定要在最前面,由於頁面加載的有順序,保證後面的擴展庫能使用到jQuery。同時,請下載最新的jQuery Datatable版本,由於它的寫法以及參數更加簡潔,功能更加多。【注:參數區別會在附錄寫明】
4. 編寫前端代碼。咱們是要使用Ajax對後臺進行請求,所以在配置datatable時,加上{"serverSide": true},已保證頁面在加載時就請求後臺,以及每次對datatable進行操做時也是請求後臺。【附:若是想加上一點加載效果,能夠增長{"processing": true}】。
配置請求後臺URL:{"ajax": "load"}
5. 配置數據返回對應具體的列。在Datatable中,屬性columns用來配置具體列的屬性,包括對應的數據列名,是否支持搜索,是否顯示,是否支持排序等。根據上述頁面配置咱們具體的列。以下:
$(document).ready(function() { $("#datatable").dataTable({ "processing": true, "serverSide": true, "ajax" : "load", "columns": [ {"data": "id", "bSortable": false}, {"data": "firstName"}, {"data": "lastName"} ] }); });
第一列ID,設置爲不容許排序。也能夠增長不顯示:{"visible": false}
6. 此時對於後臺而言,返回的數據必定要按照必定規範。以下:
{ "draw": 2, "recordsTotal": 11, "recordsFiltered": 11, "data": [ { "id": 1, "firstName": "Troy", "lastName": "Young" }, { "id": 2, "firstName": "Alice", "lastName": "LL" }, { "id": 3, "firstName": "Larry", "lastName": "Bird" } // ...... ] }
參數解釋:
draw:表示請求次數
recordsTotal:總記錄數
recordsFiltered:過濾後的總記錄數
data:具體的數據對象數組
7. 最後一列Operation,咱們沒有任何數據,用來放咱們的通用操做列,如修改連接。 Datatable提供了自定義列columnDefs屬性,他的值爲數組對象,具體代碼以下:
$(document).ready(function() { $("#datatable").dataTable({ "processing": true, "serverSide": true, "ajax" : "load", "columns": [ {"data": "id", "bSortable": false}, {"data": "firstName"}, {"data": "lastName"} ], "columnDefs": [ { "targets": [3], "data": "id", "render": function(data, type, full) { return "<a href='/update?id=" + data + "'>Update</a>"; } } ] }); });
targets:表示具體須要操做的目標列,下標從0開始
data: 表示咱們須要的某一列數據對應的屬性名
render:返回須要顯示的內容。在此咱們能夠修改列中樣式,增長具體內容
屬性列表:data, 以前屬性定義中對應的屬性值
type, 未知
full, 所有數據值能夠經過屬性列名獲取
具體效果圖以下:
8. 咱們再來看具體如何進行搜索、排序、分頁。因爲只是爲了作demo,所以使用最簡單的JDBC+Servlet的方式來實現。
首先咱們來看,datatable給咱們在作請求是傳遞過來的參數:
=============== Request Paramerters ================ draw: 1 columns[0][data]: id columns[0][name]: columns[0][searchable]: true columns[0][orderable]: true columns[0][search][value]: columns[0][search][regex]: false columns[1][data]: firstName columns[1][name]: columns[1][searchable]: true columns[1][orderable]: true columns[1][search][value]: columns[1][search][regex]: false columns[2][data]: lastName columns[2][name]: columns[2][searchable]: true columns[2][orderable]: true columns[2][search][value]: columns[2][search][regex]: false order[0][column]: 0 order[0][dir]: asc start: 0 length: 10 search[value]: search[regex]: false _: 1399345292266 =============== Request Paramerters ================
其中有用的數據就是start, length, order[0][column], order[0][dir], search[value]。具體參數意思:
start: 其實記錄位置
length:頁面顯示數量
order[0][column]: 由於是二維的表格,所以只有一維須要排序,因此order的下標未0. 該屬性表示第幾列須要排序。
order[0][dir]: 排序方式ASC | DESC
search[value]: search輸入框中的值
9. 這幾個屬性對後臺進行排序、搜索、分頁頗有用。【注:由於是二維表,而且只是對一列進行操做,天然就是一維的,因此order下標始終爲1。之後操做二維表有待研究。】
首先來看包含這幾個功能的DAO層代碼:
/** * This method includes the search, sort, pagination * @param pageSize * @param startRecord * @param sortColumn * @param sortDir * @param searchValue * @return */ public List<Data> loadDataList(int pageSize, int startRecord, String sortColumn, String sortDir, String searchValue) { List<Data> results = new ArrayList<Data>(); StringBuffer sql = new StringBuffer("select * from data "); // for search String[] columnsName = { "id", "firstName", "lastName" }; boolean searchAble = false; if(searchValue != null && !"".equals(searchValue)) { sql.append("where "); searchAble = true; } if(searchAble) { StringBuffer temp = new StringBuffer(); for (String column : columnsName) { temp.append( column+ " like '%" + searchValue + "%' or "); } sql.append(temp.substring(0, temp.length() - 3)); } // for order sql.append(" order by " + sortColumn + " " + sortDir + " "); // for pagination sql.append(" limit ?,? "); System.out.println(sql.toString()); try { stmt = conn.prepareStatement(sql.toString()); stmt.setInt(1, startRecord); stmt.setInt(2, startRecord + pageSize); ResultSet rs = stmt.executeQuery(); while(rs.next()) { Data data = new Data(); data.setId(rs.getInt(1)); data.setFirstName(rs.getString(2)); data.setLastName(rs.getString(3)); results.add(data); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return results; }
DAO層中,統計代碼相似,只用把分頁和排序的SQL拼接去掉便可。
咱們須要將咱們的數據轉換成JSON返回給前端,而且還要顯示總記錄數,過濾後總記錄數。所以咱們須要一個統一的類來將這些數據進行封裝。因爲在一個系統中不僅一個對象須要展現到前端,所以統一的作一個爲datatable封裝類。
package com.web.vo; import java.util.List; /** * This VO used to generate the JSON data for data table, so please ensure that the attribute name is correct. * If you want to define the fields name by yourself, please visit: https://datatables.net * @author troyyang * * @param <T> */ public class DataVO<T> { private int draw; // Client request times private int recordsTotal; // Total records number without conditions private int recordsFiltered; // Total records number with conditions private List<T> data; // The data we should display on the page // getter and setter method }
萬事具有,只欠先後交互代碼。此處使用最簡單的servlet。
// For pagination int pageSize = 10; int startRecord = 0; String size = request.getParameter("length"); if (!"".equals(size) && size != null) { pageSize = Integer.parseInt(size); } String currentRecord = request.getParameter("start"); if (!"".equals(currentRecord) && currentRecord != null) { startRecord = Integer.parseInt(currentRecord); } // For sortable String sortOrder = request.getParameter("order[0][column]"); String sortDir = request.getParameter("order[0][dir]"); System.out.println("sortOrder: " + sortOrder); System.out.println("sortDir: " + sortDir); // For search String searchValue = request.getParameter("search[value]"); int count = 0; List<Data> results = new ArrayList<Data>(); count = dao.count(); results = dao.loadDataList(pageSize, startRecord, columnsName[Integer.parseInt(sortOrder)], sortDir, searchValue); DataVO<Data> result = new DataVO<Data>(); result.setDraw(Integer.parseInt(request.getParameter("draw") == null ? "0" : request.getParameter("draw")) + 1); result.setData(results); result.setRecordsTotal(count); result.setRecordsFiltered(count); Gson gson = new Gson(); String output = gson.toJson(result); System.out.println("Output JSON: \n" + output); PrintWriter out = response.getWriter(); out.write(output); out.flush(); out.close();
附錄:
使用jQuery Datatable1.10以前的版本,必須使用sAjaxSource進行請求,可是請求數據和如今版本的請求數據不一樣,以下:
=============== Request Paramerters ================ sEcho: 1 iColumns: 4 sColumns: ,,, iDisplayStart: 0 iDisplayLength: 10 mDataProp_0: id sSearch_0: bRegex_0: false bSearchable_0: true bSortable_0: false mDataProp_1: firstName sSearch_1: bRegex_1: false bSearchable_1: true bSortable_1: true mDataProp_2: lastName sSearch_2: bRegex_2: false bSearchable_2: true bSortable_2: true mDataProp_3: id sSearch_3: bRegex_3: false bSearchable_3: true bSortable_3: true sSearch: bRegex: false iSortCol_0: 0 sSortDir_0: asc iSortingCols: 1 _: 1399515247114 =============== Request Paramerters ================
更過特性,持續更新......