前言
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 數據庫之:數據庫請求構建器【往後繼續補充】