使用 jQuery Datatable 实现动态数据加载
本文将介绍如何使用 jQuery Datatable 构造数据列表,并通过后台动态加载数据以提高效率。同时,我们还将学习如何实现排序、分页和搜索等功能。
## 主要步骤
1. 通过后台进行分页
2. 通过后台进行排序
3. 通过后台进行搜索
具体使用方法如下:
### 第1步:构建数据列表及页面显示表格
首先,我们需要构建一个数据列表以及一个用于显示数据的 HTML 表格。以下是一个简单的示例:
```html
ID | First Name | Last Name | Operation |
---|
```
表格的构建非常简单,只需定义好表格的 `id` 以及表头即可。
### 第2步:下载 jQuery 和 jQuery Datatable 的 js库
接下来,我们需要下载 jQuery 和 jQuery Datatable 的相关文件。可以从以下链接下载:https://datatables.net/examples/server_side/simple.html。请确保下载最新的 jQuery Datatable 版本,因为它的写法以及参数更加简洁,功能更加多。【注:参数区别会在附录写明】
### 第3步:引入文件到页面中
将下载好的 jQuery 和 jQuery Datatable 文件引入到页面文件中。注意,jQuery 的库一定要在最前面,因为页面加载有顺序,保证后面的扩展库能使用到 jQuery。同时,请按照官方文档的要求引入相应的 CSS 和 JavaScript 文件。
. 编写前端代码。我们需要使用Ajax对后台进行请求,因此在配置datatable时,加上`{ "serverSide": true }`,以确保页面在加载时就请求后台数据,以及每次对datatable进行操作时也是请求后台数据。如果想要添加一些加载效果,可以增加`{ "processing": true }`。
配置请求后台URL:{ "ajax": "load" }
5. 配置数据返回对应的具体列。在Datatable中,属性columns用来配置具体列的属性,包括对应的数据列名、是否支持搜索、是否显示、是否支持排序等。根据上述页面配置,我们可以设置具体的列如下:
```javascript
$(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"
},
{
"columnDefs": [
{
"targets": [0],
"render": function (data, type, row) {
var editBtn = '修改';
return editBtn;
}
}
]
}
]
}
以下是重构后的代码:
```javascript
$(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 "Update";
}
}
]
});
});
```
具体效果图如下:
8. 我们再来看具体如何进行搜索、排序、分页。由于只是为了做 demo ,因此使用最简单的 JDBC+Servlet 的方式来实现。首先我们来看, datatable 给我们在做请求是传递过来的参数:
请求参数如下:
1. draw: 表格的列数,这里为1
2. columns[0][data]: 第一列数据的字段名,这里是 id
3. columns[0][name]: 第一列数据的显示名称,这里是 id
4. columns[0][searchable]: 是否允许对该列进行搜索,这里为 true
5. columns[0][orderable]: 是否允许对该列进行排序,这里为 true
6. columns[0][search][value]: 搜索框中的初始值,这里是 id
7. columns[0][search][regex]: 是否启用正则表达式搜索,这里为 false
8. columns[1][data]: 第二列数据的字段名,这里是 firstName
9. columns[1][name]: 第二列数据的显示名称,这里是 first name
10. columns[1][searchable]: 是否允许对该列进行搜索,这里为 true
11. columns[1][orderable]: 是否允许对该列进行排序,这里为 true
12. columns[1][search][value]: 搜索框中的初始值,这里是 first name
13. columns[1][search][regex]: 是否启用正则表达式搜索,这里为 false
14. columns[2][data]: 第三列数据的字段名,这里是 lastName
15. columns[2][name]: 第三列数据的显示名称,这里是 last name
16. columns[2][searchable]: 是否允许对该列进行搜索,这里为 true
17. columns[2][orderable]: 是否允许对该列进行排序,这里为 true
18. columns[2][search][value]: 搜索框中的初始值,这里是 last name
19. order[0][column]: 需要排序的列的索引,这里为 0(表示第一列)
20. order[0][dir]: 排序方式,ASC | DESC(升序或降序)
21. start: 记录的起始位置,这里为 0
22. length: 每页显示的数据条数,这里为 10
23. search[value]: search 输入框中的值,这里是空字符串("")
以下是根据提供的内容重构的 DAO 层代码,包含排序、搜索和分页功能:
```java
public interface UserDao {
/**
* 根据用户名查询用户信息
* @param username 用户名
* @return 用户信息列表
*/
List
/**
* 根据邮箱查询用户信息
* @param email 邮箱地址
* @return 用户信息列表
*/
List
/**
* 根据手机号查询用户信息
* @param phoneNumber 手机号
* @return 用户信息列表
*/
List
}
```
在上述代码中,我们定义了一个名为 `UserDao` 的接口,该接口包含了三个方法:`findByUsername`、`findByEmail` 和 `findByPhoneNumber`,分别用于根据用户名、邮箱和手机号查询用户信息。这些方法返回一个包含用户信息的列表。
```java
/** * This method includes the search, sort, pagination
* @param pageSize 页面大小
* @param startRecord 起始记录
* @param sortColumn 排序列
* @param sortDir 排序方向(升序或降序)
* @param searchValue 搜索值
* @return 返回结果列表
*/
public List loadDataList(int pageSize, int startRecord, String sortColumn, String sortDir, String searchValue) {
List results = new ArrayList();
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;
}
```
首先,我们需要创建一个统一的类来封装数据和分页信息。这个类将用于生成 JSON 数据并将其返回给前端。我们可以创建一个名为 `DataVO` 的泛型类,包含以下属性:`draw`(客户端请求次数)、`recordsTotal`(不带条件过滤的总记录数)、`recordsFiltered`(带条件过滤后的总记录数)和 `data`(需要在页面上显示的数据)。此外,我们还需要为这些属性提供 getter 和 setter 方法。
```java
package com.web.vo;
import java.util.List;
public class DataVO
private int draw; // Client request times
private int recordsTotal; // Total records number without conditions
private int recordsFiltered; // Total records number with conditions
private List
// Getter and setter methods
}
```
接下来,我们需要在后端处理数据的分页和排序。这部分代码与之前的代码类似,只需去掉拼接 SQL 以实现分页和排序功能。在处理完数据后,我们可以将其封装到 `DataVO` 类中,并设置相应的属性值。
最后,我们需要实现前后端交互。在这里,我们可以使用最简单的 Servlet 作为示例。Servlet 将从数据库中获取数据,填充到 `DataVO` 对象中,然后将其转换为 JSON 格式并返回给前端。
```java
@WebServlet("/data")
public class DataServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 从数据库中获取数据,并将其封装到 DataVO 对象中
DataVO
// ... populate dataVO with data from database ...
// 将 dataVO 转换为 JSON 格式并返回给前端
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(new Gson().toJson(dataVO));
}
}
```
在这个示例中,`YourObject` 是你需要展示在前端的数据对象类型。你需要根据实际情况替换为相应的类型。
以下是重构后的代码:
```java
// 分页参数
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);
}
// 可排序参数
String sortOrder = request.getParameter("order[0][column]");
String sortDir = request.getParameter("order[0][dir]");
System.out.println("sortOrder: " + sortOrder);
System.out.println("sortDir: " + sortDir);
// 搜索参数
String searchValue = request.getParameter("search[value]");
int count = 0;
List results = new ArrayList<>();
count = dao.count();
results = dao.loadDataList(pageSize, startRecord, columnsName[Integer.parseInt(sortOrder)], sortDir, searchValue);
DataVO result = new DataVO<>();
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:
" + output);
PrintWriter out = response.getWriter();
out.write(output);
out.flush();
out.close();
```
在较早的 jQuery Datatable 1.10 版本中,必须使用 `sAjaxSource` 进行请求。与当前版本不同,请求数据的格式如下:
```scss
=============== 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 ================
```
随着新特性的添加和不断更新,请关注后续版本的使用说明。