iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 26
0
Software Development

新手後端工程師的學習歷程系列 第 26

Day 26 - Laravel Database 篇 part I

tags: 2019鐵人賽 Laravel database

前言

之前有提到,Laravel 是一個非常遵守 MVC 設計模式的 PHP 開發框架,所以他在 Model 的設計也非常有趣,我這邊只整理幾個重點觀念,如果要查看細部使用方法,我真心覺得看官方文件就好。Laravel 的官方文件寫得非常詳盡,如果要論缺點的話,大概是範例不夠親民,每次都只說明 code 怎麼寫,沒有一個情境範例,不能讓人一目瞭然知道這功能就是為了這種情境設計出來的。

好了,廢話又太多了!因為這裡的 Model 資料來源主要是串接資料庫,所以 Model 的設計大多與資料庫訪查有關,而 Laravel 又分成三個部分:

  1. 原生 SQL 查詢
  2. 查詢建構器
  3. Eloquent ORM

今天就要先講「原生 SQL 查詢」。

原生 SQL 查詢

如果資料庫設定完成,接著用 DB::connection('資料庫類型') 連線後,就可以使用 DB facade 進行查詢。DB facade 提供每個類型的查詢方法:selectupdateinsertdeletestatement

基本使用方法

// 連線到資料庫
DB::connection('mysql');

//select
$users = DB::select('select * from users where active = ?', [1]);
//insert
DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']);
//update
$affected = DB::update('update users set votes = 100 where name = ?', ['John']);
//delete,後面一樣可以接 where 語句設定條件
$deleted = DB::delete('delete from users where id = ?', [1]);
//一般陳述式
DB::statement('drop table users');

可以注意到的是

  1. 這些方法都有兩個可以參數帶入

    • 第一個是資料庫訪查語句(型別是字串),第二個是訪查參數(型別是數字或字串的陣列)。
    • 訪查語句有幾個「?」,訪查參數就要放幾個參數,而且是依序對應到前面的「?」。
  2. select、update、delete 會有一個回傳值

    • select 回傳資料庫內容,以「陣列」的形式存放。
    • updata、delete 回傳資料庫受影響的行數。

這邊特別提一下,select 查詢出來的結果,都是以陣列方式存放,而裡面每筆資料都是一個 PHP stdClass 的物件。

1. 由於取出來的資料是陣列,所以如果從資料庫撈出來的資料想再作處理,就要比照陣列的處理模式,例如 foreachwhile ...

2. 由於每筆資料都是 stdClass,所以可以把存取的欄位當作物件的一個屬性來存取每個欄位的值

// 連線到資料庫
DB::connection('mysql');

//select
$users = DB::select('select * from users where active = ?', [1]);

foreach ($users as $user) {
    echo $user->name;
}

監聽查詢事件

Laravel 5.1之後取消了 getQueryLog(),取而代之的是DB::listen()

但是呢,官方文件只提到怎麼寫,但沒提怎麼用...

我這裡舉個例子:存在 Log file。

  1. import use Illuminate\Support\Facades\Log;
  2. 透過 Log::info() 把記錄存在 Log file(路徑:/storage/logs)
<?php

namespace App\Providers;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * 啟動任何應用程式服務。
     *
     * @return void
     */
    public function boot()
    {
        DB::listen(function ($query) {
            Log::info($query->sql);
            // $query->bindings
            // $query->time
        });
    }
}

Database Transactions

在資料存取資料庫時,最怕出了什麼差錯,導致資料處理不連續,最終導致資料錯亂。這如同銀行轉賬,如果轉出帳戶扣款了,但是轉入帳戶發生意外沒寫入資料庫,那麼這次轉賬就宣告失敗,轉出帳戶的金額要復原。

為了避免 sql 原生語法有 transaction 的機制,整個程序中一但有一步資料沒處理好,就整個程序都取消,過程中已經執行過的動作全部復原!

在 Laravel 中更簡便了這個動作,呼叫 transaction() 將資料庫查訪動作寫在閉包裡面,一但閉包成功,就完成程序;閉包失敗,就自動還原資料庫。不用再特地手動提交或還原了。

使用方法如下

DB::transaction(function () {
    DB::table('users')->update(['votes' => 1]);

    DB::table('posts')->delete();
});

上一篇
Day 25 - Laravel Validation 篇
下一篇
Day 27 - Laravel Database 篇 part II
系列文
新手後端工程師的學習歷程30

尚未有邦友留言

立即登入留言