Laravel筆記--Eloquent 模型


Eloquent 模型

默認繼承use Illuminate\Database\Eloquent\Model類。

 

數據表名稱與模型名稱約定:

數據庫的表名一般使用“蛇形命名法”命名。蛇形命名法要求單詞小寫,單詞之間用_下划線連接,且名稱是復數。

與之對應的模型名稱,則使用“帕斯卡法“命名,即單詞頭一字母都大寫。

如果不是按以上約定,則需指明對應的數據表:

class Flight extends Model
{
    /**
     * 與模型關聯的數據表
     *
     * @var string
     */
    protected $table = 'myflights';
}

 

主鍵:

模型默認數據表用id字段作主鍵,並且是遞增整數類型。這些可以自定義:

class Flight extends Model
{
    /**
     * 與模型關聯的數據表
     */
    protected $table = 'my_flights';

    protected $primaryKey='mid';  //自定義主鍵字段
    
    protected $keyType = 'string';  //自定義主鍵類型為字串
    
    public $incrementing = false;    //主鍵非自增型
}

 

 

時間截:

模型默認存在created_at 和 updated_at兩字段,可設定$timestamps不需兩字段:

class Flight extends Model
{
    /**
     * 該模型是否被自動維護時間戳
     */
    public $timestamps = false;
}

 

$dateFormat屬性可自定義時間截格式存儲在數據表的格式:

class Flight extends Model
{
    /**
     * 模型的日期字段的存儲格式
     */
    protected $dateFormat = 'U';
}

 

自定義時間截字段名:

<?php

class Flight extends Model
{
    const CREATED_AT = 'creation_date';
    const UPDATED_AT = 'last_update';
}

 

 

自定義數據庫連接:

class Flight extends Model
{
    /**
     * 此模型的連接名稱。
     */
    protected $connection = 'connection-name';
}

 

 

模型查詢:

use App\Flight;

$flights = App\Flight::all();   //查詢所有數據

foreach ($flights as $flight) {
    echo $flight->name;
}

$flights = App\Flight::where('active', 1)
               ->orderBy('name', 'desc')
               ->take(10)
               ->get();             //有條件地查詢數據

 

 all和get方法返回 Illuminate\Database\Eloquent\Collection實例。

 

如果查詢大批量數據,可使用chunk,可節省內存:

Flight::chunk(200, function ($flights) {
    foreach ($flights as $flight) {
        //
    }
});

 

或使用游標方法cursor大幅度減少內存的使用:

foreach (Flight::where('foo', 'bar')->cursor() as $flight) {
    //
}

 

 

查詢單條數據:

// 通過主鍵取回一個模型...
$flight = App\Flight::find(1);

// 取回符合查詢限制的第一個模型 ...
$flight = App\Flight::where('active', 1)->first();

//如果找不到模型則拋出異常
//Illuminate\Database\Eloquent\ModelNotFoundException
//自動返回 HTTP 404 響應給用戶
$model = App\Flight::where('legs', '>', 100)->firstOrFail();

 

 

聚合查詢:

$count = App\Flight::where('active', 1)->count();

$max = App\Flight::where('active', 1)->max('price');

 

 

數據更新:

save方法:需要先檢索一次,再設置要更新的屬性再執行save方法,同時updated_at也會自動更新。

update方法:設置where條件,將更新字段以鍵值對傳入update方法。該更新不會觸發saved和updated模型事件。

$flight = App\Flight::find(1);
$flight->name = 'New Flight Name';
$flight->save(); //查詢一次后再更新


App\Flight::where('active', 1)
          ->where('destination', 'San Diego')
          ->update(['delayed' => 1]); //設置條件后再批量更新

 

 

插入數據:

使用模型創建數據,需先設置$fillable或$guarded屬性。兩屬性只能二選一。

class Flight extends Model
{
    /**
     * 可以被批量賦值的屬性。
     * @var array
     */
    protected $fillable = ['name'];
}

class Flight extends Model
{
    /**
     * 不可被批量賦值的屬性。可定義為空數組,表示所有屬性都可以賦值。
     * @var array
     */
    protected $guarded = ['price'];
}

 

插入數據的方法:

$flight = App\Flight::create(['name' => 'Flight 10']); //添加新記錄並返回已保存的模型實例

$flight->fill(['name' => 'Flight 22']); //已有實例模型可使用fill方法

 

// 通過 name 屬性檢索航班,當結果不存在時創建它...
$flight = App\Flight::firstOrCreate(['name' => 'Flight 10']);

// 通過 name 屬性檢索航班,當結果不存在的時候用 name 屬性和 delayed 屬性去創建它
$flight = App\Flight::firstOrCreate(
    ['name' => 'Flight 10'], ['delayed' => 1]
);

// 通過 name 屬性檢索航班,當結果不存在時實例化...
$flight = App\Flight::firstOrNew(['name' => 'Flight 10']);
// 通過 name 屬性檢索航班,當結果不存在的時候用 name 屬性和 delayed 屬性實例化
$flight = App\Flight::firstOrNew(
    ['name' => 'Flight 10'], ['delayed' => 1]
);

// 如果有從奧克蘭飛往聖地亞哥的航班,將價格設為 99 美元
// 如果不存在匹配的模型就創建一個
$flight = App\Flight::updateOrCreate(
    ['departure' => 'Oakland', 'destination' => 'San Diego'],
    ['price' => 99]
);

firstOrCreate:如果查不到該數據,則根據第一參數和第二參數記錄創建記錄返回保存的模型;

firstOrNew:如果查不到該數據,則根據第一參數和第二參數記錄創建新模型,但並未保存數據,需要手動save才可以保存數據;

updateOrCreate:根據第一參數作條件用更新第二參數數據,如果數據不存在則合並兩參數創建記錄返回保存的模型。

 

刪除模型:

$flight = App\Flight::find(1);
$flight->delete();  //通過查詢所得的模型實例進行delete方法刪除

//通過主鍵刪除一至多條數據:
App\Flight::destroy(1);
App\Flight::destroy([1, 2, 3]);
App\Flight::destroy(1, 2, 3);

//通過查詢條件批量刪除,並返回刪除條數
$deletedRows = App\Flight::where('active', 0)->delete();

批量刪除時,deleted和deleting模型事件不會被觸發。

 

 軟刪除:

數據表應設置deleted_at字段。模型內引用SoftDeletes trait,並設置deleted_at字段到$dates屬性上。

<?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']; 
}

 

設置了軟刪除的模型,在delete方法會設置deleted_at為當前日期和時間。查詢軟刪除的模型會自動排除被軟刪除的模型。

if ($flight->trashed()) {
    //檢查該模型實例是否被軟刪除
}

$flights = App\Flight::withTrashed()  //能使用查詢包含軟刪除的數據
                ->where('account_id', 1)
                ->get();

$flights = App\Flight::onlyTrashed()  //只查詢軟刪除的數據
                ->where('airline_id', 1)
                ->get();

$flight->restore();  //恢復被軟刪除的模型

App\Flight::withTrashed()   //批量恢復模型,不會觸發任何模型事件
        ->where('airline_id', 1)
        ->restore();

 

 

軟刪除模型使用強制刪除:

$flight->forceDelete();

 

查詢作用域:

給模型添加查詢約束。分全局和本地兩種:

全局--每個查詢都自動加條件約束;

本地--根據需要調用本地約束。

 

全局作用域:

首先需實現scope接口類.

<?php

namespace App\Scopes;

use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

class AgeScope implements Scope
{
    /**
     * 將范圍應用於給定的 Eloquent 查詢生成器
     *
     * @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 語句中,則應該使用 addSelect 方法而不是 select,以免替換查詢的現有select。

應用全局作用域:

在模型的boot方法使用addGlobalScope方法。

<?php

namespace App;

use App\Scopes\AgeScope;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * 模型的「啟動」方法
     *
     * @return void
     */
    protected static function boot()
    {
        parent::boot();

        static::addGlobalScope(new AgeScope);
    }
}

 

 

也可以使用閉包定義全局作用域,不必單獨定義一個類:

class User extends Model
{
    /**
     * 模型的「啟動」方法
     *
     * @return void
     */
    protected static function boot()
    {
        parent::boot();

        static::addGlobalScope('age', function(Builder $builder) {
            $builder->where('age', '>', 200);
        });
    }
}

 

 

刪除全局作用域:

User::withoutGlobalScope(AgeScope::class)->get();  //刪除指定的作用域

// 刪除所有的全局作用域
User::withoutGlobalScopes()->get();

// 刪除一些全局作用域
User::withoutGlobalScopes([
    FirstScope::class, SecondScope::class
])->get();

 

 

本地作用域:

定義通用的約束在需要時使用。定義方法:在模型內定義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);
    }
}

 

使用方法:

$users = App\User::popular()->active()->orderBy('created_at')->get();

 

動態作用域:

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();

 

 

模型事件:

retrieved --查詢觸發

creatingcreated--創建觸發

updatingupdated--更新觸發

savingsaved--創建、更新觸發

deletingdeleted--刪除觸發

restoringrestored--恢復觸發

 

事件指派相應的監控器:

<?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 $dispatchesEvents = [
        'saved' => UserSaved::class,   //觸發saved事件,調用UserSaved監控器
        'deleted' => UserDeleted::class, //觸發deleted事件,調用UserDeleted監控器
    ];
}

 

 

也可所有監聽放在一個觀察器類中:

<?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)
    {
        //
    }
}

 

注冊觀察器:

<?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);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM