ThinkPHP 分页和原生查询

1. 前言

本小节介绍 ThinkPHP 框架的分页查询和原生查询,通过定义一个学生列表来介绍分页查询的目的是限制请求返回的数据量,防止内存被打满,原生查询主要用于 sql 语句比较复杂的场景。

2. 批量添加多条学生信息

为了演示方便需要添加多条学生信息,下面给出 ThinkPHP 添加多条学生信息的方法:

    public function addStudents()
    {
        $nameArr = ["吴小明", "张红", "赵四", "王五", "钱学", "孙空", "李珍"];
        $ageArr = [18, 19, 20, 21, 22, 23, 24, 25];
        $saveArr = [];
        $createdAt = time();
        for ($i = 0; $i < 200; $i++) {
            $arr = [];
            $arr['name'] = $nameArr[array_rand($nameArr)];
            $arr['age'] = $ageArr[array_rand($ageArr)];
            $arr['id_number'] = "42011720100512" . mt_rand(1000, 9999);
            $arr['status'] = 1;
            $saveArr[] = $arr;
        }
        Db::table('student')->insert($saveArr);
        return json('添加成功');
    }

Tips: 也可以通过 sql 语句在 MySQL 客户端自行添加。

如下图所示:
图片描述

3. 获取学生分页列表接口

3.1 定义路由

首先在 study.php 路由文件添加 GET 路由如下:

//获取学生列表接口
Route::get('students', 'app\controller\Study\StudentController@getStudents');

如下图所示:
图片描述

3.2 定义路由指向的方法

下面定义一下路由里面指向的 getStudents() 方法,方法如下:

    /**
     * 获取学生列表
     * @return \think\response\Json
     * @throws \think\db\exception\DbException
     */
    public function getStudents()
    {
        //每页条数
        $size = (int)$this->request->param('size', 15);

        $students = StudentModel::where('status', 1)->order('created_at DESC')->paginate($size);

        return json($students);
    }

Tips: paginate($size) 方法表示使用数据库查询分页且每页 $size 条,order('created_at DESC') 表示列表按照创建时间倒序。

3.4 请求接口获取分页学生列表

如下图所示,可以在 postman 请求上述定义好的学生分页列表:
图片描述

Tips: page 表示翻页参数,这个参数不需要在控制器去接收,框架中的 paginate() 方法底层代码会处理 page 参数,但 size 参数是需要在控制器接收的,这里列表数据没有处理时间格式。
下面对返回参数说明一下:

返回参数 含义描述
total 总条数
per_page 每页条数
current_page 当前页数
last_page 总页数
data 列表数据

4. 原生查询

下面主要介绍一下 ThinkPHP 框架原生查询,一般情况下,框架自带的方法都可以满足大多数查询需求,但有时候对于复杂的 sql 查询逻辑,使用原生查询比较合适,下面定义一个方法使用原生查询获取学生列表数据:

    /**
     * 获取学生列表
     * @return \think\response\Json
     * @throws \think\db\exception\DbException
     */
    public function getStudents()
    {
        //每页条数
        $size = (int)$this->request->param('size', 15);
        //页数
        $page = (int)$this->request->param('page', 1);
        $limit = ($page - 1) * $size;

        $students = Db::query("select * from `student` where `status`=1 order by created_at desc limit {$limit},{$size}");

        return json($students);
    }

page=2size=5 返回数据如下:

[
    {
        "id": 6,
        "name": "王五",
        "age": 25,
        "id_number": "420117201005123617",
        "created_at": 1603617951,
        "update_at": 0,
        "status": 1
    },
    {
        "id": 7,
        "name": "张红",
        "age": 19,
        "id_number": "420117201005123721",
        "created_at": 1603617951,
        "update_at": 0,
        "status": 1
    },
    {
        "id": 8,
        "name": "吴小明",
        "age": 21,
        "id_number": "420117201005123197",
        "created_at": 1603617951,
        "update_at": 0,
        "status": 1
    },
    {
        "id": 9,
        "name": "钱学",
        "age": 19,
        "id_number": "420117201005121149",
        "created_at": 1603617951,
        "update_at": 0,
        "status": 1
    },
    {
        "id": 10,
        "name": "孙空",
        "age": 21,
        "id_number": "420117201005124671",
        "created_at": 1603617951,
        "update_at": 0,
        "status": 1
    }
]

Tips: 此时的数据结构和上面分页的不一样。

5. 小结

本小节介绍了如何使用分页查询学生列表,分页查询的目的就是为了控制每页的条数从控制请求数据量过大的问题,分页查询中的 page 参数表示页数,这个参数在 ThinkPHP 框架中会自动处理,每页条数默认是 15,若需要改变分页每页条数,则需要向 paginate() 方法传递条数参数。

Tips: 代码仓库:https://gitee.com/love-for-poetry/tp6