DataTables的服务器端(SpringMVC)分页模式

简介: 版权声明:欢迎转载,请注明沉默王二原创。 https://blog.csdn.net/qing_gee/article/details/82285030 Datatables是一款jquery表格插件。
版权声明:欢迎转载,请注明沉默王二原创。 https://blog.csdn.net/qing_gee/article/details/82285030

Datatables是一款jquery表格插件。它是一个高度灵活的工具,可以将任何HTML表格添加高级的交互功能。

分页,即时搜索和排序
几乎支持任何数据源:DOM, javascript, Ajax 和 服务器处理
支持不同主题 DataTables, jQuery UI, Bootstrap, Foundation
各式各样的扩展: Editor, TableTools, FixedColumns ……
丰富多样的option和强大的API
支持国际化
免费开源 ( MIT license )! 商业支持

因此这一款非常值得推荐的表格插件。今天借此机会我们来记录一下使用服务器端(SpringMVC)分页的方法。

首先,来看客户端的JavaScript代码:

var self_order_table = $("#self_order_table").DataTable({
            "processing": true,
            "serverSide": true,
            "paging": true,
            language : QINGE._set.table_language,
             "ajax": {
                   "url": CONFIG.mec_datable.index + "otm/order/list?p=self",
                   "type": "POST",
                   "data": function (d) {
                      //删除多余请求参数
                      for(var key in d){
                          if(key.indexOf("columns")==0||key.indexOf("order")==0||key.indexOf("search")==0){ //以columns开头的参数删除
                              delete d[key];
                          }
                      }
                      var searchParams= {
                              page : d.start == 0 ? 1 : (d.start/d.length + 1),
                              rows : d.length,
                       };
                      //附加查询参数
                      if(searchParams){
                          $.extend(d,searchParams); //给d扩展参数
                      }
                   },
                   "dataType" : "json",
                   "dataFilter": function (response) {//json是服务器端返回的数据
                       var json = QINGE.jsonEval(response);

                        if (json[QINGE.keys.statusCode] == QINGE.statusCode.error) {
                            if (json[QINGE.keys.message])
                                $.showErr(json[QINGE.keys.message]);
                        } else {
                               var returnData = {};
                               returnData.draw = json.result.vo.mo.draw;
                               returnData.recordsTotal = json.result.count;//返回数据全部记录
                               returnData.recordsFiltered = json.result.count;//后台不实现过滤功能,每次查询均视作全部结果
                               returnData.data = json.result.list;//返回的数据列表
                               return JSON.stringify(returnData);//这几个参数都是datatable需要的,必须要
                        }

                   }
               },
            deferRender : true,
            "scrollX" : true,
            scrollCollapse : true,
            fixedColumns : {
                leftColumns : 1,
            },
            "columnDefs" : [
                    {
                        targets : 0,
                        data : "scode",
                        title : "商品",
                        render : function(data, type, row) {
                            return "</div><div style='color: #676b6e;font-size: 10px; '>" + row.scode + "</div>";
                        }
                    }, {
                        targets : 1,
                        "data" : "order_count",
                        title : "委托量",
                    }, {
                        targets : 2,
                        "data" : "chengjiao_count",
                        title : "成交量",
                    }, {
                        targets : 3,
                        "data" : "order_price",
                        title : "委托价",
                    } ],
            "rowCallback" : function(row, data, index) {
            },
        });

需要注意的内容就是,如果使用服务器端分页,需要开启:

"processing": true,
"serverSide": true,
"paging": true,

然后借助ajax选项来定制发往服务器端的分页参数和服务器端返回的分页参数,先来看分页请求参数:

   "data": function (d) {
  //删除多余请求参数
  for(var key in d){
      if(key.indexOf("columns")==0||key.indexOf("order")==0||key.indexOf("search")==0){ //以columns开头的参数删除
          delete d[key];
      }
  }
  var searchParams= {
          page : d.start == 0 ? 1 : (d.start/d.length + 1),
          rows : d.length,
   };
  //附加查询参数
  if(searchParams){
      $.extend(d,searchParams); //给d扩展参数
      }
   },

其中page为第几页,rows为一页显示多少行,这两个是必须参数。这个时候,发往服务器端的参数都有哪一些呢?看下图。

这里写图片描述

①、其中draw是DataTables一个必须参数,是记录第几次分页的一个关键参数,服务器端还需要返回。
②、通过start和length参数可以计算出当前请求是第几页,比如说上图中的start为40,length为10,即page等于5(计算公式为:d.start == 0 ? 1 : (d.start/d.length + 1)
③、rows和length是相同的,只不过本次我们的SpringMVC端只认rows,不认length,所以需要转换一下。

再来看服务器端返回的数据处理,此时需要用到Ajax的dataFilter:

"dataFilter": function (response) {//json是服务器端返回的数据
 var json = QINGE.jsonEval(response);

if (json[QINGE.keys.statusCode] == QINGE.statusCode.error) {
    if (json[QINGE.keys.message])
        $.showErr(json[QINGE.keys.message]);
    } else {
        var returnData = {};
          returnData.draw = json.result.vo.mo.draw;
          returnData.recordsTotal = json.result.count;//返回数据全部记录
          returnData.recordsFiltered = json.result.count;//后台不实现过滤功能,每次查询均视作全部结果
          returnData.data = json.result.list;//返回的数据列表
          return JSON.stringify(returnData);//这几个参数都是datatable需要的,必须要
    }
}

服务器端返回的是json字符串,因此可以通过jsonEval函数来转换成json对象。然后从中取出datatables需要的关键数据:

var returnData = {};
returnData.draw = json.result.vo.mo.draw;
returnData.recordsTotal = json.result.count;//返回数据全部记录
returnData.recordsFiltered = json.result.count;//后台不实现过滤功能,每次查询均视作全部结果
returnData.data = json.result.list;//返回的数据列表
return JSON.stringify(returnData);//这几个参数都是datatable需要的,必须要

QINGE.jsonEval(response)函数的具体内容如下:

jsonEval : function(data) {
    try {
        if ($.type(data) == 'string')
            return eval('(' + data + ')');
        else
            return data;
    } catch (e) {
        return {};
    }
},

这样的话,针对客户端传递到服务器端的参数和接收服务器端返回的数据就处理完成了,接下来我们来看Java端(也就是SpringMVC)来如何接收分页请求和响应分页数据。

首先来看controller:

@SuppressWarnings({ "rawtypes", "unchecked" })
@RequestMapping(value = "list")
public void list(HttpServletResponse response) {
    Map result = new HashMap();

    // 获取列表参数
    BaseConditionVO vo = getBaseConditionVOForTable();
    vo.addParams("uid", InfoEL.getMemberUid());

    String p = getPara("p", "trade");
    if ("self".equals(p)) {
        result.put("vo", vo);
        result.put("count", selfOrderService.countTotal(vo));
        result.put("list", selfOrderService.getList(vo, vo.createRowBounds()));
        renderJsonDone(response, result);
    }
}

其中BaseConditionVO 为分页的请求参数,里面包含如下属性:

public static int PAGE_SHOW_COUNT = 50;// 默认一页为50行
private int pageNum = 1;//第几页
private int numPerPage = 0;// 一页显示多少行数据
private long totalCount = 0;// 总页数
private String orderField = "";// 排序字段
private String orderDirection = "";// 排序方式

/**
 * @Fields ps : 对参数类型进行封装,同时方便存储其他参数
 */
private Map<String, Object> mo = new HashMap<String, Object>();

其中renderJsonDone为返回json字符串的方法:

    private void renderJson(HttpServletResponse response, String jsonText) {
        PrintWriter writer = null;
        try {
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);

            response.setContentType(contentType);
            writer = response.getWriter();
            writer.write(jsonText);
            writer.flush();
        } catch (IOException e) {
            throw new OrderException(e.getMessage());
        } finally {
            if (writer != null)
                writer.close();
        }
    }

    protected void renderJsonDone(HttpServletResponse response, final Object value) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("statusCode", 200);
        map.put("result", value);
        String jsonText = JSON.toJSONString(map);

        renderJson(response, jsonText);
    }

那么,SpringMVC是怎么分页的呢?关键方法就在:

result.put("count", selfOrderService.countTotal(vo));// 计算总页数
result.put("list", selfOrderService.getList(vo, vo.createRowBounds()));// 获取分页

对于SpringMVC来说,其强大的集成功能就在于此,我们只需要按照这种方式将RowBounds:vo.createRowBounds()对象传递给Mybatis,Mybatis就会自己帮我们处理好分页,我们并不需要关注分页的具体细节。
先来来看Mybatis的处理:

    <!--列 -->
    <sql id="Base_Column_List">
        so.*
    </sql>

    <sql id="queryJoins">
    </sql>

    <sql id="Base4List">
        from otm_self_order so
        <include refid="queryJoins"/>
        where so.del_flag = 0
        <if test="mo.status != null">
            and so.status = #{mo.status}
        </if>
        <if test="mo.uid != null">
            and so.uid = #{mo.uid}
        </if>
        <if test="mo.cancel != null">
            and so.cancel = #{mo.cancel}
        </if>
    </sql>

    <select id="getList" resultMap="BaseResultMap" parameterType="map">
        select
        <include refid="Base_Column_List" />
        <include refid="Base4List" />
        <choose>
            <when test="orderField !=null and orderField !=''">
                ORDER BY ${orderField}
                <if test="orderDirection != null and orderDirection != ''">${orderDirection}</if>
            </when>
            <otherwise>
                order by so.update_date DESC
            </otherwise>
        </choose>
    </select>

    <select id="countTotal" resultType="java.lang.Integer" parameterType="map">
        select
            count(0)
        <include refid="Base4List" />
    </select>

好了,说完了客户端和服务器端的处理细节,我们来看一下具体的服务器端返回数据形式,通过Chrome浏览器的network面板就可以观察到,如下图:

这里写图片描述

另外,分页的效果图如下:

这里写图片描述

相关文章
|
9月前
|
存储 弹性计算 编解码
ecs实例规格工作负载模式
阿里云ECS实例有多种工作负载模式:计算密集型(适合高性能计算)、内存密集型(适用于内存数据库)、通用型(平衡资源,多场景适用)、大数据型(优化大数据分析)、共享型(低成本,轻负载)和企业级实例(高稳定性和隔离性)。用户依据业务需求选择实例规格,结合SLB和ESS服务可优化架构,应对动态负载。
81 4
|
9月前
|
存储 设计模式
用反应器模式和epoll构建百万并发服务器
用反应器模式和epoll构建百万并发服务器
85 0
|
4月前
|
消息中间件 分布式计算 监控
大数据-78 Kafka 集群模式 集群的应用场景与Kafka集群的搭建 三台云服务器
大数据-78 Kafka 集群模式 集群的应用场景与Kafka集群的搭建 三台云服务器
139 6
|
4月前
|
SQL 存储 数据管理
Hadoop-15-Hive 元数据管理与存储 Metadata 内嵌模式 本地模式 远程模式 集群规划配置 启动服务 3节点云服务器实测
Hadoop-15-Hive 元数据管理与存储 Metadata 内嵌模式 本地模式 远程模式 集群规划配置 启动服务 3节点云服务器实测
87 2
|
5月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:如何提高代码的可维护性与扩展性在软件开发领域,PHP 是一种广泛使用的服务器端脚本语言。随着项目规模的扩大和复杂性的增加,保持代码的可维护性和可扩展性变得越来越重要。本文将探讨 PHP 中的设计模式,并通过实例展示如何应用这些模式来提高代码质量。
设计模式是经过验证的解决软件设计问题的方法。它们不是具体的代码,而是一种编码和设计经验的总结。在PHP开发中,合理地使用设计模式可以显著提高代码的可维护性、复用性和扩展性。本文将介绍几种常见的设计模式,包括单例模式、工厂模式和观察者模式,并通过具体的例子展示如何在PHP项目中应用这些模式。
|
7月前
|
SQL 弹性计算 资源调度
云服务器 ECS产品使用问题之bin/spark-sql --master yarn如何进行集群模式运行
云服务器ECS(Elastic Compute Service)是各大云服务商阿里云提供的一种基础云计算服务,它允许用户租用云端计算资源来部署和运行各种应用程序。以下是一个关于如何使用ECS产品的综合指南。
|
6月前
|
数据采集 弹性计算 供应链
阿里云服务器付费模式:按量付费、包年包月和抢占式实例全解析
阿里云服务器提供包年包月、按量付费与抢占式实例三种付费模式。包年包月为预付费,适合长期稳定使用,价格更优惠并支持备案。按量付费则为后付费模式,按小时结算,适合短期或访问量波动大的场景,但不支持备案。抢占式实例基于按量付费,价格更低(最多节省90%),适用于无状态应用,如临时测试或可弹性伸缩的Web服务,但存在被系统释放的风险,同样不支持备案。根据具体需求选择合适的付费模式能够有效降低成本并提高效率。
300 0
|
7月前
|
弹性计算 供应链 并行计算
阿里云ECS服务器五种计费模式有啥区别?包年包月、按量付费、抢占式实例、节省计划和预留实例券
阿里云服务器计费多样化:包年包月适合长期稳定服务,如Web网站;按量付费适合短期或波动需求,如测试、扩展;抢占式实例享折扣但可能被释放,适合无状态任务;预留实例券抵扣按量付费账单;节省计划提供资源使用承诺的折扣,适用于用量稳定的业务。
207 7
|
6月前
|
Ubuntu 关系型数据库 应用服务中间件
在Ubuntu 18.04上安装和配置pgAdmin 4服务器模式的方法
在Ubuntu 18.04上安装和配置pgAdmin 4服务器模式的方法
117 0
|
7月前
|
弹性计算 数据安全/隐私保护 云计算
云服务器 ECS产品使用问题之幻兽帕鲁服务器如何修改困难模式
云服务器ECS(Elastic Compute Service)是各大云服务商阿里云提供的一种基础云计算服务,它允许用户租用云端计算资源来部署和运行各种应用程序。以下是一个关于如何使用ECS产品的综合指南。

热门文章

最新文章