華文網

laravel框架中Eloquent ORM的底層實現

在Laravel框架中,Eloquent ORM擴展的底層依然使用的是查詢構造器實現的,這裡通過簡單對比兩者的區別來理解Active Record模式的思想。在查詢構造器中訪問資料表時需要通過table()函數給定表名,而在Eloquent ORM中每個類就對應一個資料表;查詢構造器查詢結果返回的是資料陣列,

而在Eloquent ORM中返回的則是類的實例物件,每個實例物件對應一行資料;在Eloquent ORM中類直接封裝了對該資料表的操作,使用時更加方便。下面依然通過一個簡單的實例來介紹Eloquent ORM的底層實現,然後通過一個實例來介紹模型類中封裝的方法。

1.模型類的創建;下面介紹模型類的創建和操作。一般模型類存放在laravelapp目錄下,當然也可以根據實際需求放置在其他位置,

只要符合composer自動載入的規範就可以。這裡在laravelapp目錄下建立一個User類並繼承自Model類,這樣一個Eloquent ORM模型就創建了,通常也稱它為模型類,$timestamp屬性用於表示Laravel框架自訂時間欄位無效,因為在設計表的時候沒有用這個欄位。就這樣簡單,一個模型類就創建完成了,雖然你覺得自己什麼都沒做,但是這個類已經與一個資料表生成了物件關係映射,通過操作這個模型類,
就可以操作對應的資料表了。下面先通過這個模型類獲取表中所有的資料,來看看它到底是怎麼工作的,只需要通過“User::all();”語句就可以實現上述功能。具體實例代碼如下:

2.模型類的實現原理;在新創建的模型類中其實什麼都沒有做,就可以實現對資料庫操作的相關功能,

而這些功能都是在繼承類Model中完成的。但是,沒有無條件的便利,因為底層是事先實現好的,在使用時就需要准守它的規則,那麼需要對底層的實現原理有一個清晰的認識才能更好地去應用。下面就通過實例來介紹,逐步瞭解模型類實現的流程,這裡也將其分為兩個階段:第一階段是Eloquent ORM查詢構造器的生成,第二階段是操作命令的執行。本實例是查詢資料表中的所有資料。
首先,介紹第一階段,這裡給出部分代碼細節:

這裡首先通過“new static;”語句生成一個模型類實例,用到了後期靜態繫結,生成AppUser類的實例,在本實例中,因為沒有傳遞任何參數,所以構造函數並沒有執行有意義的工作,這部分將在後期封裝資料時再來介紹。

對於後期靜態繫結可以在PHP的重要性質中瞭解相關內容。接下來將通過“$instance->newQuery()”語句生成Eloquent ORM查詢構造器。

Eloquent ORM的底層使用了查詢構造器來實現,這裡通過newBaseQueryBuilder()函數創建一個基礎查詢構造器,而這個基礎查詢構造器中的資料庫連接最終也是通過資料庫控制器(IlluminateDatabaseDatabaseManager類實例)的connection()函數實現的。在完成基礎查詢構造器的產生實體後,通過newEloquentBuilder()函數對該查詢構造器進行封裝,實現Eloquent查詢構造器的創建。

在完成Eloquent查詢構造器的產生實體後,也就獲取了與資料庫的連接、SQL語法規則和結果處理的功能,因為對資料庫的操作不再以陣列的形式交互,而是通過這個模型類實例來與資料庫進行交互。資料表名稱是通過Model類物件的getTable()函數獲取的,如果物件中的$table屬性存在值,則使用該資料表名,如果不存在,則以模型類名的複數作為資料表名,即通過代碼“str_replace('','',Str::snake(Str::plural(class_basename($this))));”實現,這就是為什麼創建的模型類沒有指定資料表名,依然可以操作資料庫中的資料表的原因,在本實例中,預設的資料表名為“users”。

在完成基礎查詢構造器的產生實體後,通過newEloquentBuilder()函數對該查詢構造器進行封裝,實現Eloquent查詢構造器的創建。

在完成Eloquent查詢構造器的產生實體後,也就獲取了與資料庫的連接、SQL語法規則和結果處理的功能,因為對資料庫的操作不再以陣列的形式交互,而是通過這個模型類實例來與資料庫進行交互。資料表名稱是通過Model類物件的getTable()函數獲取的,如果物件中的$table屬性存在值,則使用該資料表名,如果不存在,則以模型類名的複數作為資料表名,即通過代碼“str_replace('','',Str::snake(Str::plural(class_basename($this))));”實現,這就是為什麼創建的模型類沒有指定資料表名,依然可以操作資料庫中的資料表的原因,在本實例中,預設的資料表名為“users”。