【小(xiǎo)編推薦】ThinkPHP3.2——視(sδ₩hì)圖模型

2014-06-26  <∏‍ ; |   發布者:梁國(guó)芳×☆σ   | ∑≥;  查看(kàn):332↑♠∑∏0次

Thinkphp

視(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記錄(集)。

  1. namespace Home\Model;
  2. use Think\Model\ViewModel;
  3. class BlogViewModel extends ViewModel {
  4. public $viewFields = array(
  5. 'Blog'=>array('id','name','title'),
  6. 'Category'=>array('title'=>'category_name', '_on'=>'Blog.category_id=Category.id'),
  7. 'User'=>array('name'=>'username', '_on'=>'Blog.user_id=User.id'),
  8. );
  9. }

我們來(lái)解釋一(yī)下(xià)定義的£ε'♠(de)格式代表了(le)什(shén)麽。

$viewFields 屬性表示視(shì)圖模型包含的(de)字段,每個(gè)元素定義了(l'♦★εe)某個(gè)數(shù)據表或者模型的(de)字段。

例如(rú):

  1. '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):

  1. '_table'=>"test_user"
  2. // 3.2.2版本以上(shàng)還(há♦↓≠i)可(kě)以使用(yòng)簡化(huà)定義(自(zì)動獲取表前綴)₩©Ωπ
  3. '_table'=>"__USER__"

如(rú)果希望給當前數(shù)據表定義另 &™外(wài)的(de)别名,可(kě)以使用(yòng)

  1. '_as'=>'myBlog'

BlogView視(shì)圖模式除了(le)包含Blog模型之外(w←♣‌ài),還(hái)包含了(le)Category和(hé)×ε$User模型,下(xià)面的(de)定義:

  1. '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)過

  1. '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ú):

  1. '_on'=>'Blog.category_id=Category‌₽.id'

理(lǐ)解之後,User模型的(de)定義方式同樣也(yě)就(jiù±☆•)很(hěn)容易理(lǐ)解了(le)。

  1. 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ì)

  1. Select
  2. Blog.id as id,
  3. Blog.name as name,
  4. Blog.title as title,
  5. Category.title as category_name,
  6. User.name as username
  7. from think_blog Blog JOIN think_category Category JOIN think_user User
  8. where 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ì)圖定義♥≤​改成:

  1. public $viewFields = array(
  2. 'Blog'=>array('id','name','title','_type'=>'LEFT'),
  3. 'Category'=>array('title'=>'category_name','_on'=>'Category.id=Blog.category_id','_type'=>'RIGHT'),
  4. 'User'=>array('name'=>'username','_on'=>'User.id=Blog.user_id'),
  5. );

需要(yào)注意的(de)是(shì),這(zhè)裡(♠​✔lǐ)的(de)_type定義對(duì)下(xià)一 ® (yī)個(gè)表有(yǒu)效,因此要(y<£ào)注意視(shì)圖模型的(de)定義順序。Blog模型的(de)

  1. '_type'=>'LEFT'

針對(duì)的(de)是(shì)下(xià)α≠"一(yī)個(gè)模型Category而言,通(tōng)過上(shàng)β&面的(de)定義,我們在查詢的(de)時(shí)候最終生(shēng)©®成的(de)SQL語句就(jiù)變成:

  1. Select
  2. Blog.id as id,
  3. Blog.name as name,
  4. Blog.title as title,
  5. Category.title as category_name,
  6. User.name as username
  7. from 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ì)字段

  1. '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)π £ 。

  1. $Model = D("BlogView");
  2. $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ǐ<≠)。

  1. $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ì)顯然非常繁瑣。

  1. $Model = D("Blog");
  2. $Model->table('think_blog Blog,think_cate£φ∞gory Category,think_us∏↔¶er User')
  3. ->field('Blog.id,Blog.name,Blog.ti™•←tle,Category.title as ca♣₩tegory_name,User.namαΩ •e as username')
  4. ->order('Blog.id desc')
  5. ->where('Blog.category_id=Ca$שtegory.id AND Blog.user_id=User.id')
  6. ->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)。≠&←