發布日期:Jun 18, 2021

文章於 Jun 18, 2021 更新

20210618

事件紀錄

(一)

看到同事用 ->addBinding($LaravelEloquentObject->getBindings()) 取代原本的寫法 ->mergeBindings($LaravelEloquentObject->getQuery())

想知道差異在哪裡?待查。

(二)

疑問:

在不需要關聯別的表、也沒有 subquery 出其他別名的情況下,還需要特地指定是拿哪個表的欄位嗎?

原始SQL概念

    SELECT
        employee.id
    FROM
        employee

Laravel Eloquent ORM 寫法

## parent:
/**
    * 建立資料
    * @param array $entity_data
    * @return |null
    */
public function createEntity(array $entity_data)
{
    $Entity = null;
    if ($this->Entity instanceof Model) {
        $Entity = $this->Entity->create($entity_data);
    }
    return $Entity;
}

## main
public function __construct()
{
    $this->Employee = app()->make(Employee::class);
    $this->employee_table_name = $this->Employee->getTable();
    parent::__construct();
}

public function getCompanyEmployeeCount()
{
    // 資料表名稱
    $employee_table_name = $this->employee_table_name;

    // 自訂欄位
    $custom_select_field = [
        "{$employee_table_name}.id",
    ];
    $EmployeeCountSubQuery = $this->Employee
        ->select($custom_select_field)
        ->where('company_id', $company_id);

    // 將原本撈取邏輯當作子查詢計算數量
    // https://stackoverflow.com/questions/24823915/how-to-select-from-subquery-using-laravel-query-builder
    $employee_count = DB::table( DB::raw("({$EmployeeCountSubQuery->toSql()}) as sub") )
        ->mergeBindings($EmployeeCountSubQuery->getQuery()) // you need to get underlying Query Builder
        ->count();

    return $employee_count;
}

解說:

指定不指定都可以,但先指定可以避免之後有關聯出錯,就弄得比較完整一點,避免之後還要一一修改。

因為 id 出現在很多表裡面,為了節省看程式的時候的時間,寫清楚一點比較方便。 萬一之後有需求要 join ,這段就可以重複使用。

(三)

LengthAwarePaginator 與 Paginator 的差異,目前只知道是否強制傳入總頁數。待驗證。 https://laravel.tw/docs/5.2/pagination

(四)

Arr::wrap

雖然 wrap 可以把傳入的字串變數之類的打包成陣列,但是是在「傳入值不明確,想整理型別」時使用。

如果當下傳入值已經很明確,直接 Assign 陣列就好:

$a = [];
$a = ["xxx"];

除非是擔心傳入的值可能為陣列,用 wrap 的話傳入的值是陣列就會原封不動的輸出。

但這邊取值時就已經明確知道不是陣列,此時直接打包就好。 否則進到 wrap 裡面還有 if 判斷式,徒增流程複雜度。

總結

1. 工作技能有沒有因此成長了?

[長知識]

  1. ORM 全名是 Object Relational Mapping ,最實用的好處是可以有效避免 SQL injection 。 也可以將程式碼更加語意化。 參考

  2. 觀摩別人的 Eloquent 使用方法 (參考:在 Laravel 7.0 實現 Repository 模式)

  3. Arr::wrap 的使用時機。

2. 計畫如何改善現況或者可以試著做得更好?

應該要完整搞懂 Laravel Eloquent ORM 的規劃與運作。

3. 如何在這件事上提升效率?

4. 有沒有把時間花在刀口上?

一步一腳印,累積知識,加油!

關鍵字

  • addBinding()
  • Laravel Eloquent ORM
  • LengthAwarePaginator
  • Arr::wrap