zoukankan      html  css  js  c++  java
  • datatables使用服务器端分页、排序、搜索功能(PHP)

      datatables可以自动帮我们实现分页,但当数据量过万时,datatables显示数据会很慢,因为datatables每取出一条数据,就要创建 tr/td ,所以数据越多,速度就越慢(我5万条数据大概需要40秒)。

      datatables的服务端模式可以解决这个问题。客户端模式是一次性把数据加载到前台渲染,很耗时间,服务端模式,根据分页到后台提取相应的数据。

      使用服务端模式一般需要配置下面的一些参数,案例:

    <!DOCTYPE html>
    <html>
    <head>
        <title>测试datatables服务端</title>
        <link rel="stylesheet" type="text/css" href="__ADMIN__/css/jquery.dataTables.css">
        <!-- jQuery -->
        <script type="text/javascript" charset="utf8" src="__ADMIN__/js/jquery.js"></script>
        <!-- DataTables -->
        <script type="text/javascript" charset="utf8" src="__ADMIN__/js/jquery.dataTables.js"></script>
    </head>
    <body>
        <table id="table_id_example" class="display">
        <thead>
            <tr>
                <th>user_id</th>
                <th>username</th>
                <th>email</th>
            </tr>
        </thead>
        <tbody>
        <!-- 由datatables自动添加 tr、td -->
        </tbody>
    </table>
    
    <script>
    $(document).ready(function() {
        $("#table_id_example").dataTable({
          "lengthMenu": [
              [4,8,10,15,20,-1],    // 具体的数量
              [4,8,10,15, 20,"全部"] // 文字描述
          ],
          "paging": true,    // 是否开启分页功能(默认开启)
          'info': true,      // 是否显示分页的统计信息(默认开启)
          "searching":true,  // 是否开启搜索功能(默认开启)
          "ordering": true,  // 是否开启排序功能(默认开启)
          "order":[ [0,'asc'] ], // 设置默认排序的表格列[参数1是表格列的下标,从0开始]
          "stateSave": true,      // 是否保存当前datatables的状态(刷新后当前保持状态)
          "processing"true,     // 显示处理中的字样[数量多的时候提示用户在处理中](默认开启)
          "serverSide": true,    // 是否开启服务器模式
                                  // false时,会一次性查询所有的数据,dataTables帮我们完成分页等。
                                  // true时,点击分页页码就会每次都到后台提取数据。
          "language": //把文字变为中文
              {  
                "sProcessing": "处理中...",  
                "sLengthMenu": "显示 _MENU_ 项结果",  
                "sZeroRecords": "没有匹配结果",  
                "sInfo": "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项",  
                "sInfoEmpty": "显示第 0 至 0 项结果,共 0 项",  
                "sInfoFiltered": "(由 _MAX_ 项结果过滤)",  
                "sInfoPostFix": "",  
                "sSearch": "搜索:",  
                "sUrl": "",  
                "sEmptyTable": "表中数据为空",  
                "sLoadingRecords": "载入中...",  
                "sInfoThousands": ",",  
                "oPaginate": {  
                    "sFirst": "首页",  
                    "sPrevious": "上页",  
                    "sNext": "下页",  
                    "sLast": "末页"  
                },  
                "oAria": {  
                    "sSortAscending": ": 以升序排列此列",  
                    "sSortDescending": ": 以降序排列此列"  
                }  
              },
          // 使用ajax到后台服务获取数据
          "ajax": {               
          "url": "{:url('User/index')}", //请求数据的后台地址
          "type": "POST",     // ajax的请求方法
              
          },
          //需要接收返回的数据
          //总的数量与表格的列数必须一致,不能多也不能少,一个变量代表一个td
          //如果data接收服务器没有返回该字段信息,那么该字段一定要同时设置defaultContent属性
          //例{'data':'a',"defaultContent":""},
          "columns": [
            {"data": "user_id"},
            {"data": "username"},
            {"data": "email"},
          ]
        });
      });
    </script>
    </body>
    </html>

       上面的设置好之后,给服务端发送ajax请求,我们可以在浏览器的控制台看到ajax请求的数据如下:

      

      我们可以在服务端接收这些数据,由于接收到的是一个多维数组,拆分数据的时候注意一下即可。以下是PHP中TP5框架处理服务端数据的案例:

    if( request()->isAjax() ){
                $this->user = new UserModel;
    
                //接收所有传过来的post数据
                $datatables = request()->post();
                //得到排序的方式
                $order = $datatables['order'][0]['dir'];
                //得到排序字段的下标
                $order_column = $datatables['order'][0]['column'];
                //根据排序字段的下标得到排序字段
                $order_field = $datatables['columns'][$order_column]['data'];
                //得到limit参数
                $limit_start = $datatables['start'];
                $limit_length = $datatables['length'];
                //得到搜索的关键词
                $search = $datatables['search']['value'];
    
                //从数据库取出结果
                //如果有搜索行为,则按照关键词查询数据
                if ($search) {
                    $data = $this->user
                            ->order("$order_field $order")
                            ->limit($limit_start,$limit_length)
                            ->where('user_id','LIKE',"%$search%")
                            ->select();
                    $data_keyword = $this->user
                                    ->where('user_id','LIKE',"%$search%")
                                    ->select();
                    $cnt = count($data_keyword);   //获取满足关键词的总记录数
    
                }else{
                    //没有关键词,则查询全部
                    $data = $this->user
                    ->order("user_id $order")
                    ->limit($limit_start,$limit_length)
                    ->select();
                    $cnt = $this->user->count(); // 数据总数
                }
    
                if($data) {
                    $data = collection($data)->toArray();
                }            
                $info = [
                   'draw'=> request()->post('draw'), // ajax请求次数,作为标识符
                   'recordsTotal'=>count($data),  // 获取到的结果数(每页显示数量)
                   'recordsFiltered'=>$cnt,       // 符合条件的总数据量
                   'data'=>$data,          //获取到的数据结果
                ];
                //转为json返回
                return json( $info );

      如果不会TP5框架或者使用其他编程语言,这里有通用的思路。

      因为现在是后端模式,一些业务逻辑需要我们去处理:

      1.从ajax中接收到必要的数据,如果需要用到分页,需要查数据库的limit函数的开始、结束参数;要实现排序,则需要获取排序的字段、排序的方式;要加上搜索功能,就要获取到搜索的关键字。

      2.要做是否有搜索行为的判断,有搜索关键字就用到where语句将关键字查出,没有则直接查出返回结果即可。比较直白的逻辑:将这些数据整合到sql查询语句中,需要排序就用order,需要分页就加上limit,需要搜索就加where条件判断

      3.由于要返回符合条件的总数量,搜关键词跟查询所有数据获得的数据量肯定不同,所以要分来获取;搜关键词的时候要查询2次数据库,一次是查出带limit的结果,一次是查出带关键词的结果

      4.查关键词不会得到查哪个字段,只能自己通过程序判断出来,所以最好只查一个字段的关键词

      5.最后的返回数据是核心,‘draw’要原样返回,'data'是从数据库中获取到的数据,转为json格式返回给datatables。

      附:

      datatables简单使用

  • 相关阅读:
    GNU编码标准
    glade2 与 glade 3 (转)
    简单 gcc 参数
    gtk 主循环函数
    指针与数组关联导致的一些现象
    C语言声明数组变量时,在什么情况下,可不指定数组大小
    文件复制函数的效率比较
    关于VMware虚拟机的上网
    errno的基本用法
    查找数组中最大的2个数
  • 原文地址:https://www.cnblogs.com/bk233/p/7656229.html
Copyright © 2011-2022 走看看