Laravel 反对原生的 SQL 查问、晦涩的查问结构器 和 Eloquent ORM 三种查问形式:
- 晦涩的查问结构器(简称 DB),它是为创立和运行数据库查问提供的一个接口,反对大部分数据库操作,和手写 SQL 的实质是一样的。
- Eloquent ORM(简称 ORM),是一个对象关系映射 (Object Relational Mapper) 工具,通过建设模型与数据表进行交互,它会把数据库中的数据映射成对象和汇合对象,无需接触底层数据,能够间接调用映射进去的对象进行开发。
这篇笔记次要来整顿下罕用的 ORM 操作。
查问
artisan tinker
是 Laravel 框架自带的命令,用以调出 Laravel 的交互式运行时,Eloquent ORM 的代码能够间接在该环境中运行。
查问列表
获取所有数据:
use App\Models\User;
$users = User::all();
如果只须要局部字段,有两种形式进行限定:
$users = User::all(["id", "name"]);
$users = User::select("id", "name")->get();
获取单列:
$name = User::pluck('name');
// ["boo", "mac", "yumi"]
还能够在返回的汇合中指定字段的自定义键名,留神:该自定义键必须是该表的其它字段列名,否则会报错:
$name = User::pluck('email','name');
// ["boo" => "boo@example.com", "yumi" => "yumi@example.com"]
查问单条数据
// 通过主键获取模型
$user = User:;find(1);
// 获取匹配查问条件的第一个模型
$user = User::where('is_enable', 1)->first();
// 获取第一条数据的指定列值
$user = User::value("name");
// 返回后果是字符串:boo
// 传递主键数组来调用 find 办法,返回匹配记录汇合
$user = User::find([1,2,3]);
// 等同于
$user = User::whereIn("id", [1,2,3])->get();
解决返回后果集
Eloquent ORM 查问返回值是 Illuminate\Database\EloquentCollection
的一个实例,所以除了能够应用传统的数组形式进行遍历,还能够应用汇合形式进行遍历。
chunk
chunk
办法能够把大的后果集分成小块查问,例如,咱们能够将全副 User 表数据切割成一次解决 5
条记录的一小块:
$result = User::chunk(5, function ($users) {foreach ($users as $user) {echo $user->name.PHP_EOL;}
});
// result 为 boolean
在 User 表中一共有 14
条数据,通过查看查问日志,能够看到chunk
分了三次查问:
each
如果想对一个汇合中的每一项都进行一些操作,但不批改汇合自身,则能够应用each
:
$users = User::all();
$users = $users->each(function ($user , $key) {$user->password = bcrypt(122410);
});
// 返回后果蕴含残缺的 User 模型,其中 password 字段的值被批改
map
如果想对汇合中的所有元素进行迭代,对它们进行批改,并返回蕴含批改的新汇合,那么须要应用map
:
$users = User::all();
$users = $users->map(function ($user, $key) {
return [
"name" => $user->name,
"password" => bcrypt(122410),
];
});
// 返回后果仅蕴含 name 和 password 字段,其中 password 字段的值被批改
聚合办法
// 统计总数
$count = User::count();
// 统计分组
$count = User::select(User::raw("count(id) as aggregate"))->groupBy("is_enable")->get();
// 留神不能这样写:User::select('count(id) as aggregate')->groupBy("is_enable")->get();
条件查问
构建简单查问:
// 组合查问形式一
$where = [];
$where[] = ["is_enable", 1];
$where[] = [function($query){$query->where("id", ">", 10)
->orWhere("name", "like", "%admin%");
}];
User::select("id", "name as username", "email")->where($where)->get();
// 组合查问形式二
$builder = User::select("id", "name as username", "email");
$builder->where("is_enable", 1);
$builder->where(function ($query){$query->where("id", ">", 10)
->orWhere("name", "like", "%admin%");
});
$users = $builder->get();
// 两种形式的查问 SQL 是一样的:select `id`, `name` as `username`, `email` from `users` where (`is_enable` = '1' and (`id` > '10' or `name` like '%admin%'))
// Where Exists
$builder = User::select("id", "name", "email");
$builder->whereExists(function ($query){$query->select(User::raw("title"))
->from("topics")
->whereRaw("topics.user_id = users.id");
});
排序
// 用户 id 倒序
$user = User::orderBy("id", "desc")->get();
// 获取 created_at 最大的一条记录
$user = User::latest()->first();
// 获取 created_at 最小的一条记录
$user = User::oldest()->first();
// 随机一条记录
$users = User::inRandomOrder()->first();
限定
// 跳过前两条记录,取三条记录
$users = User::skip(2)->take(3)->get();
// 输入 SQL:select * from `users` limit 3 offset 2
// 同上
$users = User::offset(2)->limit(3)->get();
其余
// 应用别名
$user = User::select("name as username", "id")->first();
// 创立一个查问构建器
$builder = User::select("name");
// 增加一个查问列到已存在的 select 子句
$user = $builder->addSelect("id")->first();
分页
$users = User::paginate(10);
$users = User::simplePaginate(10);
paginate
办法,返回Illuminate\Pagination\LengthAwarePaginator
实例simplePaginate
办法,返回Illuminate\Pagination\Paginator
实例
每个分页器实例都能够通过以下办法提供更多分页信息:
$result->count() // 当前页条数
$result->currentPage() // 以后页码
$result->perPage() // 每页多少条
$result->total() // 总数(应用 simplePaginate 时有效)
$result->hasMorePages() // 是否有更多
$result->firstItem()
$result->lastItem()
$result->lastPage() (应用 simplePaginate 时有效)
$result->nextPageUrl()
$result->previousPageUrl()
$result->url($page)
插入
$user = new User();
$user->name = "yumi";
$user->fill(["email" => "yumi@example.com"]);
$user->save();
// 返回模型对象
$result = User::create(["name"=>"boo", 'email' => 'boo@example.com']
);
// 返回模型对象
$result = User::insert(["name"=>"boo", 'email' => 'boo@example.com']
);
// 返回 Boolean
$result = User::insertGetId(["name"=>"boo", 'email' => 'boo@example.com']
);
// 返回插入记录对应 ID
更新
单个更新
$user = User::find(1);
$user->name = 'yumi';
$user->save();
// 返回 Boolean
$user = User::where("id", 1)->update(['password' => bcrypt(122410)]);
// 返回受影响行数
批量更新:
$user = User::whereIn("id", [1,2,3])->update(['password' => bcrypt(122410)]);
// 返回受影响行数
删除
单个删除
// 通过主键查问,删除模型
$user = User::find(1);
$user->delete();
// 返回 Boolean
// 间接通过主键删除
User::destroy(1);
// 返回受影响行数
User::where('id', 1)->delete();
批量删除:
User::destroy([1, 2, 3]);
User::destroy(1, 2, 3);
// 注:通过 Eloquent 批量删除时,deleting 和 deleted 事件不会被触发,因为在进行模型删除时不会获取模型。User::whereIn('id', [1, 2, 3])->delete();
// 均返回受影响行数
软删除
除了实在删除数据库记录,Eloquent 也能够「软删除」模型。软删除的模型并不是真的从数据库中删除了。事实上,是在模型上设置了 deleted_at
属性并将其值写入数据库。如果 deleted_at
值非空,代表这个模型已被软删除。
如果要开启模型软删除性能,须要在模型上应用 Illuminate\Database\Eloquent\SoftDeletes trait
,同时须要增加 $dates
属性:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
}
当初,当在模型实例上应用 delete
办法,以后日期工夫会写入 deleted_at
字段。同时,查问进去的后果也会主动排除已被软删除的记录。
软删除常见操作
// 验证给定的模型实例是否已被软删除
if ($user->trashed()) {//}
// 包含已软删除的模型
$users = User::withTrashed()->get();
// 只检索软删除模型
$users = User::onlyTrashed()->get();
// 永恒删除
$user->forceDelete();
留神⚠️:
- 通过 Eloquent 批量删除时,deleting 和 deleted 事件不会被触发,因为在进行模型删除时不会获取模型。
- 通过 Eloquent 批量更新时,更新的模型不会触发 saving, saved, updating 和 updated 模型事件。这是因为在批量更新时实际上从未检索模型。
参考链接
- Eloquent 疾速入门
- Laravel 中 Eloquent ORM 相干操作