• 游客 您好:

    目前「IT人巴啦啦天地」需要數個專家協助發表文章。

    只要您願意,可以直接與我 ihstat 連絡。我將會給你「專家」身份。

    成為「專家」有什麼好處?目前暫時還沒有。我也只願意提供最多10名會員有這樣的身份。

    他可能可以成為未來非常高的權限。(除了管理) 也可以獲得由浩瀚星空站提供的資源。

  • 本站不接受任何被列入廣告發文黑名單的電子信箱。如您無法註冊,可能是您使用的電子信箱為廣告黑名單信箱。正常的信箱都是可以正常註冊。

    如果您可以証實您的信箱非廣告黑名單,請自行來信 hstaryoching#gmail.com 申請。

    申請請留下您的正統名稱及信箱,並告知從何得知及想進來的理由。

  • 浩瀚星空站已經重新整合並新增新的開發小站天地。

    採用新版的xenforo 2.2.3 做為最新的站點系統。

    中文搜尋已在本站啟用成功,歡迎多加測試看看

    有問題請再回報

教學 Laravel架構規劃教學(四)-Model(ORM)基本應用篇

ihstar

管理員
管理成員
抱歉啦!這次的更新比較久了。有點太混。
上一次是在說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 = [

    ];
}

這裏來一一說明一些常用的變數
  1. $table:設定主要對應的表。
    1. 一般這可以省略。
    2. ORM會自動依model名來取得對應的表名稱。如User會自動對應 users 表。(後面的 s 會自動加入) ,UserInfo 會自動對應 user_infos 表。
    3. 如果你所使用的表名並非是預設對應的。才會需要用這個變數指定。
  2. $primaryKey:主鍵值對應的欄位名稱
    1. 大多數來說,如果主鍵值的欄位名稱是 id 的話。此值是可以省略不設定。
    2. 但如果您的主鍵值並非是 id 。則需要指定。
    3. 像是我在設定主鍵值是使用 user_id 。那我就得去指定這個值
  3. $dates:軟刪用指定欄位
    1. 一般這個欄位還需要搭配引入 SoftDeletes 這個套件。
    2. 如果未引入軟刪用的套件,其值是沒意義的。
    3. 軟刪一般預設欄位名為 deleted_at 。如果是直接使用此欄位名稱。則該值可以不需要設定。
  4. $fillable:欄位設定名
    1. 這個是設定主要處理的欄位名資料串。這一般我都是建議最好還是設定進去。可避免不需要的KEY值被引入寫進去。
    2. 一些系統用的值並不需要在這裏設定如主鍵值、資料時間值(created_at、updated_at)。這是為了確保重要資料不要被寫入到。
    3. 系統用的欄位值,就算不設定。也會透過系統的動作來自動寫入。所以不需要擔心。
    4. 這邊如果有設定好的話。可在程式應用上使用 $orm->fill($data) 來過濾掉不該儲存的KEY。
  5. $hidden:不輸出的欄位值
    1. 該選項要小心使用。一般很少設定它。但有時特別的情況可以將其設定
    2. 原則上如果ORM中有使用了SELECT的方式,大多數此設定是可有可無。
    3. 此大多數是應用到機敏資料為主,也就是它是絕對不輸出的。
    4. 雖然是不輸出,但還是可以使用update的方式來更新。只是會拿不到原本的值。
  6. $casts:欄位格式特定化使用。
    1. 用的有 integer、string、array、date、datetime
    2. 一般來說 integer及string 並不太需要特別去設定。因為ORM會自動依欄位格式來轉換。
    3. 比較特殊的是 array 如為json、obj等格式的欄位才會有作用。其它格式有時會報錯。不過它可以省下轉換格式處理
    4. date、datetime只能應用在日期時間相關欄位類型上。其它類型會出現錯誤。
    5. casts 是可以自訂化。這個在後面進階篇時再做討論
以上就是ORM一般基本的規劃設計及宣告變數。
就正常來說,如都是用預設值的情況下。只需要設定 fillable 這個變數即可。
等表基本都定義好後,再來就是要準備定義關聯了

這邊就先從比較單純1對1及1對多來說明
這裏就先準備好三張表

表名使用說明對應關聯
User用戶帳號表
->(1)UserInfo ->(*)Thread
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');
}
上面是目前比較正統的寫法。也就是用 hasOne 來代表我跟這張表對應使用 user_id 來做1對1關聯對應。
但這樣的寫法,還需要引入 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 就會有其必要性了,畢竟我可能會需要拿該用戶的名稱及其它相關資料。
所以就會去設定一個反向回來。
 
最后編輯:

ihstar

管理員
管理成員
題外話:

雖然我在關聯時,幾乎都是用同 Model 的名字來宣告對應 Function 屬性對應名。
其實這個名稱是可以隨便您命名的。
 
頂部