thinkphp5 數據庫和模型

一、Db和模型的存在只是ThinkPHP5.0架構設計中的職責和定位不一樣,Db負責的只是數據(表)訪問,模型負責的是業務數據和業務邏輯。
二、Db和模型最明顯的一個區別就是Db查詢返回的數據類型爲數組(對於一個沒有業務邏輯的數據而言,數組已經足夠),而模型的查詢返回類型的是模型對象實例。
三、總而言之,想要掌握模型,必須明白和理解下面幾個原則:
模型和數據庫層的定位和職責不一樣;
不要由於性能而放棄使用模型,那是得不償失的;
用面向對象的方式來使用和設計模型;
模型的數據底層操做仍然是數據庫抽象訪問層,並且是自動的


四、模型定義有幾個要素:
一般會繼承think\Model(或者子類),虛擬模型除外;
一個模型並不老是對應一個數據表(可能會有多個),雖然默認如此;
模型名和數據表名也不是直接對應關係;
儘管一個空模型和使用Db類無異,但意義不一樣;


五、模型定義階段要達成的目的:
定義數據表(默認就是模型類名)
定義數據表主鍵(默認會自動獲取)
定義數據庫鏈接(默認使用數據庫配置)
定義數據處理邏輯(包括屬性和方法)
定義業務邏輯(方法)


六、下面的定義是不須要或者不支持的:
數據表字段(不須要,會自動獲取,並支持緩存機制)
數據表前綴(不支持,模型不關心前綴)


七、大多數狀況下,數據表和數據庫鏈接是不須要定義的,數據處理邏輯和業務邏輯纔是模型定義的重點


八、在新版框架的架構設計規範中,咱們建議數據表的命名不使用前綴設計,表前綴其實已是一種過期的設計了,不少時候跨庫的設計比表前綴的設計來的更靈活和實用,並且前綴設計(尤爲是在混合用的狀況下)帶來的一些困惑和問題倒是不少新手最大的苦惱,因此何須自尋煩惱(若是你必定要採用前綴設計,那麼請用name方法替代table方法,而且在數據庫配置文件中配置prefix參數,我也不攔着你,哭的時候別找我^_^)


九、關於模型的鏈接對象和查詢對象,要清楚下面這些事實:


模型能夠單獨設置數據庫鏈接;
模型的數據庫鏈接是惰性的(由於鏈接自己就是惰性);
若是使用統一的數據庫配置,模型使用的鏈接對象是相同的;
模型使用的查詢對象是獨立的;
模型可使用自定義的查詢對象;


十、模型類實現了ArrayAccess接口,所以同樣可使用數組方式操做對象


十一、由於模型基本上是內部處理業務邏輯,因此會出現內部調用的時候
以name屬性爲例,獲取模型數據的方式有下列三種:
場景 方法
外部獲取模型數據 $model->name
內部獲取模型數據 $this->getAttr('name')
內部獲取(原始)模型數據 $this->getData('name')
getData和getAttr方法的區別前者是原始數據,後者是通過讀取器處理的數據,若是沒有定義數據讀取器的話,兩個方法的結果是相同的。


對應的設置模型數據的方式也有三種:
場景 方法
外部設置模型數據 $model->name='thinkphp'
內部設置模型數據(通過修改器) $this->setAttr('name','thinkphp')
內部設置模型數據 $this->data('name','thinkphp')
data和setAttr方法的區別前者是賦值最終數據,後者賦值的數據還會通過修改器處理,若是沒有定義修改器的話,兩個方法的結果是相同的。


十二、CURL
模型的CURD操做最終調用的仍是Db類的操做,區別在於使用了ActiveRecord模式和單獨作了一層封裝而已
除了模型本身的方法操做外,還能夠調用Db類的全部查詢方法,也就是說Db類的CURD操做方法均可以在模型類中被調用。
//建立
//動態
$user        = new User;
$user->name  = 'thinkphp';
$user->email = 'thinkphp@qq.com';
$user->save();
// 獲取用戶的主鍵數據
echo $user->id;
//靜態
$user = User::create([
    'name'  => 'thinkphp',
    'email' => 'thinkphp@qq.com',
]);
echo $user->id;


//讀取
$user = User::get(1);
echo $user->id;


// 查詢用戶數據集
$users = User::all([1, 2, 3]);
$users = User::where('id', '>', 1)
    ->limit(5)
    ->select();
// 遍歷讀取用戶數據
foreach ($users as $user) {
    echo $user->id;
    echo $user->name;
}




//更新
//動態 返回影響的記錄數
$user = User::get(1);
$user->save([
    'name'  => 'topthink',
    'email' => 'topthink@qq.com',
]);
//靜態 返回模型對象實例
User::update([
    'name'  => 'topthink',
    'email' => 'topthink@qq.com',
], ['id' => 1]);


//刪除
$user = User::get(1);
$user->delete();
//靜態實現
User::destroy(1);


如今咱們已經掌握了模型的基本CURD操做,咱們來總結下方法區別:
用法 Db類 模型(動態) 模型(靜態)
建立 insert save create
更新 update save update
讀取單個 find find get
讀取多個 select select all
刪除 delete delete destroy
而後要注意幾個注意事項:


模型類能夠直接調用Db類的全部方法;
模型類和Db類的查詢返回類型是徹底不一樣的,即使是調用同一個方法查詢;
模型類封裝的靜態方法本質上仍是調用的動態方法,只是爲了方便不一樣的需求場景;
模型對象的查詢操做盡可能使用靜態方法調用;


1三、查詢構造器
查詢構造器的用法在模型類中沒有變化,而且還作了一些加強來支持模型的CURD封裝方法。


全部的鏈式方法均可以直接被模型類靜態調用,並且同樣不分前後次序,你只要掌握了數據庫的查詢構造器用法,就能掌握模型的查詢用法,並且模型類不須要調用table方法來指定數據表名稱,由於模型已經有本身的對應數據表規則,從這一點來講,模型的查詢操做應該比Db類的查詢操做用法簡單


模型能夠直接調用Db類(確切的說是查詢類)的方法,不管是靜態仍是動態調用,也就是說你能夠把模型類當成Db類同樣使用(雖然用法同樣,但其實區別很大,可能查詢條件、查詢結果和返回類型都不一樣)


1四、數據集
// 設置數據集返回類型 database.php中
'resultset_type'  => 'collection',
// 設置模型的數據集返回類型 模型中
protected $resultSetType = 'collection';
數據集的優點:


數據更對象化;
關聯操做更方便;
數據集自己能夠單獨定義獨立的業務方法;


1五、業務邏輯
業務邏輯應當封裝到具體模型中,並由控制器來調用;php

相關文章
相關標籤/搜索