658 views
# Using Database in Laravel ###### tags: `MCL` `web` References ~ * https://laravel.com/docs/5.8/migrations * https://laravel.com/docs/5.8/seeding * https://laravel.com/docs/5.8/eloquent 這篇的範例情境是值班打卡紀錄 `check_records`。 ## Laravel 上的遷移表 基本上建立遷移表有三種方式: 1. 自己加檔案 2. 直接透過指令建立遷移表 3. :crown: 建立 ORM 的同時順便建立遷移表 ### 建立 ORM 的同時順便建立遷移表 ORM (物件關聯對映, Object Relational Mapping) 的功能是實現程式語言當中與各種類型資料的互動。 在 Laravel 建立 ORM 的指令如下: ```php php artisan make:model [駝峰式資料表名稱 (單數)] -m ``` ```php php artisan make:model CheckRecord -m ``` 後面 `-m` 的意思就是建立 ORM 的同時也會建立對應的遷移表。 而這樣的動作會產生兩個檔案: - 物件檔案:`app/CheckRecord.php` - 遷移檔案:`database/migrations/xxxx_xx_xx_xxxxxx_create_check_records_table.php` ### [Optional] 直接透過指令建立遷移表 複習一下,上周我們使用 `migrate` 指令遷移預設遷移表到資料庫系統去。這次我們會練習建立自己的遷移表,並且使用同樣的方式建立自己的資料表。 建立遷移表的指令如下: ```bash php artisan make:migration create_[蛇底式資料表名稱 (複數)]_table ``` 此時他就會在 `database/migrations` 下建立一個對應於資料表名稱的遷移表。 > 1. 資料表名稱通常為**複數** > 2. 如果是多名詞想要區隔的話,會使用底線 `_` (snake_case naming style) 根據這次的範例情境,我們的指令如下: ```bash php artisan make:migration create_check_records_table ``` ### 編輯遷移表 此時你會在 `database/migrations` 中看到對應的 `.php` 檔。他的內容會長得像下面這個樣子: ```php= <?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateCheckRecordsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('check_records', function (Blueprint $table) { $table->bigIncrements('id'); // 相當於 index 的東西 /** * 這邊可以加你想要增加的欄位 */ $table->timestamps(); // 時戳 (建立時間、更新時間) }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('check_records'); } } ``` 思考一下我們需要的欄位以及他對應的型態: | 欄位名稱 | 型態 | 備註 | | ---------- | --------------- | --------------------------------------------------- | | id | bigIncrements | 系統會自動記數 (視為這筆資料的唯一識別碼,很重要!!) | | user_id | unsignedInteger | 對應使用者 index | | check_time | dateTime | 這個有到秒哦 | | comment | string | 如果想儲存換行要使用 `text` | > 更多欄位型態可以查 Laravel 官方列舉的清單: > https://laravel.com/docs/5.8/migrations#columns 接著把這個型態轉換成程式碼,放到剛剛生成的遷移表: ```php <?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateCheckRecordsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('check_records', function (Blueprint $table) { $table->bigIncrements('id'); // 相當於 index 的東西 $table->unsignedInteger('user_id'); $table->dateTime('check_time'); $table->string('comment'); $table->timestamps(); // 時戳 (建立時間、更新時間) }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('check_records'); } } ``` 放好之後我們就可以嘗試遷移到 SQL Server 了,同樣的指令: ```bash php artisan migrate ``` 遷移指令成功的話,你就可以看到你寫的資料表就出現在資料庫上面了。 ### 透過 `seeder` 建立種子資料 (或者說是假資料) 你可能會需要事先在資料表中先填入一些資料,通常這件事情有這幾種發生可能: 1. 有些功能需要在有資料的前提下才能運作,不然會報錯 2. 基於開發需求,預先寫好一些測試資料方便使用 同樣也可以透過 `artisan` 建立 `seeder` : ```bash php artisan make:seeder CheckRecordsTableSeeder ``` 建立好後他 `database/seeds/CheckRecordsTableSeeder.php` 會是一個沒有實際程式碼的檔案,這時候我們可以加上個人指令去新增資料列: ```php <?php use Illuminate\Database\Seeder; use Illuminate\Support\Facades\DB; // 記得要加 class CheckRecordsTableSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { DB::table('check_records')->insert([ 'user_id' => 1, 'check_time' => '2020-05-07 21:00', 'comment' => '安安', 'created_at' => '2020-05-07 21:00', 'updated_at' => '2020-05-07 21:00' ]); } } ``` 完成之後換到同目錄下的 `DatabaseSeeder.php`,將目前的 seeder class 加進去: ```php <?php use Illuminate\Database\Seeder; class DatabaseSeeder extends Seeder { /** * Seed the application's database. * * @return void */ public function run() { $this->call([ CheckRecordsTableSeeder::class ]); } } ``` #### 執行 ```bash php artisan db:seed ``` ### 常用的 `migrate` 指令 - 清空資料庫 `php artisan migrate:reset` - 刷新資料庫 `php artisan migrate:refresh` (相當於清空 + 遷移) - 遷移時附帶種子資料 `php artisan migrate --seed` ## 使用 ORM 在 controller 前面加上 `use App\CheckRecord;`,即可對此資料表進行操作,以下是實現查詢功能的範例: * `routes/web.php` ```php <?php Route::group(['middleware' => 'auth'], function () { Route::get('/check', 'DateController@getCheckRecords'); Route::get('/add', 'DateController@addCheckRecord'); }); ``` * `app/Http/Controllers/DateController.php` ```php <?php namespace App\Http\Controllers; use Auth; use App\CheckRecord; use Illuminate\Http\Request; class DateController extends Controller { public function getCheckRecords(Request $request) { $data = CheckRecord::whereUserId(Auth::user()->id)->get(); return $data; } public function addCheckRecord(Request $request) { $checkRecord = new CheckRecord; $checkRecord->user_id = Auth::user()->id; $checkRecord->check_time = now(); $checkRecord->comment = $request->get('comment'); $checkRecord->save(); return redirect('/check'); } } ```