發布日期:Jun 18, 2021
文章於 Jun 18, 2021 更新
(一)
看到同事用 ->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 判斷式,徒增流程複雜度。
[長知識]
ORM 全名是 Object Relational Mapping ,最實用的好處是可以有效避免 SQL injection 。 也可以將程式碼更加語意化。 參考
觀摩別人的 Eloquent 使用方法 (參考:在 Laravel 7.0 實現 Repository 模式)
Arr::wrap 的使用時機。
應該要完整搞懂 Laravel Eloquent ORM 的規劃與運作。
略
一步一腳印,累積知識,加油!