首頁技術(shù)文章正文

TP5中model與Db有什么不同?【運(yùn)維培訓(xùn)】

更新時(shí)間:2020-06-03 來源:黑馬程序員 瀏覽量:

在TP5的使用過程中,很多使用者剛接觸到數(shù)據(jù)庫操作時(shí),不能很好調(diào)用相關(guān)的方法進(jìn)行數(shù)據(jù)庫的交互。下面就分享一下TP5中Db與模型的區(qū)別。

1、關(guān)于db與model的選擇

(1)使用DB方式是直接獲取到的query類(thinkphp/library/think/db/Query.php)的對象進(jìn)行數(shù)據(jù)庫的操作提供了基本的數(shù)據(jù)庫curd操作功能。

(2)使用model的方式是通過獲取到模型對象然后在調(diào)用query類下的方法進(jìn)行數(shù)據(jù)操作,但是在TP中的模型基類中還提供了較多的其他的方法可以方便使用例如獲取器、修改器、數(shù)據(jù)完成等等功能。因此模型的功能更為強(qiáng)大

(3)就數(shù)據(jù)格式而言,在DB中是采用的數(shù)組格式使用。而在模型中統(tǒng)一使用對象。其中數(shù)據(jù)庫交互后涉及到格式轉(zhuǎn)換。因此在同等情況下db的數(shù)據(jù)略快與模型方式。

因此對于TP5使用DB與model的方式具體在編程中選擇哪一個(gè)按照個(gè)人的觀點(diǎn)并無強(qiáng)制要求。有時(shí)候?yàn)榱隧?xiàng)目中的封裝采用模型方式可能更為合適一些

2、DB數(shù)據(jù)庫的操作

關(guān)于DB數(shù)據(jù)庫操作具體如何執(zhí)行下面使用一個(gè)操作的案例介紹

2.1、創(chuàng)建測試相關(guān)代碼

①創(chuàng)建測試使用的數(shù)據(jù)表

CREATE TABLE `tp_user` (

    `id` int(11) NOT NULL AUTO_INCREMENT,

    `name` varchar(255) NOT NULL DEFAULT '',

    PRIMARY KEY (`id`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8;

②寫入測試數(shù)據(jù)

insert into tp_user VALUES(null,'leo')

③配置好數(shù)據(jù)的連接

model與Db的區(qū)別01



④創(chuàng)建一個(gè)測試的方法

model與Db的區(qū)別02



⑤執(zhí)行的結(jié)果

model與Db的區(qū)別04




2.2、分析index方法中的執(zhí)行過程

由于TP中的自動(dòng)加載機(jī)制Db::name(‘user’)這段代碼的執(zhí)行會(huì)自動(dòng)找到Db類(thinkphp/library/think/Db.php)下的靜態(tài)方法name執(zhí)行


①查看name方法

在源碼中無法找到有name方法的存在但是找到了一個(gè)__callstatic的魔術(shù)方法。該魔術(shù)方法可以在調(diào)用靜態(tài)方法時(shí)自動(dòng)的觸發(fā)

②查看__callstatic方法

model與Db的區(qū)別03


在該方法中使用call_user_func_array調(diào)用了當(dāng)前類下connect方法并且傳遞了其他的參數(shù)其中$method為要調(diào)用的方法名稱即name方法


③查看connect方法

model與Db的區(qū)別04

對于該connect方法的作用就是用于獲取對象數(shù)據(jù)庫的操作對象,此處可以打印出得到的對象為think\db\connector\Mysql(thinkphp/library/think/db/connector/Mysql.php)的對象。即在控制器中所執(zhí)行的Db::name(‘user’)等價(jià)于使用think\db\connector\Mysql調(diào)用了name方法


④查看think\db\connector\Mysql對象

model與Db的區(qū)別05


在該類下并未發(fā)現(xiàn)存在name方法以及魔術(shù)方法的存在。因此代碼能夠執(zhí)行絕對在父類的Connection(thinkphp/library/think/db/Connection.php)中


⑤在Connection類中查看name相關(guān)的方法

在該類下也并未發(fā)現(xiàn)存在name方法但是卻找到了一個(gè)魔術(shù)方法__call

model與Db的區(qū)別06



結(jié)果為

model與Db的區(qū)別07.1


該魔術(shù)方法也是調(diào)用了自身類下的getQuery方法


⑥查看getQuery的方法

model與Db的區(qū)別07


此代碼執(zhí)行最終就獲取到了Query類的一個(gè)對象。

⑦查看query類下name方法


model與Db的區(qū)別08


在name方法后返回了當(dāng)前對象本身因此最終Db::name(‘user’)得到了一個(gè)query類的對象 ,在調(diào)用query下的find就找到了數(shù)據(jù)


3、模型數(shù)據(jù)庫的操作

3.1、創(chuàng)建模型相關(guān)代碼

①創(chuàng)建測試方法

model與Db的區(qū)別09


②創(chuàng)建自定義的模型


model與Db的區(qū)別10



③執(zhí)行結(jié)果

model與Db的區(qū)別11


3.2、分析index2方法中的執(zhí)行過程

①model函數(shù)的執(zhí)行

在控制器中model(‘User’)函數(shù)為TP5自帶的助手函數(shù)可以用于獲取到自定義模型類的對象


model與Db的區(qū)別12

此處是通過的Loader類調(diào)用了靜態(tài)方法所獲取到的對象。具體是否為真實(shí)的模型對象可以自行打印model(‘User’)所執(zhí)行的結(jié)果


②調(diào)用get方法

由于自定義的模型為空并且繼承了TP模型基類因此調(diào)用的為模型基類下的get方法

model與Db的區(qū)別13


在源碼中通過使用static::parseQuery調(diào)用最終得到了query的對象。到這里可以說明模型的數(shù)據(jù)操作其本質(zhì)也是調(diào)用的query類下的方法所實(shí)現(xiàn)

4、關(guān)于模型與DB的轉(zhuǎn)換

在使用TP5的模型操作數(shù)據(jù)時(shí)可能由于各種非模型方法的調(diào)用導(dǎo)致直接轉(zhuǎn)換為了query對象此后就不能調(diào)用模型方法了往往導(dǎo)致錯(cuò)誤無法定位。其實(shí)在模型基類中存在__call與__callStatic這兩個(gè)魔術(shù)方法。一旦調(diào)用了非模型方法就會(huì)自動(dòng)觸發(fā)得到一個(gè)query對象

①修改控制器下的測試代碼

model與Db的區(qū)別14


②在__Call方法處增加打印

model與Db的區(qū)別15


③結(jié)果

目前所得到的為query的對象因此后續(xù)就不能再調(diào)用模型方法了。

model與Db的區(qū)別16



猜你喜歡:

服務(wù)器是什么?服務(wù)器空間又是什么?

DNS服務(wù)器是什么?DNS劫持又是什么?

什么是域名?域名和URL有什區(qū)別?

分享到:
在線咨詢 我要報(bào)名
和我們在線交談!