附錄A: 常見問題

陸續(xù)整理數(shù)據(jù)庫和模型相關(guān)的常見問題(保持更新~)

內(nèi)置支持的數(shù)據(jù)庫有哪些寻馏?

5.0內(nèi)置支持的數(shù)據(jù)庫包括Mysql诚欠、SqlitePgsqlSqlServer粉寞,另外還提供了OracleMongoDb的擴(kuò)展驅(qū)動唧垦。

Db類封裝的方法看起來很簡單液样,是如何實現(xiàn)調(diào)用的蓄愁?

Db類只是一個數(shù)據(jù)庫操作的入口類,數(shù)據(jù)庫的查詢方法都是由Query類實現(xiàn)的妇斤,調(diào)用Db類的靜態(tài)方法會自動實現(xiàn)Query類方法的動態(tài)調(diào)用丹拯。并且Db類是一個工廠類,針對不同的數(shù)據(jù)庫驅(qū)動實現(xiàn)了統(tǒng)一的封裝死相。

Db類的內(nèi)部是什么實現(xiàn)原理咬像?

Db類可以看成是數(shù)據(jù)庫抽象訪問層的入口類,抽象訪問層本身包含了連接器類(負(fù)責(zé)連接不同的數(shù)據(jù)庫和執(zhí)行基礎(chǔ)查詢)陷舅、查詢器類(負(fù)責(zé)各種查詢方法的實現(xiàn))和生成器類(負(fù)責(zé)把查詢方法轉(zhuǎn)換為基礎(chǔ)查詢語句)莱睁,各司其職完成了跨數(shù)據(jù)庫的底層操作芒澜,我們只需要操作Db類即可完成數(shù)據(jù)庫抽象訪問層的操作痴晦,系統(tǒng)的數(shù)據(jù)庫抽象訪問層實際上是對PDO的一種擴(kuò)展和增強(qiáng),主要的優(yōu)勢是CURD的增強(qiáng)和查詢事件旨袒,PDO本身只有基礎(chǔ)查詢方法。

模型和Db類的區(qū)別主要是什么施无?

Db類(其實就是數(shù)據(jù)庫抽象訪問層)負(fù)責(zé)數(shù)據(jù)和查詢本身猾骡,而模型類側(cè)重于業(yè)務(wù)邏輯和數(shù)據(jù)處理兴想。Db類僅僅是單純的進(jìn)行操作存取操作,主要使用的是數(shù)組類型捞镰,而模型操作的數(shù)據(jù)主要是模型的對象實例岸售,更加面向?qū)ο蠡椭庇^厂画,并且提供了模型關(guān)聯(lián)操作可以大大簡化業(yè)務(wù)邏輯的相關(guān)處理和數(shù)據(jù)獲取屎慢,模型本身是依賴數(shù)據(jù)庫抽象訪問層的。

tablename方法的區(qū)別是什么环肘?

Db類提供了tablename兩個方法廷臼,table方法用于指定數(shù)據(jù)表的完整名稱(包括前綴荠商,而且不會進(jìn)行大小寫轉(zhuǎn)換處理)续誉,name方法僅僅用于指定數(shù)據(jù)表的標(biāo)識(會把駝峰表名轉(zhuǎn)換為小寫加下劃線的方式酷鸦,并且不包含前綴)。

如果你遵循框架的數(shù)據(jù)表命名規(guī)范嘹裂,并且不使用表前綴的話寄狼,這兩個方法是等效的氨淌。

模型的getall方法可以支持條件查詢么盛正?

可以豪筝,如果模型的getall方法如果傳入一個索引數(shù)組壤蚜,就表示查詢條件,例如:

User::all([
    'name'  =>  'thinkphp',
    'id'    =>  ['>', 10],
]);

模型的getall方法可以支持排序等鏈?zhǔn)讲僮髅矗?/h2>

模型類的get和all方法之前不支持Db類的鏈?zhǔn)椒椒ㄕ{(diào)用聪富,如果你需要使用Db類的鏈?zhǔn)椒椒ǘ章梢允褂瞄]包方式,例如:

User::all(function($query){
    $query->field('name,email,id')->order('id');
});

等效于

User::field('name,email,id')->order('id')->select();

但區(qū)別是可以支持模型的事件操作昏名。

閉包查詢?nèi)绾蝹魅胱兞?/h2>

如果要在閉包中傳入外部變量轻局,可以使用use語法仑扑,例如:

User::get(function($query) use($name){
    $query->where('name',$name);
});

用類似的方法可以支持傳入多個變量置鼻,下面的用法是錯誤的:

User::get(function($query,$name) {
    $query->where('name',$name);
});

在模型里面怎么限制查詢字段

如果在模型里面調(diào)用的是find或者select方法箕母,那么依然可以使用field方法進(jìn)行字段限制,模型類的getall方法查詢的話本身不支持field方法钙勃,但可以通過閉包完成(參考上一個問題)肺缕。

但并不建議模型查詢的時候指定字段,因為可能會影響模型的獲取器跛十,尤其存在依賴關(guān)系的話秕硝。如果僅僅是希望不暴露敏感數(shù)據(jù)远豺,則可以在輸出數(shù)據(jù)的時候使用hidden或者visible方法進(jìn)行隱藏和指定顯示躯护。

5.0還有數(shù)據(jù)表字段緩存么?

5.0默認(rèn)不會生成字段緩存棺滞,但提供了數(shù)據(jù)表字段緩存的命令行指令裁蚁,你可以在部署上線后執(zhí)行php think optimize:schema命令生成字段緩存矢渊。

獲取器和修改器方法名的規(guī)范是什么?

獲取器和修改器方法的命名規(guī)范分別是getFieldNameAttrsetFieldNameAttr枉证,其中的FieldName是數(shù)據(jù)表字段的駝峰法表示矮男,也就是對應(yīng)數(shù)據(jù)表的field_name字段。

獲取器是在什么時候觸發(fā)室谚?

獲取器的作用是對模型的數(shù)據(jù)對象的(原始)數(shù)據(jù)做出自動處理毡鉴,定義了獲取器之后會在下列情況自動觸發(fā):

  • 模型的數(shù)據(jù)對象取值操作($model->field_name);
  • 模型的序列化輸出操作($model->toArray()或者$model->toJson())秒赤;
  • 顯式調(diào)用getAttr方法($this->getAttr('field_name'));

修改器是在什么時候觸發(fā)倒脓?

修改器的作用是在寫入數(shù)據(jù)庫之前對模型數(shù)據(jù)進(jìn)行修改處理撑螺,一般在顯式賦值(包括單個賦值和批量賦值)的時候會自動觸發(fā),不過有一些修改器是在設(shè)置了自動完成后被動觸發(fā)崎弃,下面是觸發(fā)條件甘晤。

  • 模型對象賦值;
  • 調(diào)用模型的data方法饲做,并且第二個參數(shù)傳入true线婚;
  • 調(diào)用模型的save方法,并且傳入數(shù)據(jù)盆均;
  • 顯式調(diào)用模型的setAttr方法塞弊;
  • 定義了該字段的自動完成;

為什么定義的修改器會執(zhí)行兩次

如果定義的修改器字段同時定義了自動完成泪姨,并且你也進(jìn)行了賦值操作游沿,那么就會導(dǎo)致修改器執(zhí)行兩次。避免的方法是對需要賦值操作的字段不再定義自動完成肮砾。典型的場景就是密碼字段使用md5加密保存诀黍,如果定義了自動完成,然后同時表單又賦值了仗处,那么可能會被加密兩次導(dǎo)致出錯眯勾。

如何使用視圖模型?

ThinkPHP提供了多種方式的視圖查詢的支持婆誓,包括:

一吃环、直接在數(shù)據(jù)庫中創(chuàng)建視圖

可以直接在數(shù)據(jù)庫中創(chuàng)建視圖,然后使用Db類或者創(chuàng)建模型類進(jìn)行操作洋幻,這種方式的優(yōu)點是方便郁轻,缺點是有些數(shù)據(jù)庫不支持創(chuàng)建視圖,而且不支持?jǐn)?shù)據(jù)寫入操作鞋屈。

二范咨、使用Db類的view方法動態(tài)創(chuàng)建視圖查詢

這種方式可以動態(tài)的創(chuàng)建一個視圖并進(jìn)行查詢操作故觅,而不依賴數(shù)據(jù)庫,缺點也是不支持?jǐn)?shù)據(jù)寫入渠啊。

三输吏、使用聚合模型

可以把聚合模型看成是view方法的模型封裝,而且可以支持寫入操作替蛉,缺點是不直觀和配置麻煩贯溅,而且聚合模型和原始模型不能同時使用(最新版本已經(jīng)不再推薦使用)。

四躲查、使用模型關(guān)聯(lián)

最新版本的模型關(guān)聯(lián)對一對一關(guān)聯(lián)改進(jìn)了很多它浅,包括關(guān)聯(lián)屬性綁定到當(dāng)前模型,以及關(guān)聯(lián)自動寫入功能镣煮,這是ThinkPHP5最為推薦的視圖操作方式姐霍,相比前面幾種,優(yōu)勢是操作直觀和支持寫入典唇。

設(shè)置主從分離后镊折,如何切換到主庫進(jìn)行查詢操作

一旦開啟了數(shù)據(jù)庫的主從分離,默認(rèn)情況下所有讀操作都是在從庫介衔,而寫操作則是在主庫恨胚,如果因為某些情況需要(例如對于實時性要求較高的查詢,寫入后立刻查詢從庫同步還不及時的情況)在主庫進(jìn)行查詢炎咖,我們可以使用

Db::name('user')->where('id',10)->update(['name'=>'thinkphp']);
// 連接到主庫進(jìn)行查詢操作
Db::name('user)->master(true)->find(10);

如何查詢一個字段值為NULL或者NOT NULL的數(shù)據(jù)赃泡?

5.0.5版本開始,可以直接使用快捷查詢方法如下:

// 查詢name為NULL的數(shù)據(jù)
Db::name('user')->whereNull('name')->select();
// 查詢name為NOT NULL的數(shù)據(jù)
Db::name('user')->whereNotNull('name')->select();

如果要使用OR查詢乘盼,可以傳入第二個參數(shù)為OR

// 查詢name為thinkphp或者NULL的數(shù)據(jù)
Db::name('user')->where('name','thinkphp')->whereNull('name','or')->select();
// 查詢name為thinkphp或者NOT NULL的數(shù)據(jù)
Db::name('user')->where('name','thinkphp')->whereNotNull('name','or')->select();

5.0.5版本之前升熊,可以使用下面的方式

// 查詢name為NULL的數(shù)據(jù)
Db::name('user')->where('name','null')->select();
// 查詢name為NOT NULL的數(shù)據(jù)
Db::name('user')->where('name','not null')->select();

如何直接使用字符串條件進(jìn)行查詢?

可以在where方法的第一個參數(shù)直接傳入字符串條件绸栅,并且可以和其它條件混合使用:

Db::name('user')
    ->where('( name like :name OR name IS NULL ) AND id > :id', ['name' => '%think%', 'id' => 10])
    ->where('email', 'like', '%think')
    ->select();

如何切換數(shù)據(jù)庫連接

無論在Db類還是模型里面僚碎,要切換數(shù)據(jù)庫都可以直接調(diào)用connect方法,該方法的參數(shù)可以是數(shù)組或者DNS字符串阴幌,以及配置文件中的數(shù)據(jù)庫連接配置參數(shù)名,例如:

Db::connect('db_config')->name('user')->find();

必須在connect方法后面調(diào)用查詢卷中。

模型中如何使用事務(wù)

在模型中使用事務(wù)和數(shù)據(jù)庫中使用事務(wù)一樣矛双,

$this->startTrans();
try{
    // 添加實現(xiàn)代碼
    // ...
    // 提交事務(wù)
    $this->commit();    
} catch (\Exception $e) {
    // 回滾事務(wù)
    $this->rollback();
}

但仍然建議直接使用

$this->transaction(function(){
    // 添加實現(xiàn)代碼
});

能夠?qū)崿F(xiàn)事務(wù)的自動提交及回滾。

Db類如何使用軟刪除功能

軟刪除功能是模型的特性蟆豫,Db類默認(rèn)不支持议忽,不過5.0.8+版本開始,可以使用useSoftDelete方法來支持軟刪除操作十减。

查詢數(shù)據(jù)的時候不包含軟刪除數(shù)據(jù)(假設(shè)軟刪除字段是delete_time)栈幸。

Db::name('user')->useSoftDelete('delete_time')->select();

上一篇:第九章:性能和安全
下一篇:附錄B:使用MongoDb

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末愤估,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子速址,更是在濱河造成了極大的恐慌玩焰,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芍锚,死亡現(xiàn)場離奇詭異昔园,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)并炮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門默刚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人逃魄,你說我怎么就攤上這事荤西。” “怎么了伍俘?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵邪锌,是天一觀的道長。 經(jīng)常有香客問我养篓,道長秃流,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任柳弄,我火速辦了婚禮舶胀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘碧注。我一直安慰自己嚣伐,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布萍丐。 她就那樣靜靜地躺著轩端,像睡著了一般。 火紅的嫁衣襯著肌膚如雪逝变。 梳的紋絲不亂的頭發(fā)上基茵,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音壳影,去河邊找鬼拱层。 笑死,一個胖子當(dāng)著我的面吹牛宴咧,可吹牛的內(nèi)容都是我干的根灯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼烙肺!你這毒婦竟也來了纳猪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤桃笙,失蹤者是張志新(化名)和其女友劉穎氏堤,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體怎栽,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡丽猬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了熏瞄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脚祟。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖强饮,靈堂內(nèi)的尸體忽然破棺而出由桌,到底是詐尸還是另有隱情,我是刑警寧澤邮丰,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布行您,位于F島的核電站,受9級特大地震影響剪廉,放射性物質(zhì)發(fā)生泄漏娃循。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一斗蒋、第九天 我趴在偏房一處隱蔽的房頂上張望捌斧。 院中可真熱鬧,春花似錦泉沾、人聲如沸捞蚂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽姓迅。三九已至,卻和暖如春俊马,著一層夾襖步出監(jiān)牢的瞬間丁存,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工柴我, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留柱嫌,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓屯换,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子彤悔,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容

  • ORA-00001: 違反唯一約束條件 (.) 錯誤說明:當(dāng)在唯一索引所對應(yīng)的列上鍵入重復(fù)值時嘉抓,會觸發(fā)此異常。 O...
    我想起個好名字閱讀 5,307評論 0 9
  • 點擊查看原文 Web SDK 開發(fā)手冊 SDK 概述 網(wǎng)易云信 SDK 為 Web 應(yīng)用提供一個完善的 IM 系統(tǒng)...
    layjoy閱讀 13,758評論 0 15
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,096評論 1 32
  • --- layout: post title: "如果有人問你關(guān)系型數(shù)據(jù)庫的原理晕窑,叫他看這篇文章(轉(zhuǎn))" date...
    藍(lán)墜星閱讀 788評論 0 3
  • 一抑片、Python簡介和環(huán)境搭建以及pip的安裝 4課時實驗課主要內(nèi)容 【Python簡介】: Python 是一個...
    _小老虎_閱讀 5,744評論 0 10