前言
1、大纲
写后端API,与数据库打交道无疑是很重要的角色。php
PHP数据库操做:从MySQL原生API到PDOhtml
PHP数据库操做:使用ORMmysql
Ref: [PHP] 07 - Json, XML and MySQLlaravel
2、细节
SQL 教程sql
3、初识 Eloquent ORM
Eloquent ORM是Laravel框架使用的ORM。Laravel 的 Eloquent ORM 提供了更优雅的ActiveRecord 实现来和数据库的互动。每一个数据库表对应一个模型文件。数据库
Goto: Eloquent: 入门【2.完整复习版本】后端
From: Eloquent ORM笔记【1.基础篇】api
新增
# 新建了一条 id, name $user = new User; $user->name = 'John'; $user->save(); $insertedId = $user->id;//从对象取得 id 属性值
使用模型的 Create 方法 class User extends Model { protected $guarded = ['id', 'account_id']; //黑名单,不会被更新
} // 创建一个用户
$user = User::create(['name' => 'John']); // 以属性找用户 - 若没有则新增并取得新的实例...
$user = User::firstOrCreate(['name' => 'John']); // 以属性找用户 - 若没有则创建新的实例...
$user = User::firstOrNew(['name' => 'John']);
辨析
firstOrCreate:判断以后直接入库
firstOrNew :判断以后还要作其余业务流程,以后再入库
$student=Student::firstOrNew([
'vip_name'=>'mmm']);
$student->save();
# 就是须要再单独save一下
删除 $this->where($where)->delete(); 或者 $user = User::find(1); $user->delete();
更新 return $this->where($where)->update($data); 或者 $user = User::find(1); $user->update($data);
查找 //取出全部记录 - 能够遍历
$this->all()->toArray(); //取出一条数据
$one = $this->find('2'); return array( $one->id,
$one->title,
$one->content, ); //查找id=2的第一条数据
$this->where('id', 2)->first()->toArray(); //查找id>0的全部数据
$this->where('id', '>', '0')->get()->toArray();
- For
find(n)
, you retrieve a row based on the primary key which is 'n'.
- For
first()
, you retrieve the first row among all rows that fit the where clauses.
- For
get()
, you retrieve all the rows that fit the where clauses. (Please note that loops are required to access all the rows or you will get some errors).
//降序排列
$this->where('id', '>', '0')->orderBy('id', 'desc')->get()->toArray(); //降序排列,计数
$this->where('id', '>', '0')->orderBy('id', 'desc')->count(); //从offset起始算起的limit条数据
$this->where('id', '>', '0')->orderBy($order[0], $order[1])->skip($offset)->take($limit); //等同于
$this->where('id', '>', '0')->orderBy($order[0], $order[1])->offset($offset)->limit($limit);
条件类 //条件类 where('id', '>', '0') where('id', '>=', '0') where('id', '<', '0') where('id', '<=', '0') where('id', 'like', 'name%') whereIn($key, $array) whereNotIn($key, $array) whereBetween($key, $array) whereNotBetween($key, $array) orWhereIn($key, $array) orWhereNotIn($key, $array) orWhereBetween($key, $array) orWhereNotBetween($key, $array)
结果方法 //结果方法:Illuminate\Database\Query\Builder first()取第一个 get()取全部 all()取全部(无条件)
数学统计 //聚合方法
count() avg() sum() max() min()
Pure SQL
RDBMS 指关系型数据库管理系统,全称 Relational Database Management System。数组
(1). 登陆:mysql -u root -p 闭包
(2). phpMyAdmin建立数据库,并导入.sql文件。
(3). 支持中文:set names utf8;
详见:[MySQL] 01- Basic sql
Eloquent: 入门
{tip} 因为 Eloquent 模型是查询构造器,所以你应当去阅读全部 查询构造器 中可用的方法。
1、模型
php artisan make:model User --migration php artisan make:model User -m
<?php
namespace App;
use Illuminate\Database\Eloquent\Model; # 全部的 Eloquent 模型都继承自这个 class Flight extends Model
{
// 用它从 数据表中取回与保存信息
}flights
[1] 表名
除非数据代表确地指定了其它名称,不然将使用类的「蛇形名称」、复数形式名称来做为数据表的名称。自定义对应表名:
protected $table = 'my_flights';
[2] 主键
设每一个数据表都有一个叫作 id
的主键字段。你也能够定义一个 $primaryKey
属性来重写这个约定。
默认是递增;不然,必须在你的模型 public $incrementing=
false
。
[3] 时间戳
默认状况下,Eloquent 会认为在你的数据库表有 created_at
和 updated_at
字段。
若是你不但愿让 Eloquent 来自动维护这两个字段,可在模型内将 $timestamps=
false。
决定了日期应如何在数据库中存储,以及当模型被序列化成数组或 JSON 格式 protected $dateFormat = 'U';
[4] 链接数据库
默认状况下,全部的 Eloquent 模型会使用应用程序中默认的数据库链接设置。
若是你想为模型指定不一样的链接,可使用 protected $connection = 'connection-name';
[5] 经过模型获取结果
$flights = App\Flight::where('active', 1) ->orderBy('name', 'desc') ->take(10) ->get();
详见:"3、初识 Eloquent ORM"
补充:软删除
模型上设置一个 deleted_at
属性并将其添加到数据库。若是模型有一个非空值 deleted_at
,表明模型已经被软删除了。
[1] 设置字段
当模型被软删除时,它们并不会真的从数据库中被移除。而是会在模型上设置一个 deleted_at
属性并将其添加到数据库。
若是模型有一个非空值 deleted_at
,表明模型已经被软删除了。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Flight extends Model
{
use SoftDeletes;
/**
* 须要被转换成日期的属性。
* 添加 字段到你的 属性。
*
* @var array
*/
protected $dates = ['deleted_at'];
}deleted_at$dates
[2] 添加 deleted_at
字段到数据表
Schema::table('flights', function ($table) { $table->softDeletes(); });
当查询有启用软删除的模型时,被软删除的模型将会自动从全部查询结果中排除。
[3] 查询 deleted_at 字段
确认指定的模型实例是否已经被软删除,可使用 trashed
方法:
if ($flight->trashed()) { // }
[4] 查询捎带上 '软删除‘ 集合
$flights = App\Flight::withTrashed() ->where('account_id', 1) ->get();
[5] 只查询 ‘软删除’ 集合
$flights = App\Flight::onlyTrashed() ->where('airline_id', 1) ->get();
[6] 恢复 '软删除'
$flight->restore(); App\Flight::withTrashed() ->where('airline_id', 1) ->restore();
[7] 永久地删除模型
// 强制删除单个模型实例...
$flight->forceDelete(); // 强制删除全部相关模型...
$flight->history()->forceDelete();
2、集合
Collection
类提供 多种辅助函数 来处理你的 Eloquent 结果。
[Chunk]
It will "paginate" your query, this way you use less memory. (1) Uses less memory (2) It takes longer
public function getData() { Contact::chunk(1000, function ($contacts) { foreach ($contacts as $contact) { //rest of your code...
} }); }
[Cursor]
You will use PHP Generators to search your query items one by one. (1) It takes less time (2) Uses more memory
public function getData() { foreach (Contact::cursor() as $contact) { //rest of your code...
} }
// 取回符合查询限制的第一个模型 ...
$flight = App\Flight::where('active', 1)->first(); $flights = App\Flight::find([1, 2, 3]);
$model = App\Flight::findOrFail(1); $model = App\Flight::where('legs', '>', 100)->firstOrFail();
// 用法示范 Route::get('/api/flights/{id}', function ($id) {
return App\Flight::findOrFail($id);
});
可使用 count
、sum
、max
,和其它 查询构造器 提供的 聚合函数。
这些方法会返回适当的标量值,而不是一个完整的模型实例
$count = App\Flight::where('active', 1)->count(); $max = App\Flight::where('active', 1)->max('price');
3、控制器
自动完成了例如对时间戳的记录。
<?php namespace App\Http\Controllers; use App\Flight; use Illuminate\Http\Request; use App\Http\Controllers\Controller; class FlightController extends Controller { /** * 建立一个新的航班实例。 * * @param Request $request * @return Response */
public function store(Request $request) {
$flight = new Flight;
$flight->name = $request->name; $flight->save(); } }
$flight = App\Flight::find(1); $flight->name = 'New Flight Name'; $flight->save();
两个where并列条件,而后更新字段:delayed
App\Flight::where('active', 1) ->where('destination', 'San Diego') ->update(['delayed' => 1]);
{note} 当经过“Eloquent”批量更新时,saved
和updated
模型事件将不会被更新后的模型代替。这是由于批量更新时,模型历来没有被取回。
注意:批量赋值是有风险的,全部的 Eloquent 模型都针对批量赋值(Mass-Assignment)作了保护。
方案:$fillable
做为一个能够被批量赋值的属性「白名单」;$guarded 是「黑名单」,设置为空表明大门敞开。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* 能够被批量赋值的属性。
* 使 模型的 属性能够被批量赋值
*
* @var array
*/
protected $fillable = ['name'];
}Flightname
赋值:
$flight = App\Flight::create(['name' => 'Flight 10']); $flight->fill(['name' => 'Flight 22']);
4、查询做用域
自定义全局做用域很简单,首先定义一个实现 Illuminate\Database\Eloquent\Scope
接口的类,该接口要求你实现一个方法:apply
。
<?php namespace App\Scopes; use Illuminate\Database\Eloquent\Scope; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Builder; class AgeScope implements Scope { /** * 应用做用域 * * @param \Illuminate\Database\Eloquent\Builder $builder * @param \Illuminate\Database\Eloquent\Model $model * @return void */
public function apply(Builder $builder, Model $model) { return $builder->where('age', '>', 200); # select * from `users` where `age` > 200 } }
{tip} Laravel 没有规定你须要把这些类放置于哪一个文件夹,你能够自由在 app
文件夹下建立 Scopes
文件夹来存放。
<?php
namespace App;
use App\Scopes\AgeScope;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* 数据模型的启动方法
*
* @return void
*/
protected static function boot() # 须要重写给定模型的 boot 方法
{
parent::boot();
static::addGlobalScope(new AgeScope); # 并使用 方法
}
}addGlobalScope
添加做用域后,若是使用 User::all()
查询则会生成以下SQL语句:select * from `users` where `age` > 200
Eloquent 还容许咱们使用闭包定义全局做用域,这在实现简单做用域的时候特别有用,这样的话,咱们就不必定义一个单独的类。
<?php namespace App; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Builder; class User extends Model { /** * 数据模型的启动方法 * * @return void */
protected static function boot() { parent::boot(); static::addGlobalScope('age', function(Builder $builder) { $builder->where('age', '>', 200); }); } }
User::withoutGlobalScope('age')->get(); User::withoutGlobalScope(AgeScope::class)->get(); // 移除多个
User::withoutGlobalScopes([FirstScope::class, SecondScope::class])->get();
本地做用域容许咱们定义通用的约束集合以便在应用中复用。
例如,你可能常常须要获取最受欢迎的用户,要定义这样的一个做用域,只需在对应 Eloquent 模型方法前加上一个 scope
前缀,做用域老是返回查询构建器:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { /** * 限制查询只包括受欢迎的用户。 * * @return \Illuminate\Database\Eloquent\Builder */
public function scopePopular($query) { return $query->where('votes', '>', 100); } /** * 限制查询只包括活跃的用户。 * * @return \Illuminate\Database\Eloquent\Builder */
public function scopeActive($query) { return $query->where('active', 1); } }
Then, 利用查询范围
一旦定义了范围,则能够在查询模型时调用范围方法。在进行方法调用时不须要加上 scope
前缀。你甚至能够链式调用不一样的范围,如:
$users = App\User::popular()->active()->orderBy('created_at')->get();
定义一个可接受参数的范围。
这时只需给你的范围加上额外的参数便可。范围参数应该被定义在 $query
参数以后:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { /** * 限制查询只包括指定类型的用户。 * * @return \Illuminate\Database\Eloquent\Builder */
public function scopeOfType($query, $type) { return $query->where('type', $type); } }
在范围调用时传递参数:
$users = App\User::ofType('admin')->get();
5、事件
事件让你每当有特定的模型类在数据库保存或更新时,执行代码。
Eloquent 模型会触发许多事件,让你在模型的生命周期的多个时间点进行监控:creating
, created
, updating
, updated
, saving
, saved
, deleting
, deleted
, restoring
, restored。
举例子:
当一个新模型被初次保存将会触发 creating
以及 created
事件。
若是一个模型已经存在于数据库且调用了 save
方法,将会触发 updating
和 updated
事件。
在这两种状况下都会触发 saving
和 saved
事件。
<?php namespace App; use App\Events\UserSaved; use App\Events\UserDeleted; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable { use Notifiable; /** * 模型的事件映射。 * * @var array */
protected $events = [ 'saved' => UserSaved::class,
'deleted' => UserDeleted::class, ]; }
若是你在一个给定的模型中监听许多事件,您可使用观察者将全部监听器变成一个类。
观察者类里的方法名应该反映Eloquent想监听的事件。 每种方法接收 model 做为其惟一的参数。
Laravel不包括观察者默认目录,因此你能够建立任何你喜欢你的目录来存放:
<?php namespace App\Observers; use App\User; class UserObserver { /** * 监听用户建立的事件。 * * @param User $user * @return void */
public function created(User $user) { // } /** * 监听用户删除事件。 * * @param User $user * @return void */
public function deleting(User $user) { // } }
在AppServiceProvider
注册观察者
<?php namespace App\Providers; use App\User; use App\Observers\UserObserver; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { /** * 运行全部应用. * * @return void */
public function boot() { User::observe(UserObserver::class); } /** * 注册服务提供. * * @return void */
public function register() { // } }
Ref: Laravel 数据库之:数据库请求构建器【往后继续补充】