Skip to main content
 首页 » 编程设计

php之Laravel Yajra 数据表服务器端存在分页问题

2026年09月08日2langtianya

我是 Laravel 新手,我正在尝试使用 Yajra Datatable具有服务器端功能的插件。该插件适用于少量记录,但我的记录量很大,大约 100000 条记录。

为了加快 Controller 中的处理速度,我使用 take(10) 限制查询结果,并使用另一个查询来计算总结果。到目前为止一切都很好。

问题是如何管理研究。除了主要研究领域之外,我还使用了individual column searching但我不知道如何返回正确的记录数来使用单独的搜索过滤器管理分页。

我认为个人搜索键位于 $columns = $request->get('columns'); 中,但我不知道如何管理计数的查询。

感谢您的宝贵建议。

HTML 查看代码:

<table id="oTable"> 
   <thead> 
      <tr> 
         <th>Action</th> 
         <th>Brand</th> 
         <th>Code</th> 
         <th>Description</th> 
      </tr>  
      <tr> 
         <th class="no_search"></th> 
         <th></th> 
         <th></th> 
         <th></th> 
      </tr> 
   </thead> 
</table> 

Jquery 代码:

$('#oTable').DataTable({ 
    dom: 'lfrtip', 
    "processing": true, 
    "serverSide": true, 
    "ajax": '{!! url('getRecords') !!}', 
    "columns": [ 
      {data: 'items.id', name: 'items_id'}, 
      {data: 'brands.description', name: 'brands_description'}, 
      {data: 'items.code', name: 'items_code'}, 
      {data: 'items.description', name: 'items_description'} 
    ], 
    columnDefs: [ 
      {targets: 'no_sort', orderable: false} 
    ], 
    initComplete: function () { 
 
      this.api().columns().every(function () { 
        var column = this; 
        var columnClass = column.header().className; 
        if (columnClass.indexOf('no_search') != false) { 
          var input = document.createElement("input"); 
          $(input).addClass('form-control'); 
          $(input).appendTo($(column.header()).empty()) 
          .on('change', function () { 
            column.search($(this).val(), false, false, true).draw(); 
          }); 
        } 
      }); 
    } 
  }); 

Controller 的方法:

public function getRecords(Request $request) { 
 
      $search = $request->input('search.value'); 
      $columns = $request->get('columns'); 
 
      $count_total = \DB::table('items') 
                        ->join('brands', 'item.brand', '=', 'brands.code') 
                        ->count(); 
 
      $count_filter = \DB::table('items') 
                        ->join('brands', 'items.brand', '=', 'brands.code') 
                        ->where(   'brands.description' , 'LIKE' , '%'.$search.'%') 
                        ->orWhere( 'items.description' , 'LIKE' , '%'.$search.'%') 
                        ->orWhere( 'items.code' , 'LIKE' , '%'.$search.'%') 
                        ->count(); 
 
      $items= \DB::table('items') 
        ->join('brands', 'items.brand', '=', 'brands.code') 
        ->select( 
            'items.id as items_id', 
            'items.code as items_code', 
            'items.description as items_description', 
            'brands.description as brands_description' 
        ) -> take(10); 
 
        return Datatables::of($items)           
          ->with([ 
            "recordsTotal" => $count_total, 
            "recordsFiltered" => $count_filter, 
          ]) 
          ->rawColumns(['items_id','brands_description']) 
          ->make(true); 
    } 

请您参考如下方法:

您只需替换 Controller 内部的方法并按如下所述设置内容即可。 它将解决您的问题

  1. 管理带或不带搜索的查询
  2. 通过启用分页提高性能

    public function getRecords(Request $request) { 
     
        $search = $request->input('search.value'); 
        $columns = $request->get('columns'); 
     
        $pageSize = ($request->length) ? $request->length : 10; 
     
        $itemQuery = \DB::table('items') 
        ->join('brands', 'items.brand', '=', 'brands.code'); 
     
        // $itemQuery->orderBy('items_id', 'asc'); 
        $itemCounter = $itemQuery->get(); 
        $count_total = $itemCounter->count(); 
     
        $count_filter = 0; 
        if($search != ''){ 
            $itemQuery->where( 'brands.description' , 'LIKE' , '%'.$search.'%') 
                    ->orWhere( 'items.description' , 'LIKE' , '%'.$search.'%') 
                    ->orWhere( 'items.code' , 'LIKE' , '%'.$search.'%') 
            $count_filter = $itemQuery->count(); 
        } 
     
        $itemQuery->select( 
            'items.id as items_id', 
            'items.code as items_code', 
            'items.description as items_description', 
            'brands.description as brands_description' 
        ); 
     
        $start = ($request->start) ? $request->start : 0; 
        $itemQuery->skip($start)->take($pageSize); 
        $items = $itemQuery->get(); 
     
        if($count_filter == 0){ 
            $count_filter = $count_total; 
        } 
     
        return Datatables::of($items)           
            ->with([ 
            "recordsTotal" => $count_total, 
            "recordsFiltered" => $count_filter, 
            ]) 
            ->rawColumns(['items_id','brands_description']) 
            ->make(true); 
    }