Laravel 支持原生的 SQL 查询、流畅的查询构造器 和 Eloquent ORM 三种查询方式:php
这篇笔记主要来整理下经常使用的ORM 操做。laravel
artisan tinker
是 Laravel 框架自带的命令,用以调出 Laravel 的交互式运行时,Eloquent ORM 的代码能够直接在该环境中运行。数据库
获取全部数据:segmentfault
use App\Models\User; $users = User::all();
若是只须要部分字段,有两种方式进行限定:数组
$users = User::all(["id", "name"]); $users = User::select("id", "name")->get();
获取单列:app
$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
的一个实例,因此除了可使用传统的数组方式进行遍历,还可使用集合方式进行遍历。dom
chunk
方法能够把大的结果集分红小块查询,例如,咱们能够将所有User 表数据切割成一次处理 5
条记录的一小块:工具
$result = User::chunk(5, function ($users) { foreach ($users as $user) { echo $user->name.PHP_EOL; } }); // result 为 boolean
在User表中一共有14
条数据,经过查看查询日志,能够看到chunk
分了三次查询 :ui
若是想对一个集合中的每一项都进行一些操做,但不修改集合自己,则可使用each
:
$users = User::all(); $users = $users->each(function ($user , $key) { $user->password = bcrypt(122410); }); // 返回结果包含完整的User模型,其中password 字段的值被修改
若是想对集合中的全部元素进行迭代,对它们进行修改,并返回包含修改的新集合,那么须要使用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();
注意⚠️: