Laravel 中的數據遷移和數據填充

本文首發於 https://jaychen.cc
做者 JayChenphp

這是一篇基礎教程,對標 Laravel 文檔中的數據遷移數據填充laravel

migration

Laravel 中提供了數據庫遷移的方式來管理數據庫,想象一個場景:在一個多人開發的項目中,你的同事修改了某個數據庫結構並修改了代碼,經過 git 你能夠即時的同步同事修改的代碼,可是數據庫結構,你只能經過手工的方式來複制同事修改的 SQL 語句,執行以保證數據庫的結構一致。那麼,Laravel 中的數據庫遷移概念,就是用於解決團隊中保證數據庫結構一致的方案。git

migration 使用很是簡單,編寫必定的 php 代碼並執行,那麼 Laravel 就會自動的更新數據庫。假設你的同事要修改數據庫某個字段,那麼只要編寫 php 代碼,接着你經過 git 更新了代碼,執行 migrate 操做以後,你的數據庫結構就和他的同步了。下面咱們就來看具體的使用方法。github

migrate

Laravel 把編寫數據庫改動的 php 代碼稱爲遷移,能夠經過 php artisan make:migration filename 的方式來建立遷移文件。假設你須要建立一張新的 user 表,那麼你能夠經過執行 php artisan make:migration create_user_table --create=user 來建立一個遷移文件,執行命令會在 database/migrations/ 目錄下創建一個 文件建立時間_filename 的 php 文件,那麼這個文件就是咱們接下來用來編寫數據庫結構變化的文件了。這裏要提一點,雖說建立遷移文件的名稱能夠隨意,可是爲了管理方便,最好文件名能夠體現要執行的數據庫操做,好比這裏咱們要建立一張 user 表,因此文件名稱爲 create_user_tablesql

php artisan make:migration filename 有兩個可選參數數據庫

  • --create=tablename 代表該遷移是用來建立表。
  • --table=tablename 代表該遷移是用來對 tablename 這張表進行操做。

咱們建立出來的遷移文件 create_user_table 會包含兩個方法。閉包

public function up()
{
    Schema::create('user', function (Blueprint $table) {
        $table->increments('id');
        $table->timestamps();
    });
}


public function down()
{
    Schema::dropIfExists('user');
}

這兩個方法是互逆的操做,好比咱們能夠再 up 方法中編寫咱們要建立的 user 表的相關信息,而 down 方法中則是刪除 user 表的操做。這樣,咱們就能夠作到回滾操做,當咱們建立 user 表以後發現某個字段名寫錯了,就能夠經過 down 來刪除 user 表,進而從新創建 user 表。 函數

假設 user 表有 id,username,email 三個字段,那麼能夠再 up 方法中寫測試

public function up()
{
    Schema::create('user', function (Blueprint $table) {
        $table->increments('id')->index()->comment('用戶id');
        $table->string('name')->default('')->comment('用戶名');
        $table->string('email')->nullable()->comment('用戶郵箱');
        $table->timestamps();
    });
}

通常,咱們的邏輯會在閉包函數中寫。上面的代碼,即時不能徹底明白,也能夠大概猜出如下幾點:this

  • 咱們操做的表是 user 表。
  • user 表中定義了 id 字段,由於調用了 increments 方法,因此 id 爲 auto_increment,調用了 index 方法說明給 id 添加了索引,最後 comment 等同於註釋。
  • 有了 id 的經驗,那麼 name 字段也很好理解了,string 方法說明 name 是 varchar/char 類型的,default 定義了 name 字段的默認值。
  • email 字段 調用了 nullable 方法說明運行 email 字段爲空。
  • 定義字段結構的時候可使用鏈式調用的方式。

Laravel 中的方法是知足你對 sql 語句的全部操做,若是你須要定義一個類型爲 text 的字段,那麼能夠調用 text() 方法,更多的方法說明能夠參見文檔 Laravel 數據庫結構構造器

咱們已經編寫好了 user 表的結構,接下來執行 php artisan migrate,Laravel 會根據 create 方法自動爲咱們建立 user 表。至此,咱們已經成功的經過 Larvel 的遷移功能來實現建立表。

Rollback

使用 Laravel 的遷移功能能夠有後悔藥吃。

執行 php artisan migrate 建立 user 表以後,以爲不行,不要 user 這張表,因而你打算刪除這張表。那麼這時候咱們就要使用剛剛說到的 down 方法了。

public function down()
{
    Schema::dropIfExists('user');
}

這裏 Laarvel 已經爲咱們寫好邏輯了,dropIfExists 函數就是用來刪除表,咱們只須要執行 php artisan migrate :rollback 就能夠回滾到執行 php artisan migrate 以前的狀態。

重命名錶

除了建立表,也能夠用遷移記錄表的其餘任何操做,包括修改表屬性,修改字段等等操做。這裏再舉個例子說明如何用遷移來對錶進行重命名。

  • 假設有表 user,咱們須要對它重命名爲 users。首先要執行 php artisan make:migration rename_user_to_users --table user 來建立遷移文件。
  • up 方法中寫咱們要重命名錶的邏輯。
public function up()
{
    Schema::table('user', function (Blueprint $table) {
        Schema::rename('user','users');
    });
}
  • 爲了能夠 rollback 能夠順利執行,咱們還須要在 down 方法中編寫撤銷重命名操做的邏輯。
public function up()
{
    Schema::table('user', function (Blueprint $table) {
        //
        Schema::rename('users','user');
    });
}
  • 最後執行 php artisan migrate 就就能夠完成對 user 表的重命名操做。若是須要回滾,只要執行 php artisan migrate:rollback

你會發現,若是執行一次遷移以後,若是執行第二次遷移是不會重複執行的,這是由於 Laravel 會在數據庫中創建一張 migrations 的表來記錄哪些已經進行過遷移。

基本的 migration 介紹就到這裏,以上的內容能夠應對大部分的需求,若是須要更詳細的介紹,可能須要閱讀 Laravel 那不知所云的文檔了。:)

Seeder

Laravel 中除了 migration 以外,還有一個 seeder 的東西,這個東西用於作數據填充。假設項目開發中須要有一些測試數據,那麼一樣能夠經過編寫 php 代碼來填充測試數據,那麼經過 git 同步代碼,全部的人均可以擁有一份一樣的測試數據。

一樣,數據填充在 Laravel 中被稱爲 Seeder,若是須要對某張表填充數據,須要先創建一個 seeder。經過執行 php artisan make:seeder UserTableSeeder 來生成一個 seeder 類。這裏咱們但願填充數據的表示 test 表,因此名字爲 UserTableSeeder。固然這個名字不是強制性的,只是爲了作到見名知意。

建立 UserTableSeeder 以後會在 database/seeders 目錄下生成一個 UserTableSeeder 類,這個類只有一個 run 方法。你能夠在 run 方法中寫插入數據庫的代碼。假設咱們使用 DB facade 來向 test 表插入數據。

class UserTableSeeder extends Seeder
{

    public function run()
    {
        DB::table('users')->insert($insertData);
    }
}

編寫完代碼以後,執行 php artsian db:seeder --class= UserTableSeeder 來進行數據填充。執行完畢以後查看數據庫已經有數據了。

若是咱們有多個表要進行數據填充,那麼不可能在編寫完 php 代碼以後,逐個的執行 php artisan db:seeder --class=xxxx 來進行填充。有一個簡便的方法。在 DatabaseSeederrun 方法中添加一行 $this->call(UserTableSeeder::class);,而後執行 php artisan db:seeder,那麼 Laravel 就會執行 DatabaseSeeder 中的 run 方法,而後逐個執行遷移。

和 migration 不一樣,若是屢次執行 php artisan db:seeder 就會進行屢次數據填充。

加入你想一次性插入大量的測試數據 ,那麼在 run 方法中使用 DB facade 來逐個插入顯然不是一個好的方法。Laravel 中提供了一種模型工廠的方式來建立建立大量的數據。

模型工廠

模型工廠,意味着本質實際上是一個工廠模式。那麼,在使用模型工廠建立數據須要作兩件事情

  1. 建立工廠,定義好工廠要返回的數據。
  2. 調用工廠獲取數據。

Laravel 中經過執行 php artisan make:factory UserFactory --model=User 來爲 User Model 建立一個工廠類,該文件會放在 database/factory 目錄下。打開該文件能夠看到以下代碼:

$factory->define(App\User::class, function (Faker $faker) {
    return [
        //
    ];
});

這裏, return 的值就是咱們第 2 步調用工廠獲取到的數據。生成數據的邏輯也只須要寫在閉包函數中就能夠。這裏須要提一下 Faker 這個類。這是一個第三方庫,Laravel 集成了這個第三方庫。這個庫的做用很好玩:用於生成假數據。假設 User 表須要插入 100 個用戶,那麼就須要 100 個 username,那麼你就沒必要本身寫邏輯生成大量的 test01,test02 這樣子幼稚的假數據,直接使用 Faker 類,會替你生成大量逼真的 username。(我也不知道這個算不算無聊了 :)。。。)。

如今假設 User 表有 id, email, username 三個字段,那麼我要生成 100 個用戶,首先在工廠類中實現邏輯。

$factory->define(App\Models\User::class, function (Faker $faker) {
    return [
        // 直接調用 faker API 生成假數據,更多 faker 相關查看 文檔。
        'username' => $faker->name,
        'email' => $faker->unique()->safeEmail,
    ];
});

如今,咱們已經定義好了工廠,如今咱們就要在 UserSeeder@run 函數中使用模型工廠來生成測試數據。

class UserTableSeeder extends Seeder
{

    public function run()
    {
        factory(App\User::class)->times(10)->make()->each(function($user,$index){
            $user->save();
        });
    }
}

run 函數中這一波行雲流水的鏈式調用在我剛剛開始接觸 Laravel 的時候也是一臉黑線,不過習慣以後感受這代碼可讀性確實很強

  • factory(App\User::class) 指明返回哪一個工廠,參數 App\User::class 就是工廠的惟一標識。這裏咱們在定義工廠的時候 define 的第一個參數已經指明瞭。
  • ->times(10) 指明須要工廠模式生成 10 個 User 數據。即會調用 10 次 define 函數的第二個參數。
  • ->make() 把生成的 10 個 User 數據封裝成 Laravel 中的集合對象。
  • ->each() 是 Laravel 集合中的函數,each 函數會針對集合中的每一個元素進行操做。這裏直接把數據保存到數據庫。

好了,數據遷移和數據填充的基本操做也就這些了。更多複雜的用法。。。。也不必定能用上。

相關文章
相關標籤/搜索