版权声明:本文为HCG原创文章,未经博主允许不得转载。请联系[email protected] https://blog.csdn.net/qq_39455116/article/details/84329071
前后端JSP系统用datatables前后端分页的实现
1. 引入Maven
com.github.pagehelper pagehelper 4.1.62. 给springMVC添加pageHelper的配置
在mybatis-config.xml中添加如下配置
其实就是加了一个plugins配置还有扫描包的配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- 4.0.0以后版本可以不设置该参数 -->
<property name="dialect" value="mysql"/>
<!-- 该参数默认为false -->
<!-- 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 -->
<!-- 和startPage中的pageNum效果一样-->
<property name="offsetAsPageNum" value="true"/>
<!-- 该参数默认为false -->
<!-- 设置为true时,使用RowBounds分页会进行count查询 -->
<property name="rowBoundsWithCount" value="true"/>
<!-- 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 -->
<!-- (相当于没有执行分页查询,但是返回结果仍然是Page类型)-->
<property name="pageSizeZero" value="true"/>
<!-- 3.3.0版本可用 - 分页参数合理化,默认false禁用 -->
<!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 -->
<!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->
<property name="reasonable" value="true"/>
<!-- 3.5.0版本可用 - 为了支持startPage(Object params)方法 -->
<!-- 增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 -->
<!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,orderBy,不配置映射的用默认值 -->
<!-- 不理解该含义的前提下,不要随便复制该配置 -->
<!-- <property name="params" value="pageNum=start;pageSize=limit;"/> -->
<!-- 支持通过Mapper接口参数来传递分页参数 -->
<property name="supportMethodsArguments" value="true"/>
<!-- always总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page -->
<property name="returnPageInfo" value="check"/>
</plugin>
</plugins>
<mappers>
<!-- 导入包下面的所有文件mapper.xml -->
<package name="com.ybl"/>
</mappers>
</configuration>
3. 最后只需要在controller或者service里面添加两句话就可以了
原本的可能是:
@RequestMapping(value= "/json" , method = RequestMethod.POST)
@ResponseBody
public List<User> userJson( ) {
//这个可能有上万条数据
List<User> list= userService.listAll();
return list;
}
加上之后是:
@RequestMapping(value= "/json" , method = RequestMethod.POST)
@ResponseBody
public PageInfo<User> userJson( ) {
PageHelper.startPage(req.getStart() / 10 + 1, 10);
//这个可能有上万条数据
List<User> list= userService.listAll();
PageInfo<User> pageInfo = new PageInfo<User>(list);
return pageInfo;
}
然后就完成了分页查询数据的功能,但是仅仅完成了分页,并没有整合datatable
如果要整合datatable必然要传输给datatable它想要的数据,所以后台要封装成datatable想要的格式
而且要接收datatable传给后端的数据,所以要接收参数,下面我们看一下前后端的数据参数
但是我们查看datatable的文档如下
https://datatables.net/examples/server_side/simple.html
它需要后台接收参数,发现它传送给后端的参数有以下几个重要数据
draw 、 start、 length 、 search
draw 这个不用理解,就是绘制表格,当然这个数据查询的时候你会发现
它传给后台是多少,后台要返回多少
start 开始的数据,不是页码,而是数据个数,但是后台要的是页面,那你需要找到所有的数据,除以每页
length 每页的长度
serch 查询的内容
而datatable前端需要的数据,也有几个参数,分别是
draw 、 recordsTotal、recordsFiltered 、error、 data
recordsTotal 总共多少,一般是数据库有多少,就写多少
recordsFiltered 过滤后的数据,我这里和recordsTotal是一样的
error 可以选填
data 传给datatable的数据,当然名字可以换,换名字之后,要指定数据源
比如换成 dataJson 那么要添加一个,下面有详细使用
"dataSrc": "dataJson",
或者
"dataSrc": "dataMap.list",
所以我们要理解上面两排参数的意义,然后给后台封装对象
针对入参和出参,我封装了两个对象
public class RcDetailResponse {
返回对象
private int draw;
private int recordsTotal;
private int recordsFiltered;
private String error;
private Map<String,Object> dataMap = new HashMap<>();
getter and setter ....
}
public class RcDetailRequest {
//接收参数对象
private int draw;
private int start;
private int length;
private String search;
getter and setter ....
}
重新定义controller
@RequestMapping(value = "/json", method = RequestMethod.POST)
@ResponseBody
public RcDetailResponse queryRcDetail(@RequestBody RcDetailRequest req) {
//根据当前的数量,算出来要查询的页码,第一页开始从0,第二页是10,每页数量10,所以页码要+1
PageHelper.startPage(req.getStart() / 10 + 1, 10);
List<User> list = accountService.listFriendAll();
PageInfo<User> pageInfo = new PageInfo<User>(list);
HashMap<String, Object> map = new HashMap<>();
map.put("list", list);
RcDetailResponse res = new RcDetailResponse();
//前端传过来的draw是多少,就返回多少
res.setDraw(req.getDraw());
//过滤后的数量
res.setRecordsFiltered(300);
//总共的数量
res.setRecordsTotal(300);
res.setDataMap(map);
return res;
}
B 但是如何利用datatable实现AJAX分页呢
datatable的常用都是将所有数据塞进去,这里我们用Ajax点击当前页面实现分页
1. 准备JSP
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:set var="baseResourcePath" scope="request" value="${pageContext.request.contextPath}/resource"/>
<c:set var="baseAppPath" scope="request" value="${pageContext.request.contextPath}"/>
<body>
<link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet">
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tfoot>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</tfoot>
</table>
</body>
</html>
<%--如果你本地有这两个JS用这两个,没有直接用链接--%>
<%--<script src="https://code.jquery.com/jquery-3.3.1.js"></script>--%>
<script src="${baseResourcePath}/js/lib/jquery.min.js"></script>
<script src="${baseResourcePath}/js/lib/jquery.dataTables.min.js"></script>
<%--<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>--%>
<script>
var table = $('#example').DataTable({
responsive: true, //开启响应式
serverSide: true,//开启服务器模式
ajax: {
url: '/td/ad/orderitem/account/json',
data: function (d) {
var str = {
"draw": d.draw,
"start": d.start,
"length": d.length,
"search": d.search.value
};
return JSON.stringify(str);
},
//指定下面用到的数据是JSON里面的哪个
"dataSrc": "data",
type: "POST",
contentType: 'application/json; charset=UTF-8'
},
"columns": [
{
//在列里面放的数据
"data": "id",
//列的宽度
"width": "50px",
//列的名称
"title": "id"
}, {
"data": "faceUrl",
"title": "头像",
"width": "80px",
//这个函数可以自定义返回结果
"render": function (data, type, row, meta) {
return '<img style="width:56px;" src=' + data + ' >';
}
},
{
"data": "briedIntroduction",
"width": "200px",
"title": "a",
//这个函数主要用来换行
render: function(data, type, row, meta) {
//然后是 内容太多用。。。。表示、内容不换行,鼠标移上去显示详情
return '<div id="a" style="white-space: normal;text-overflow:
ellipsis;overflow: hidden" '+
'title="简介">'+data +'</div>';
}},
{
"data": null,
"width": "350px",
"title": "b",
//这个函数是一列显示多列的数据
render: function(data, type, row, meta) {
return '<label>' + row.id + '</label> <label>' + row.cnName + '</label>';
}}
]
})
</script>
注意我的JSP里面已经有了datatable的配置,如果对这些配置不清楚的可以看一下这个
https://datatables.net/examples/server_side/simple.html
其实后端已经分好页了,现在做的就是把数据按照指定的格式传给前端,那我们看一下前端需要的数据格式是什么样子的,继续看下面的链接需要的数据
https://datatables.net/examples/server_side/simple.html
{
"draw": 9,
"recordsTotal": 300,
"recordsFiltered": 300,
"error": null,
"dataMap": {
"list": [
{
"id": 1,
"enId": null,
"cnName": "一加",
"faceUrl": "url",
"briedIntroduction": "很长很长的简介
............................................."
},
{
"id": 2,
"enId": null,
"cnName": "小米",
"faceUrl": "url",
"briedIntroduction": "很长很长的简介
............................................."
}
]
}
}
其实数据的格式都是可以换的,data里面可以是数组,也可以是对象,还可以是对象数组,不管怎么样,都是可以的
但是大概就是上面所示的。其实就三个重要,draw,recordsTotal ,recordsFiltered
5.1 下面讨论一下datatable的取数据,比如要取json中data对象数组里面的id
先指定数据源
"dataSrc": "data",
然后在columns中指定当前列的数据是JSON.data里面的哪个,这里我们用id
"columns": [
{
//在列里面放的数据
"data": "id",
//列的宽度
"width": "50px",
//列的名称
"title": "id"
}
]
5.2 把数据换一种方式展示,比如图像
{
"data": "faceUrl",
"title": "头像",
"width": "80px",
//这个函数可以自定义返回结果
"render": function (data, type, row, meta) {
return '<img style="width:56px;" src=' + data + ' >';
}
}
5.3 一列显示多个数据
{
"data": null,
"width": "350px",
"title": "b",
//这个函数是一列显示多列的数据
render: function(data, type, row, meta) {
return '<label>' + row.id + '</label> <label>' + row.cnName + '</label>';
}}
5.4 字数太多,让它自动换行
{
"data": "briedIntroduction",
"width": "200px",
"title": "a",
//这个函数主要用来换行
render: function(data, type, row, meta) {
//然后是 内容太多用。。。。表示、内容不换行,鼠标移上去显示详情
return '<div id="a" style="white-space: normal;text-overflow:
ellipsis;overflow: hidden" '+
'title="简介">'+data +'</div>';
}}