視(shì)圖定義
視(shì)圖通(tōng)常是(shì)指數(shù)據庫的 ¥$↑(de)視(shì)圖,視(shì)圖是(shì)一(yī)個(gè)虛拟表,¶Ω其內(nèi)容由查詢定義。同真實的(de♠₩★)表一(yī)樣,視(shì)圖包含一(yī)系列帶有(yǒu)名稱的(deεΩ)列和(hé)行(xíng)數(shù)據。但(dàn)是(shì),視(shλσ↔↕ì)圖并不(bù)在數(shù)據庫中 以存儲的(de)數(↔σσshù)據值集形式存在。行(xíng)和(hé★φ♦)列數(shù)據來(lái)自(zì)由定義視(shì)圖∞ 的(de)查詢所引用(yòng)的(de)表,并且在引用(yòng)視(δ'¥≠shì)圖時(shí)動态生(shēng)成。對(duì)其中所引用(yòng₹γ)的(de)基礎表來(lái)說(shuō),視(shì)圖的(de)作(zuσ↓♠ò)用(yòng)類似于篩選。定 義視(shì)圖的(d☆∞↓πe)篩選可(kě)以來(lái)自(zì)當前或其它數(shù)據庫的(de)¥一(yī)個(gè)或多(duō)個(gè)表,或者其它視(shì↔®₽)圖。分(fēn)布式查詢也(yě)可(kě)用(yò∑≥<"ng)于定義使用(yòng)多(duō)個(gè)異類源數(shù)據的(de≠•γ )視(shì)圖。如(rú)果有(yǒu)幾台不(σ£¥☆bù)同的(de)服務器(qì)分(fēn)别存儲 組織中不(bù)同地(dì•←÷)區(qū)的(de)數(shù)據,而您需要(yào)将這(zhè)些(φ→≈xiē)服務器(qì)上(shàng)相(xiàng)似結構的(de♣¶)數(shù)據組合起來(lái),這(zhè)種方式就(jiù)很(hěn)'✘有(yǒu)用(yòng)。 視(shì)圖在有(yǒu)些(x±®×£iē)數(shù)據庫下(xià)面并不(bù)被支持,但(dàn)是(shβ₹±ì)ThinkPHP模拟實現(xiàn)了(le)數(shù)據庫的(de)視←αα(shì)圖,該功能(néng)可(kě)以用(÷↔© yòng)于多(duō)表聯合查詢。非常适合解決HAS_♥φ ONE 和(hé) BELONGS_TO 類型的(de$∏)關聯查詢。
要(yào)定義視(shì)圖模型,隻需要(yào)繼承T©hink\Model\ViewModel,然後設置viewFields屬性即可¶©(kě)。
例如(rú)下(xià)面的(de)例子(zǐ),我們定義了(le)一(y "ī)個(gè)BlogView模型對(duì)象,其中包括了(le)B¥←log模型的(de)id、name、title和(hé)U←← ser模型的(de)name,以及 Category模型☆§←的(de)title字段,我們通(tōng)≠₽π過創建BlogView模型來(lái)快(kuài)速讀(dú)取$→一(yī)個(gè)包含了(le)User名稱和(hé)類别名稱的(←£de)Blog記錄(集)。
namespace Home\Model;use Think\Model\ViewModel;class BlogViewModel extends ViewModel {public $viewFields = array('Blog'=>array('id','name','title'),'Category'=>array('title'=>'category_name', '_on'=>'Blog.category_id=Category.id'),'User'=>array('name'=>'username', '_on'=>'Blog.user_id=User.id'),);}
我們來(lái)解釋一(yī)下(xià)定義的£ε'♠(de)格式代表了(le)什(shén)麽。
$viewFields 屬性表示視(shì)圖模型包含的(de)字段,每個(gè)元素定義了(l'♦★εe)某個(gè)數(shù)據表或者模型的(de)字段。
例如(rú):
'Blog'=>array('id','name','title');
表示BlogView視(shì)圖模型要(←<>yào)包含Blog模型中的(de)id、nameσ™♦和(hé)title字段屬性,這(zhè)個(gè)其實很♦≠±(hěn)容易理(lǐ)解,就(jiù)和(hé)數(shù)據庫的(dγσ↑±e)視(shì)圖要(yào)包含某個(gè)數(shù)據∞®∞表的(de)字段一(yī)樣。而Blog相(xiàng)當于是(sh$÷§ì)給Blog模型對(duì)應的(de)數(s< πφhù)據表定義了(le)一(yī)個(gè)别名。
默認情況下(xià)會(huì)根據定義的≠ε(de)名稱自(zì)動獲取表名,如(rú)果希望指定數(s¶♦<hù)據表,可(kě)以使用(yòng):
'_table'=>"test_user"// 3.2.2版本以上(shàng)還(há♦↓≠i)可(kě)以使用(yòng)簡化(huà)定義(自(zì)動獲取表前綴)₩©Ωπ'_table'=>"__USER__"
如(rú)果希望給當前數(shù)據表定義另 &™外(wài)的(de)别名,可(kě)以使用(yòng)
'_as'=>'myBlog'
BlogView視(shì)圖模式除了(le)包含Blog模型之外(w←♣ài),還(hái)包含了(le)Category和(hé)×ε$User模型,下(xià)面的(de)定義:
'Category'=>array('title'=>'category_name');
和(hé)上(shàng)面類似,表示BlogView視(shì)圖模型還(h♥♦→ái)要(yào)包含Category模∞'♣±型的(de)title字段,因為(wèi)視(s↑↕hì)圖模型裡(lǐ)面已經存在了(le)一(y✘♦ī)個(gè)title字段,所以我們通(tōng)過
'title'=>'category_name'
把Category模型的(de)titl♦©e字段映射為(wèi)category_name字段,如(rú)果有(yǒu)多(duō)個(gè)字段,可(k ©©∑ě)以使用(yòng)同樣的(de)方式添加。
可(kě)以通(tōng)過_on來(lái)給視(shì)圖模型定義關♥♠±聯查詢條件(jiàn),例如(rú):
'_on'=>'Blog.category_id=Category₽.id'
理(lǐ)解之後,User模型的(de)定義方式同樣也(yě)就(jiù±☆•)很(hěn)容易理(lǐ)解了(le)。
Blog.categoryId=Category.id AND Blog.userId=User.id
最後,我們把視(shì)圖模型的(de)定義翻譯成SQπ★>L語句就(jiù)更加容易理(lǐ)解視(shì ✘α§)圖模型的(de)原理(lǐ)了(le)。假設我們不(bù)帶任何¥↑ 其他(tā)條件(jiàn)查詢全部的(de)字段 "Ω,那(nà)麽查詢的(de)SQL語句就(jiù)是(shì)
SelectBlog.id as id,Blog.name as name,Blog.title as title,Category.title as category_name,User.name as usernamefrom think_blog Blog JOIN think_category Category JOIN think_user Userwhere Blog.category_id=Category.id AND Blog.user_id=User.id
視(shì)圖模型的(de)定義并不(bù)需要(yào)先單獨定<±π義其中的(de)模型類,系統會(huì)默認按照(zhào)系統的(de)β 規則進行(xíng)數(shù)據表的(de)定位。如(rú)果Bl≈Ωσ₹og模型并沒有(yǒu)定義,那(nà)麽系統會(huì)自(zì)動根據當前 ✘φα 模型的(de)表前綴和(hé)後綴來(lái)自(zì)動獲取對∏★×(duì)應的(de)數(shù)據表。也(yě≤ )就(jiù)是(shì)說(shuō),如(r↑♠™®ú)果我們并沒有(yǒu)定義Blog模型類,那↑∏±₩(nà)麽上(shàng)面的(de)定義後,系統在進行(σ$₽xíng)視(shì)圖模型的(de)操作(zuò)的≥ε≤ (de)時(shí)候會(huì)根據 Blog這(zhè)個(gè)名稱和(←φ★₩hé)當前的(de)表前綴設置(假設為(wèi☆↔)Think_ )獲取到(dào)對(duì)應的(de)β ✘數(shù)據表可(kě)能(néng)是(shì↔ )think_blog。
ThinkPHP還(hái)可(kě)以支持視(s♥©§πhì)圖模型的(de)JOIN類型定義,我們♦≠β可(kě)以把上(shàng)面的(de)視(shì)圖定義♥≤改成:
public $viewFields = array('Blog'=>array('id','name','title','_type'=>'LEFT'),'Category'=>array('title'=>'category_name','_on'=>'Category.id=Blog.category_id','_type'=>'RIGHT'),'User'=>array('name'=>'username','_on'=>'User.id=Blog.user_id'),);
需要(yào)注意的(de)是(shì),這(zhè)裡(♠✔lǐ)的(de)_type定義對(duì)下(xià)一 ® (yī)個(gè)表有(yǒu)效,因此要(y<£ào)注意視(shì)圖模型的(de)定義順序。Blog模型的(de)
'_type'=>'LEFT'
針對(duì)的(de)是(shì)下(xià)α≠"一(yī)個(gè)模型Category而言,通(tōng)過上(shàng)β&面的(de)定義,我們在查詢的(de)時(shí)候最終生(shēng)©®成的(de)SQL語句就(jiù)變成:
SelectBlog.id as id,Blog.name as name,Blog.title as title,Category.title as category_name,User.name as usernamefrom think_blog Blog LEFT JOIN think_category Category ON Blog.category_id=Category.id RIGHT JOIN think_user User ON Blog.user_id=User.id
我們可(kě)以在試圖模型裡(lǐ)面定義特殊的(de)字'☆β段,例如(rú)下(xià)面的(de)例子(zǐ)↔∞定義了(le)一(yī)個(gè)統計(jì)字段
'Category'=>array('title'=>'category_name','COUNT(Blog.id)'=>'count','_on'=>'Category.id=Blog.ca¶§tegory_id'),
視(shì)圖查詢
接下(xià)來(lái),我們就(jiù)可(kě)以和(hé)使用(y€∞↓≈òng)普通(tōng)模型一(yī)樣對(duì)視(shìβ¶)圖模型進行(xíng)操作(zuò)了(le)π £ 。
$Model = D("BlogView");$Model->field('id,name,title,category_name,us←•♥"ername')->where('id>10')->order('id desc')->select();
看(kàn)起來(lái)和(hé)普通(tōng)的(€$de)模型操作(zuò)并沒有(yǒu)什(shén)麽大(dà)&₩ 的(de)區(qū)别,可(kě)以和(hé)使用(yòng)普通π☆(tōng)模型一(yī)樣進行(xíng)查詢。如(rú)果發現(x♠↔iàn)查詢的(de)結果存在重複數(shù)據,還(hái)可(k ¶ě)以使用(yòng)group方法來(lái)處理(lǐ<≠)。
$Model->field('id,name,title,category_nam←∑&e,username')->order('id desc')->group('id')->select();
我們可(kě)以看(kàn)到(dào),即使不(bù)定義視(δ✘•shì)圖模型,其實我們也(yě)可(kě)以通(tōn♠✔g)過方法來(lái)操作(zuò),但(♣♦→dàn)是(shì)顯然非常繁瑣。
$Model = D("Blog");$Model->table('think_blog Blog,think_cate£φ∞gory Category,think_us∏↔¶er User')->field('Blog.id,Blog.name,Blog.ti™•←tle,Category.title as ca♣₩tegory_name,User.namαΩ •e as username')->order('Blog.id desc')->where('Blog.category_id=Ca$שtegory.id AND Blog.user_id=User.id')->select();
而定義了(le)視(shì)圖模型之後,所有(yǒu)的(d≤σe)字段會(huì)進行(xíng)自(zì)動處理↔♣(lǐ),添加表别名和(hé)字段别名,從(cóng)而簡化(huà)₽δ£≠了(le)原來(lái)視(shì)圖的(de)複雜(zá)查詢。如(r '₩ú)果不(bù)使用(yòng)視(shì)∞π 圖模型,也(yě)可(kě)以用(yòng)連貫操作(zuò)Ω≈$ 的(de)JOIN方法實現(xiàn)相 φ↑(xiàng)同的(de)功能(néng)。≠&←




