Lumen/Laravel Model 操作

简介

Lumen的Model操作使用的是 Laravel 内置的 Eloquent ORM,Eloquent提供了一个美观、简单的与数据库打交道的 ActiveRecord 实现,每张数据表都对应一个与该表进行交互的模型(Model),通过模型类,你可以对数据表进行查询、插入、更新、删除等操作。

配置

应用的数据库配置位于 config/database.php(但是数据库用户及密码等敏感信息位于 .env 文件)。在该文件中你可以定义所有的数据库连接,并指定哪个连接是默认连接。该文件中提供了所有支持数据库系统的配置示例。

1
env('DB_CONNECTION', 'mysql') // 配置文件中通过env()获取.env文件中配置的键值

模型定义

模型定义的目录app\Models

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class TestModel extends Model
{
// 指定连接名称
// config/databases.php中的mysql索引项。
protected $connection = "mysql"
// 定义表名
protected $table = "test";

// 定义默认主键,默认是id,如果是其他值这里需要修改
protected $primaryKey = "id";
// 这里是主键的类型,默认int如果是非int类型就需要修改
protected $keyType = 'int';
// 主键是否是自增的配置
public $incrementing = true;

// 表明模型是否应该被打上时间戳,这个功能可以让ORM自动为我们的时间字段自动更新配置上时间
// 配合CREATED_AT 使用 UPDATED_AT使用
// 默认开启,如果不实用该功能配置false
public $timestamps = false;
// CREATED_AT、UPDATED_AT配置常量可以自定义自己的字段名称
const CREATED_AT = 'created_at';
const UPDATED_AT = 'updated_at';
// 当然也可以指定保存的时间格式
// 这里可接受的值跟date()的接受的值是一致的。
// 文档 https://www.php.net/manual/zh/function.date.php
protected $dateFormat = 'U';
}

模型CRUD

查询

在Contoller,Service层等可以直接调用模型方法

获取全部数据

all()返回所有数据,如果数据存在返回对象\Illuminate\Database\Eloquent\Collection 可以使用toArray()方法输出为数组格式。如果没有数据放回空数组。

1
2
$data = TestModel::all();
$data->toArray();

获取一条数据

first() 如果找到了数据返回的是个对象, 可以使用toArray()方法输出为数组格式,如果找不到数据返回null;

1
2
$data = TestModel::first();
$data->toArray();

获取多条数据

注意: 无论查询结果是否为空,get()方法都放回一个对象,如果使用empty() 检测一定都是false;所以可以完全直接调用toArray(),这一点和first()是不一样的。

1
2
$data = TestModel::get();
$data->toArray();

注意: 如果对结果集对象遍历

1
2
3
4
<?php
foreach($data as $v) {
// 这里的$v是个stdClass对象
}

查询指定字段

1
2
3
$data = TestModel::select("name")->first();
// 多个字段
$data = TestModel::select("name","status")->first();

如果要对字段进行表达式处理

1
2
3
4
// 多个字段
$data = TestModel::selectRaw("name,status")->first();
// 复杂查询
$data = TestModel::selectRaw("CASE name WHEN 1 THEN 1 ELSE -1 END name")->first();

Where条件

where条件大都封装好了,可以使用whereXXX()调用,如whereIn()whereBetween

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$data = TestModel::select("name")->where("status",1)->first();
// 或者
$data = TestModel::select("name")->where("status","=",1)->first();
// in 查询
$data = TestModel::select("name")->whereIn("status",[1,-1])->first();
// between
// select name from `test` where `status` = ? and `status` between ? and ?
$data = TestModel::select("name")->where("name","hello")->whereBetween("status",[1,-1])->first();
// between
// select name from `test` where `status` = ? or `status` between ? and ?
$data = TestModel::select("name")->where("name","hello")->whereBetween("status",[1,-1],"or")->first();
// between
// select name from `test` where `status` = ? or `status` not between ? and ?
$data = TestModel::select("name")->where("name","hello")->whereBetween("status",[1,-1],"or",true)->first();
// or
$data = TestModel::select("name")->orWhere("status","=",1)->first();

分页

1
2
3
$data = TestModel::select("name")->orWhere("status","=",1)->offset(0)->limit(10)->get();
// 或者
$data = TestModel::select("name")->orWhere("status","=",1)->skip(10)->limit(10)->get();

自动分页

Eloquent ORM 内置一个非常方便的自动分页处理函数。

1
2
// 只要传入每页条数, Eloquent自动帮你处理分页数据。指定页数是参数`page`可以修改自己的名称。
$users = TestModel::select("name")->paginate(10);

$users是一个分页对象,可以使用 appends 方法增加搜索字串到分页链接中:

1
$users->appends(['sort' => 'votes']);

这样会产生类似下列的链接:

1
http://example.com/something?page=2&sort=votes

如果您想要将「哈希片段」加到分页的 URL,您可以使用 fragment 方法:

1
$users->fragment('foo');

此方法调用后将产生 URL,看起来像这样:

1
http://example.com/something?page=2#foo

setPath 方法自定义使用的 URL:

1
$users->setPath('http://domain/path');

Join连表查询

1
$data = TestModel::select("name")->leftJoin("user","user.id","=","test.id")->first();

Count等聚合查询

直接返回整型数。

1
2
TestModel::count();
TestModel::max("price");

分组与排序

1
2
$data = TestModel::orderBy("id","desc")->first();
$data = TestModel::orderBy("id","desc")->groupBy("city")->first();

执行原生语句

1
2
3
4
// 这个方法返回一个二维数组、数组元素是一个stdClass对象。查询不到数据返回空数组。
DB::connection("mysql")->select("select * from user where status=? limit 1",[1]);
// 或者,返回与上面的一致
$data = (new TestModel())->getConnection()->select("select * from user where status=? limit 1",[1]);

插入

1
2
3
4
// 返回布尔值,成功或者失败 
$success = TestModel::insert(["namae" => "john"]);
// 返回自增ID的值
$id = TestModel::insertGetId(["namae" => "john"]);

更新

1
2
3
4
5
6
7
// 返回受影响的行数
$rowEffect = TestModel::where("id",1)->update(["status"=>1]);
// 或者
$model = TestModel::find($id);
$model->status = 1;
// 返回布尔值
$model->save();

删除

1
2
// 返回删除影响数
$delete = TestModel::where("id",1)->delete();

事务

事务的三个方法beginTransaction,commit,rollBack返回的都是NULL,出错必须用try catch结构包裹处理异常错误;

1
2
3
4
5
6
7
8
<?php
try {
DB::beginTransaction();
// todo something
DB::commit();
} catch (Exception $e) {
DB::rollBack();
}

或者

1
2
3
4
5
6
7
try {
TestModel::beginTransaction();
// todo something
TestModel::commit();
} catch (Exception $e) {
TestModel::rollBack();
}

高级用法

chuck处理大批量查询数据,减少内存占用

1
2
3
TestModel::chunk(100,function($data){
// todo something
});

使用cursor()逻辑过滤

1
2
3
4
// 无论有无结果集均返回的是集合对象,可以使用toArray()s
$result = TestModel::cursor()->filter(function ($test) {
return $test->id > 500;
});

pluck返回指定字段的值数组

1
2
3
4
5
// 返回集合对象,无论是否有记录都返回集合对象,toArray()如果为空就是返回空数组。
$result = TestModel::where("id",">=",1)->pluck("id");
// 可以使用toArray()转换成数组
$data = $resut=>toArray();
// [1,2,3,4,.....]

get('id')返回结果的区别:

1
2
$getResult = TestModel::get("id")->toArray();
$pluckResult = TestModel::pluck("id")->toArray();

$getResult 结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
array (
0 =>
array (
'id' => 1,
),
1 =>
array (
'id' => 2,
),
2 =>
array (
'id' => 3,
),
)

$pluckResult 结果:

1
2
3
4
5
array (
0 => 1,
1 => 2,
2 => 3,
)

pluck可以指定数据中的某个字段值作为键,假设数据库结构

Id status
1 Off
2 On
3 Freeze
1
$pluckResult = TestModel::pluck("id","status")->toArray();

则最终结果输出:

1
2
3
4
5
array (
"off" => 1,
"On" => 2,
"Freeze" => 3,
)

toSql查看构造器最终的SQL语句

1
2
TestModel::toSql();
TestModel::where("id",">=",1)->toSql();

总结

大部分sql的关键字的表达方式,Eloquent都已经实现,IDE输入关键字可自动提示!对于复杂SQL比如使用了聚合函数等,Eloquent都提供了xxxRaw()的方法。比如:selectRaw,whereRaw灵活应用。