Thinkphp中模型的正確使用方式,ORM的思想概念

  • 2019 年 12 月 15 日
  • 筆記

在Thinkphp的文檔中關於框架特性的描述,有這麼一句話

ORM:重構的資料庫、模型及關聯,MongoDb支援;

從這句話可以得知,Thinkphp中的資料庫、模型,基於的ORM概念來完成。

ORM是什麼?

對象-關係映射(OBJECT-RELATIONAL MAPPING,簡稱ORM)

這是在面向對象編程發展過程中演變出來的一種思想、行為概念。

主要用途是:把對象模型表示的對象映射到基於sql的關係模型資料庫結構中去。

當改變這個對象自身的屬性或者調用該對象的方法時,相對應的是執行某些sql語句。

這樣子編寫程式碼的人員就可以更好地編寫業務邏輯,而非重複地編寫增刪改查sql語句。

thinkphp中的運用示例

TP框架中關於資料庫操作有兩個模組:

  • 資料庫
  • 模型

tp中的資料庫模組

引用一句文檔的特性描述

拆分為Connection(連接器)/Query(查詢器)/Builder(SQL生成器)

  • Connection連接器主要是用來連接資料庫的,可以使用不同的驅動連接不同類型的資料庫。
  • Query查詢器則是用來運行sql語句,處理結果,映射到數據集中。
  • Builder生成器則是用來把我們傳遞進去的條件、排序等轉換成sql語句。

在這3個步驟中,我們可以知道,如果有運用到ORM思想抽象映射的,那就只可能是Query查詢器模組,但是我們可以細查TP文檔中關於數據集的描述。

它更多的是封裝提供對於數據的處理方法,比如:

(以下是從文檔複製過來的 一小部分)

toArray     將數據集的數據轉為數組  merge   合併其它數據  diff    比較數組,返回差集  flip    交換數據中的鍵和值  intersect   比較數組,返回交集  keys    返回數據中的所有鍵名  pop 刪除數據中的最後一個元素  shift   刪除數據中的第一個元素  unshift 在數據開頭插入一個元素  reduce  通過使用用戶自定義函數,以字元串返回數組

但是卻沒有提供反向映射的關係操作,比如我們操作數據集,自動更新資料庫中的數據。

所以在我的理解中,資料庫模組中的ORM思想並不多,重點還是要了解和運用模型

tp中的模型

定義模型文件
namespace appindexmodel;    use thinkModel;    // 設置類名 需要遵循轉換規則,蛇形轉為大駝峰  class User extends Model  {      // 設置主鍵欄位名      protected $pk = 'u_id';        // 開啟自動維護時間戳欄位 (什麼時間插入 什麼時間更新)      protected $autoWriteTimestamp = true;        // 軟刪除 開啟之後 刪除數據只是用一個欄位來標識為刪除狀態 方便查詢、備份等      use SoftDelete;      protected $deleteTime = 'delete_time';    }

以上程式碼比文檔中第一章節模型初始化要多了一些內容,這是為了突出 模型可以完成很多功能

這也是ORM出現的原因:將sql的執行,抽象映射為面向對象編程中的對象。

我們可以理解為:表中的一行數據,代表我們程式碼中new一個對象,改變對象,則自動更新表中對應的行。

使用模型

演示的程式碼是比較簡單的,實際是可以很靈活的

比如查詢用非主鍵的條件來查詢、查詢多行記錄等等

<?php  // *******快速查詢、更新*******  // 查詢主鍵=1的數據  $user = User::get(1);  // 然後更改它的name欄位為新的值  $user->name = 'thinkphp';  // 保存,自己去資料庫給我更新吧~  $user->save();    // *******插入新的一行數據*******  // 新建一個對象(相對應的操作就是新創建一行)  $user = new User;  // 設置欄位的值  有多個欄位就多個設置  $user->name= 'thinkphp';  // 保存,自己去插入吧~  $user->save();
誤區

看了使用之後,很多初學者就開始寫程式碼了,然而卻使用了不太正確的方式。

① model只當為Db類用

雖然model可以看成db類的超集,但是如果只是把它當成簡單的DB類使用,而不是使用ORM思想去編寫。那麼就沒什麼必要使用它了。。

如果使用不對,不僅不能提高效率,反而會影響自己。(比如程式碼規範不統一、新增表還要新增對應的模型文件等等)

程式碼演示:

<?php  $userModel = new User(); // 這裡就相當於初始化Db類  $userOneInfo = $userModel->where(['u_id' => 1])->find();    $userTwoInfo = $userModel->where(['u_id' => 2])->find();  // ... 執行其他邏輯 比如判斷上下級 操作許可權等等    // 業務需求不只是讀取用戶的數據這麼簡單  // 還要扣除餘額(就是更新資料庫)  $userOneRes = $userModel->where(['u_id' => 1])->update(['u_balance' => 'xxxx']);    // ... 執行其他邏輯 

看到這裡,先停下來思考一下。。你的程式碼有出現過這樣子的嗎?

我相信還是有些人會這樣子用的吧!因為我以前也是這樣子用的。

那麼我們看看正確的使用方法(我認為的,如果覺得不對或者有更好的,歡迎評論交流)

<?php    $userOneInfo = User::get(1);    // 這裡演示使用非主鍵條件查詢的情況!!  // 查詢一個1用戶的下級出來  $userTwoInfo = User::get(function($query){      $query->where(['p_uid' => 1]);  });    // ... 執行其他邏輯 比如判斷上下級 操作許可權等等    // 業務需求不只是讀取用戶的數據這麼簡單  // 還要扣除餘額(就是更新資料庫)  $userOneInfo->u_balance = 0;  $userOneRes = $userOneInfo->save();    $userTwoInfo->u_balance = 0;  $userTwoRes =  $userTwoInfo->save();    // ... 執行其他邏輯

因為一個對象映射一條數據,所以我們在操作同樣where條件的數據,直接操作對象就可以了, 就不用反覆編寫where u_id =1更新, u_id = 1 要刪除

使用模型,還有很多用處,(得益於開源團隊的奉獻,為我們封裝了大量的功能)

比如: – 用戶表新增一條數據,另一個附屬表也要用該用戶id初始化一行。 – 自動轉換數據格式(儲存時間戳,查詢出來為2019-7-13 19:53:04格式)。 – 自動校驗數據,自動完成數據(操作的時候默認取操作人ip 許可權等儲存)。 – 關聯查詢(TP中非常強大的功能,在模型中定義好與另一個模型的關係,比如店鋪表中的u_id 可以用來查詢出店鋪所屬用戶的資訊 相當於店鋪模型和用戶模型的關聯 自動join數據 合併 返回給我們使用) – 等等

總結

  • ORM是一種思想,概念,代表 對象-關係映射(資料庫-對象 映射)
  • ORM使得對數據的操作抽象為對對象的操作。
  • 要學會思想的改變,利用好框架提供的特性,編寫更好地程式碼。
  • TP中的模型非常強大,封裝了大量的邏輯。

Tags: