抱歉啦!這次的更新比較久了。有點太混。
上一次是在說ORM的觀念篇。
這次就來說說基本應用篇處理。
就如上一篇說的,其實ORM本身是一種資料容器。
所以Model認真來說,就是一種架構的規劃設計。
這邊就先來說說ORM的主要規劃
這裏來一一說明一些常用的變數
就正常來說,如都是用預設值的情況下。只需要設定 fillable 這個變數即可。
等表基本都定義好後,再來就是要準備定義關聯了
這邊就先從比較單純1對1及1對多來說明
這裏就先準備好三張表
這裏說明一下。
我規劃了一個帳號用的表,另外將會員的資料另外放在另一張子表上。
所以這兩張表之前的關聯為 1對1 的模式。 User(1)<->(1)UserInfo
另一張表為一個主題發文用表。一個主題最多只能一位。但一位USER是可以有多個主題的。
所以這兩張表之間的關聯為 1對多 的模式 User(1)<=>(*)Thread
所以上面一篇ORM是設定 User 。我們知道它是需要關聯2張表的。
這邊就先從 UserInfo 表關聯起。
上面是目前比較正統的寫法。也就是用 hasOne 來代表我跟這張表對應使用 user_id 來做1對1關聯對應。
但這樣的寫法,還需要引入 Use UserInfo
我個人會比較喜歡用以下的寫法
這邊需要注意一點,當關聯的表對應的ID是相同的情況下。
則可以設定一組ID就好。但如果不同怎麼辦。則可以用如下的寫法。
變數2是要關聯對應的主鍵ID。也就是我目前要關聯UserInfo的ID。
變數3則是我此Model的ID。
以上再設定完成後,只要在程式上寫
就會自動取得資料了。不用再那邊JOIN來JOIN去的。
上面講完了1對1的處理。那1對多呢???
其實1對多跟上面的處理方式都大同小異。
唯一不同的是,使用的函式是 hasMany
所以Thread的對應可以用以下的方式寫
所以1對1跟1對多的切換就變得比較單純了。只要切換函式,對應的方式就會直接改變。
最後就是對應的關聯表反向對應。
1對1來說算比較單純。
可在 UserInfo 這支模組上寫入
如果反向關聯都是單一返回的情況下。無論是1對1或是1對多。都是用 belongsTo 來反向關聯回來即可。
另外,belongsTo並不是一定要的。就算沒有來能從主表關聯。只是不能用子表關聯回來而已。
在某些情況下,沒必要就可以不需要設定。
依我目前這三張表來說, UserInfo 其實就不太需要反向關聯。畢竟它是一定得要伴隨著 User 來關聯。
幾乎不會從 UserInfo 來反向關聯回來。
但 Thread 就會有其必要性了,畢竟我可能會需要拿該用戶的名稱及其它相關資料。
所以就會去設定一個反向回來。
上一次是在說ORM的觀念篇。
這次就來說說基本應用篇處理。
就如上一篇說的,其實ORM本身是一種資料容器。
所以Model認真來說,就是一種架構的規劃設計。
這邊就先來說說ORM的主要規劃
PHP:
<?php
namespace App\Models\Users;
class User extends Authenticatable implements JWTSubject
{
/**
* 指定表(可省略)
*
* @var string
*/
protected $table = "users"; // 指定資料表名稱
/**
* 指定的主鍵值欄位,如不指定預設是id
*
* @var string
*/
protected $primaryKey = 'user_id'; //設定主鍵值欄位
/**
* 軟刪除指定欄位,需事先設定好
*
* @var string[]
*/
protected $dates = ["deleted_at"]; //建立一個指定變數 指定到該表中 軟刪除欄位
/**
* 其它相對應欄位
*
* @var array<string>
*/
protected $fillable = [
"account", "password",
"groupId", "email",
];
/**
* 不輸出的欄位值
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'token',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
];
}
這裏來一一說明一些常用的變數
- $table:設定主要對應的表。
- 一般這可以省略。
- ORM會自動依model名來取得對應的表名稱。如User會自動對應 users 表。(後面的 s 會自動加入) ,UserInfo 會自動對應 user_infos 表。
- 如果你所使用的表名並非是預設對應的。才會需要用這個變數指定。
- $primaryKey:主鍵值對應的欄位名稱
- 大多數來說,如果主鍵值的欄位名稱是 id 的話。此值是可以省略不設定。
- 但如果您的主鍵值並非是 id 。則需要指定。
- 像是我在設定主鍵值是使用 user_id 。那我就得去指定這個值
- $dates:軟刪用指定欄位
- 一般這個欄位還需要搭配引入 SoftDeletes 這個套件。
- 如果未引入軟刪用的套件,其值是沒意義的。
- 軟刪一般預設欄位名為 deleted_at 。如果是直接使用此欄位名稱。則該值可以不需要設定。
- $fillable:欄位設定名
- 這個是設定主要處理的欄位名資料串。這一般我都是建議最好還是設定進去。可避免不需要的KEY值被引入寫進去。
- 一些系統用的值並不需要在這裏設定如主鍵值、資料時間值(created_at、updated_at)。這是為了確保重要資料不要被寫入到。
- 系統用的欄位值,就算不設定。也會透過系統的動作來自動寫入。所以不需要擔心。
- 這邊如果有設定好的話。可在程式應用上使用 $orm->fill($data) 來過濾掉不該儲存的KEY。
- $hidden:不輸出的欄位值
- 該選項要小心使用。一般很少設定它。但有時特別的情況可以將其設定
- 原則上如果ORM中有使用了SELECT的方式,大多數此設定是可有可無。
- 此大多數是應用到機敏資料為主,也就是它是絕對不輸出的。
- 雖然是不輸出,但還是可以使用update的方式來更新。只是會拿不到原本的值。
- $casts:欄位格式特定化使用。
- 用的有 integer、string、array、date、datetime
- 一般來說 integer及string 並不太需要特別去設定。因為ORM會自動依欄位格式來轉換。
- 比較特殊的是 array 如為json、obj等格式的欄位才會有作用。其它格式有時會報錯。不過它可以省下轉換格式處理
- date、datetime只能應用在日期時間相關欄位類型上。其它類型會出現錯誤。
- casts 是可以自訂化。這個在後面進階篇時再做討論
就正常來說,如都是用預設值的情況下。只需要設定 fillable 這個變數即可。
等表基本都定義好後,再來就是要準備定義關聯了
這邊就先從比較單純1對1及1對多來說明
這裏就先準備好三張表
表名 | 使用說明 | 對應關聯 | ||
---|---|---|---|---|
User | 用戶帳號表 |
| ||
UserInfo | 用戶資料表 | User(1)<- | ||
Thread | 發文主題表 | User(1)<- |
這裏說明一下。
我規劃了一個帳號用的表,另外將會員的資料另外放在另一張子表上。
所以這兩張表之前的關聯為 1對1 的模式。 User(1)<->(1)UserInfo
另一張表為一個主題發文用表。一個主題最多只能一位。但一位USER是可以有多個主題的。
所以這兩張表之間的關聯為 1對多 的模式 User(1)<=>(*)Thread
所以上面一篇ORM是設定 User 。我們知道它是需要關聯2張表的。
這邊就先從 UserInfo 表關聯起。
PHP:
public function UserInfo(): HasOne
{
return $this->hasOne(UserInfo::class, 'user_Id');
}
但這樣的寫法,還需要引入 Use UserInfo
我個人會比較喜歡用以下的寫法
PHP:
public function UserInfo(): HasOne
{
return $this->hasOne('App\Models\UserInfo', 'user_Id');
}
這邊需要注意一點,當關聯的表對應的ID是相同的情況下。
則可以設定一組ID就好。但如果不同怎麼辦。則可以用如下的寫法。
變數2是要關聯對應的主鍵ID。也就是我目前要關聯UserInfo的ID。
變數3則是我此Model的ID。
PHP:
public function UserInfo(): HasOne
{
return $this->hasOne('App\Models\UserInfo', 'Id', 'user_Id');
}
以上再設定完成後,只要在程式上寫
PHP:
$orm = User::find(1);
$info = $orm->UserInfo;
$orm = User::with('UserInfo');
就會自動取得資料了。不用再那邊JOIN來JOIN去的。
上面講完了1對1的處理。那1對多呢???
其實1對多跟上面的處理方式都大同小異。
唯一不同的是,使用的函式是 hasMany
所以Thread的對應可以用以下的方式寫
PHP:
public function Thread(): HasMany
{
return $this->hasMany('App\Models\Thread', 'Id', 'user_Id');
}
所以1對1跟1對多的切換就變得比較單純了。只要切換函式,對應的方式就會直接改變。
最後就是對應的關聯表反向對應。
1對1來說算比較單純。
可在 UserInfo 這支模組上寫入
PHP:
public function User(): belongsTo
{
return $this->belongsTo('App\Models\User', 'user_Id', 'Id');
}
如果反向關聯都是單一返回的情況下。無論是1對1或是1對多。都是用 belongsTo 來反向關聯回來即可。
另外,belongsTo並不是一定要的。就算沒有來能從主表關聯。只是不能用子表關聯回來而已。
在某些情況下,沒必要就可以不需要設定。
依我目前這三張表來說, UserInfo 其實就不太需要反向關聯。畢竟它是一定得要伴隨著 User 來關聯。
幾乎不會從 UserInfo 來反向關聯回來。
但 Thread 就會有其必要性了,畢竟我可能會需要拿該用戶的名稱及其它相關資料。
所以就會去設定一個反向回來。
最后編輯: