1. 程式人生 > >Laravel 實踐之路: 資料庫遷移與資料填充

Laravel 實踐之路: 資料庫遷移與資料填充

資料庫遷移實際上就是對資料庫庫表的結構變化做版本控制,之前對資料庫庫表結構做修改的方式比較原始,比如說對某張庫表新增了一個欄位,都是直接在庫表中執行alter table xxx add .. 的方式直接修改,但是這麼做有些弊端,比如在開發階段,你自己的庫表修改了,還要把這句sql語句傳給別人再執行一遍,這在多人協同開發時不是一種好的方式.那有沒有一種方式能讓我們對資料庫 庫表的修改做一些簡單的版本控制,同時能讓其他人很方便的同步我們對資料庫的修改呢? 答案是我們可以使用Laravel 內建的Migrations .

對資料庫的管理包括哪些部分?

其實Laravel對資料庫的版本管理主要包括兩部門: 資料庫結構的管理

資料的管理.

  1. 資料庫結構的管理: 主要是對資料庫結構進行管理,比如新增了一張表,某張表增加了一個欄位等等.

  2. 資料的管理: 這個主要是管理表中的資料,生成一些填充資料,解決我們開發除錯時沒有測試資料的問題.

資料庫結構管理

要記錄下我們對資料庫結構所做的更改,我們可以使用Laravel內建 Migrations.

下面我們就走個小例子,看看如果要在資料庫中新增一個庫表具體該怎麼做:

1. 建立一個數據庫

Laravel要和我們的資料庫連線,首先要有個對應的資料庫,你可以在PHPMyAdmin或者navicat for mysql 等管理工具新建一張表:

CREATE DATABASE `laravel5`
;

2. 配置資料庫的連線資訊

我們要使用Laravel管理資料庫,第一步當然是要能連線上資料庫,資料庫的連線配置資訊是放在根目錄下的.env檔案中,這裡我連線的是本地的資料庫:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel5
DB_USERNAME=root
DB_PASSWORD=123456

3. 安裝LaravelMigrations

如果我們是第一次使用Migrations,那就要先執行migrate:install命令來支援資料庫的遷移,進入到專案的根目錄,執行安裝命令:

php artisan migrate:install

這句話執行了以後,Laravel會在資料庫新建一張migrations表,用這張表來記錄我們每次對資料庫做的更改:

4. 建立遷移檔案

以上三步是我們在首次使用Migrations是需要做的,相當於初始化工作,以後每次的更改只需要做下面的工作,好,我們接著往下走.我們的目標是建立一張表,比如說就建立一張商品表goods,首先我們用artisan命令來建立一個對應的遷移檔案:

php artisan make:migration create_goods_table --create=goods

執行資訊如下:

Created Migration: 2017_03_05_214805_create_goods_table

這句話解釋一下, make:migration 是遷移命令,create_goods_table 是遷移檔案的檔名,--create=goods是該命令攜帶的引數,意思是建立一張表,並且表名是goods,這句話執行完畢以後, 我們可以在database\migrations目錄下看到多個一個檔案:

5. 編輯遷移檔案:

我們首先看一下這個檔案的結構,

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateGoodsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('goods', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('goods');
    }
}

解釋一下這個檔案:

該檔案包括兩個函式,updown,up方法是當執行遷移動作時要執行的方法,down方法是在進行資料庫回滾的時候執行的方法,因此updown是一對反方法,up要建立一張表,down就是要刪除一張表,同理,當up中是新增一個欄位時,down方法就是刪除一個欄位了.

我們再來看一下up方法中的內容

Schema::create('goods', function (Blueprint $table) {..}
這裡呼叫Schema操作表的方法來建立表,第二個引數是一個閉包,$table可以用來定義資料庫表的結構:

$table->increments('id');
建立一個自增長的欄位,欄位名預設叫id,當然你也可以改成其他名字.

$table->timestamps();
這裡會在表中建立created_atupdated_at 欄位.

我們所需要的當然不止這麼簡單,下面我們就增加一些我們需要的欄位:

    public function up()
    {
        Schema::create('goods', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('goods_sn'); //商品貨號
            $table->string('goods_name');//商品名
            $table->decimal('prize', 10, 2); //價格
            $table->timestamps();
        });
    }

up方法中新增了三個欄位,關於更多的欄位型別選擇以及欄位修飾,可以去檢視一下文件:資料庫: 遷移
好了,要對資料庫做的更改都定義好了,下面就是真正的執行遷移工作了:

6. 執行遷移:

在執行遷移之前,還需要執行一個命令composer dump-autoload,這個命令的主要作用是讓 composer 更新 autoload_classmap 的內容,包含到我們新建的檔案,具體可參考下這篇文章深入 Composer autoload

composer dump-autoload

然後執行

php artisan migrate

輸出結果為:

然後我們檢視一下資料庫,發現goods 表生成了!

同理,如果你想在這個表中新增一個欄位,可以從第四步到第六步再走一遍,只不過這次不再是建立表,但是流程是一樣的.

7. 資料庫回滾:

有時候我們想撤銷對資料庫做的修改,比如上面新增了一張表,我現在想刪除那張表怎麼辦,這個時候就可以使用migrations的回滾rollback命令:

php artisan migrate:rollback

注意,這個命令並不是回滾所有的migrate操作,而是回滾你上一次的操作,如果你想執行所有的回滾,可以使用reset命令,執行後會按照遷移檔案的時間排序執行所有檔案的down方法;

php artisan migrate:reset

8. 重建整個資料庫

使用refresh命令,可以回滾所有的操作,然後再次執行所有的遷移,實際就是按照時間排序執行所有的down方法,然後再執行所有的up方法;

php artisan migrate:refresh

資料填充

1. 生成Seeder檔案:

現在我們已經建立起了資料庫表的結構,但是現在表中並沒有測試資料,如何製造一些假資料方便我們測試呢?在Laravel中我們可以Seeder+Faker來填充假資料;

假設我們想對goods表填充一些資料.我們第一步要做的工作是先有一個對應於goods表的Seeder檔案,讓我們通過命令生成一個:

php artisan make:seeder GoodsTableSeeder

執行完後會在database\seeds 目錄下看到生成的GoodsTableSeeder檔案:

<?php

use Illuminate\Database\Seeder;

class GoodsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        //
    }
}

可以看到,類中只有一個預設的run方法,這個run方法就是我們執行資料填充的地方.

2. 編輯Seeder檔案:

2.1 簡單的資料填充

我們先嚐試著做一次最簡單的資料填充,直接使用DB類來插入一條資料,編輯run方法:

    public function run()
    {
        DB::table('goods')->insert([
            'goods_sn' => 10001,
            'goods_name' => '加多寶涼茶',
            'prize' => 3.5
        ]);
    }

現在說了半天資料並沒有進入資料庫啊!莫慌,就差最後一步了: 執行seed命令:

php artisan db:seed --class=GoodsTableSeeder

執行完之後,就會發現資料已經填充到資料庫了:

2.2 使用模型工廠進行批量填充

上面我們簡單插入了一條資料,但是明顯不過癮,如果我們想一次插入100條資料,總不能手寫100遍吧,這個問題我們可以使用模型工廠來解決:
當然,使用模型工廠之前,必須要有個對應於goods表的一個Model類,讓我們執行命令生成一個:

php artisan make:model Models\Good

生成的ModelGood:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Good extends Model
{
    //表示對應於表goods
    protected $table = 'goods';
}

模型工廠對應於database\factories中的ModelFactory.php檔案,在這個檔案中,我們新增一段程式碼:

$factory->define(\App\Models\Good::class, function (\Faker\Generator $faker) {
    return [
        'goods_sn' => $faker->numberBetween(10001,20000),
        'goods_name' =>$faker->name, 
        'prize' => $faker->numberBetween(20,50)
    ];
});

define 方法中第一個引數表示關聯Good模型類,第二個引數傳入的是$faker,Faker是一個開源類庫,主要用於生成一些測試資料,比如電話號碼,人名,IP地址等等,這裡Laravel內建了Faker,因此可以直接使用.
在方法中,對應於每個必須的欄位,填充上對應的值;

然後回到GoodsTableSeeder.php檔案,編輯run方法:

    public function run()
    {
        factory(Good::class)->times(10)->create(); //create()表示插入資料庫中
        //factory(Good::class)->times(10)->make(); //make()表示只生成物件,不插入庫表中
    }

這裡呼叫factory方法,times表示要執行的次數.之後執行命令:

php artisan db:seed --class=GoodsTableSeeder

執行完畢之後,就會發現資料表中新增了十條資料.

2.4 單次執行全部seeder

上面的操作雖然可以完成對一張表批量插入多條資料,但是如果我有多個表都要進來批量插入資料,難道要執行多次db:seed xxx,當然不用這樣,database\seeds目錄下有個DatabaseSeeder.php檔案,這個檔案的作用就是對多個seeder進行管理的,在這裡可以呼叫其他的字Seeder類,指定他們的執行順序:

<?php

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        Model::unguard(); //解除模型的批量填充限制
        $this->call(UsersTableSeeder::class);
        $this->call(StatusesTableSeeder::class);
        $this->call(RolesTableSeeder::class);
        $this->call(AdminUsersTableSeeder::class);
        Model::reguard();

    }
}

然後我們再執行seed命令:

php artisan db:seed

這個命令的作用就是執行DatabaseSeeder run方法,因此只需要執行上面的命令,就可執行所有表的填充命令了!

其實還有個最為強大的命令:

php artisan migrate:refresh --seed

這個命令主要做了三件事:

  1. 執行所有的回滾,也就是migrations目錄下所有檔案的down方法,執行的時候按照時間順序.

  2. 所有回滾執行完畢後,執行所有的遷移,也就是按照時間順序執行所有的up方法.

  3. 執行所有的資料填充,也就是執行DatabaseSeeder 中的run方法.如果在run方法中沒有呼叫其他的seeder,則這個seederrun方法不會被執行.

定義路由在web.php中