Mysql 實現移動端滑動分頁
阿新 • • 發佈:2018-11-05
很多移動端分頁功能是滑動分頁,當 api 需要提供分頁功能的時候,資料庫端需要使用 procedure 儲存過程.
1. 使用 workbench 或其他的資料庫操作工具新建儲存過程
將新建的儲存過程命名為 paging
新建儲存過程程式碼
CREATE DEFINER=`dev_pmall`@`%` PROCEDURE `paging`(IN tb_name VARCHAR(128), IN select_str VARCHAR(1024), IN where_str VARCHAR(1024), IN where_str2 VARCHAR(1024), IN order_by_str VARCHAR(1024), IN counter INT) BEGIN SET @current = 0; SET @row_number = 0; SET @sql1 = CONCAT('SELECT t2.row_number into @current FROM (SELECT (@row_number := @row_number + 1) AS row_number, t.* FROM (SELECT * FROM ', tb_name, ') t WHERE ', where_str, ' ORDER BY ', order_by_str, ' ) t2 WHERE ', where_str2, ' ;'); PREPARE sql1 FROM @sql1; EXECUTE sql1; SET @row_number = 0; SET @sql2 = CONCAT('SELECT ', select_str, ' FROM (SELECT (@row_number := @row_number + 1) AS row_number, t.* FROM (SELECT * FROM ', tb_name, ') t WHERE ', where_str, ' ORDER BY', order_by_str, ' ) t2 WHERE t2.row_number > ', @current, ' LIMIT 0, ', counter, ';'); PREPARE sql2 FROM @sql2; EXECUTE sql2; END
封裝的儲存過程使用類(Laravel/Lumen 框架)
<?php /** * Created by PhpStorm. * User: nwei * Date: 2018/6/7 * Time: 12:05 * * .--, .--, * ( ( \.---./ ) ) * '.__/o o\__.' * {= ^ =} * > - < * / \ * // \\ * //| . |\\ * "'\ /'"_.-~^`'-. * \ _ /--' ` * ___)( )(___ * (((__) (__))) 高山仰止,景行行止.雖不能至,心嚮往之. * */ namespace App\Tools; use Illuminate\Support\Facades\DB; class CursorPaging { protected $table_name = null; protected $select_str = null; protected $where_str = null; protected $where_str2 = null; protected $order_by_str = null; protected $since = null; protected $count = null; /** * CursorPaging constructor. * @param $table_name * @param $select_str * @param $where_str * @param $where_str2 * @param $order_by_str * @param $since * @param $count * * 通過 pop 商城儲存過程修改,該 pop 使用 CI 框架,代表 sql 示例 * * if ($sec['since']) { $query = $this->db2->query(" CALL `paging`( ' {$tb_name} ', ' product_id,name,sub_name,status,image,pd_price,stocks ', ' status = 1 and device = 2 and name like ''%{$keyword}%'' ', ' product_id = {$sec['since']} ', ' date_added desc, product_id desc ', {$sec['count']} );"); } else { $query = $this->db2 ->select('product_id,name,sub_name,status,image,pd_price,stocks') ->where('status', 1) ->where('device', 2) ->like('name', $keyword) ->order_by('date_added desc, product_id desc') ->limit($sec['count'], 0) ->get('v_wx_product'); } * * * 未整合前示例 * if ($since) { $tb_name = "sms"; $select_str = "*"; $where_str = "1=1"; //條件 $where_str2 = " id = ".$since; //遊標條件 $order_by_str = " id desc "; $counter = $count; $rs = DB::select('call paging(?, ?, ?, ?,?,?)',[$tb_name,$select_str,$where_str,$where_str2,$order_by_str,$counter]); } else { $query = "select * from sms order by id desc limit 0,".env("COUNT"); $rs = DB::select($query); } return $this->jsonData("0","ok",$rs); * */ function __construct($table_name,$select_str,$where_str,$where_str2,$order_by_str,$since,$count) { $this->since = isset($since)?$since:null; $this->count = isset($count)?$count:env("COUNT"); //選填 $this->table_name = $table_name; //必填 $this->select_str = isset($select_str)?$select_str:"*"; $this->where_str = isset($where_str)?$where_str:" 1=1 "; $this->where_str2 = $where_str2; //必填 $this->order_by_str = $order_by_str; //必填 } /** * 利用遊標分頁 * @return mixed */ public function cursor_paging(){ $rs = null; if ($this->since) { $params = [ $this->table_name, $this->select_str, $this->where_str, $this->where_str2, $this->order_by_str, $this->count ]; $rs = DB::select('call paging(?, ?, ?, ?,?,?)',$params); } else { $query = "select ".$this->select_str." from ".$this->table_name." where ".$this->where_str." order by ".$this->order_by_str." limit 0,".$this->count; $rs = DB::select($query); } return $rs; } }
建構函式引數說明
建構函式中的第一個引數是表名,第二個引數是要查詢的欄位名,不傳參預設為 '*',第三個引數是查詢條件,不傳參預設為 '1=1',第四個引數是遊標條件,第五個引數是排序方式,第六個引數是開始遊標,第七個引數為每頁的數量.
使用示例
public function getProducts($request,$product_type){ $since = !empty($request->input("since"))?$request->input("since"):null; $where_str = " status = 1 and weight = 1 and product_type = ".$product_type ." "; $where_str2 = " id = ".$since ." "; $order_by_str = " updated_at desc "; $table_name = " product "; $select_str = null; $rs = []; try{ $procedure = new CursorPaging($table_name,$select_str,$where_str,$where_str2,$order_by_str,$since,null); $rs = $procedure->cursor_paging(); }catch (\Exception $exception){ $rs = false; operate_log("0","前端獲取商品列表失敗",$exception); } return $rs; }
結果
這是沒有任何引數的請求結果, 每頁兩條資料,此時它的遊標位在表中 id=1 的位置上,第二次請求時我們的路由應該變成這樣
http://localhost:30017/api/v1/front/products?since=1
結果
這樣的結果跟我們資料庫的查詢結果是一樣的