Zend Framework教程之Zend_Db_Table表關(guān)聯(lián)實(shí)例詳解
本文實(shí)例講述了Zend Framework中Zend_Db_Table表關(guān)聯(lián)用法。分享給大家供大家參考,具體如下:
介紹:
在RDBMS中,表之間有著各種關(guān)系,有一多對(duì)應(yīng),多多對(duì)應(yīng)等等。
Zend框架提供了一些方法來方便我們實(shí)現(xiàn)這些關(guān)系。
定義關(guān)系:
下面是本文用的例子的關(guān)系定義:
<?php
class Accounts extends Zend_Db_Table_Abstract
{
protected $_name = 'accounts';
protected $_dependentTables = array('Bugs');
}
class
class
protected
protected
class
protected
}
Products extends Zend_Db_Table_Abstract
{
protected $_name = 'products';
protected $_dependentTables = array('BugsProducts');
}
Bugs extends Zend_Db_Table_Abstract
{
protected $_name = 'bugs';$_dependentTables = array('BugsProducts');$_referenceMap = array(
'Reporter' => array(
'columns' => 'reported_by',
'refTableClass' => 'Accounts',
'refColumns' => 'account_name'
),
'Engineer' => array(
'columns' => 'assigned_to',
'refTableClass' => 'Accounts',
'refColumns' => 'account_name'
),
'Verifier' => array(
'columns' => array('verified_by'),
'refTableClass' => 'Accounts',
'refColumns' => array('account_name')
)
);
}
BugsProducts extends Zend_Db_Table_Abstract
{
protected $_name = 'bugs_products';$_referenceMap = array(
'Bug' => array(
'columns' => array('bug_id'),
'refTableClass' => 'Bugs',
'refColumns' => array('bug_id')
),
'Product' => array(
'columns' => array('product_id'),
'refTableClass' => 'Products',
'refColumns' => array('product_id')
)
);
我們看到例子中定義了四個(gè)類:Accounts,Products,Bugs,BugsProducts。其中Accounts,Products和Bugs是三個(gè)實(shí)體表,而BugsProducts是關(guān)系表。
我們?cè)賮矸治鲆幌逻@三個(gè)實(shí)體,一個(gè)Account有多個(gè)Bug,他們之間是一對(duì)多的關(guān)系,而Bug和Product是多對(duì)多的關(guān)系。
$_dependentTables是一個(gè)與該對(duì)象關(guān)聯(lián)的對(duì)象名,這里注意,要寫對(duì)象名而不是關(guān)聯(lián)的數(shù)據(jù)庫名。
$_referenceMap數(shù)組用來定義和其他表的關(guān)系,在這里可以設(shè)置和那些表有關(guān)系,有什么樣的關(guān)系。第一個(gè)設(shè)置的是Rule Key,也就是上面例子的'Reporter', 'Engineer'之類的。Rule Key的作用其實(shí)就是一個(gè)關(guān)系的名字,并不需要和其他數(shù)據(jù)庫表名或者其他對(duì)象名的名字一樣。只是為了標(biāo)記的,在后面的時(shí)候,我們可以看到這個(gè)Rule Key的作用。
每一個(gè)Rule下面都有如下的一些定義:(沒有特殊說明,都以如上'Reporter'關(guān)系進(jìn)行說明)
columns=> 設(shè)置和別的表關(guān)聯(lián)的字段名,如上的'report_by'就是數(shù)據(jù)庫中表Bugs的report_by字段。這里只有一個(gè)字段,也可以設(shè)置多個(gè)字段。
refTableClass=>用于設(shè)置與這個(gè)表發(fā)生關(guān)系的表。這里要注意,一定使用目標(biāo)表的對(duì)象的名字而不是表名字,例子中就和'Account'對(duì)象發(fā)生了關(guān)聯(lián)。
refColumns =>設(shè)置發(fā)生聯(lián)系的表的字段??梢詫懚鄠€(gè),如果和多個(gè)字段發(fā)生聯(lián)系的話,這里要和columns對(duì)應(yīng)。這個(gè)設(shè)置其實(shí)是可選的,如果為空,關(guān)聯(lián)字段自動(dòng)被設(shè)置成為關(guān)聯(lián)表的主鍵。上面例子中并沒有使用主鍵作為關(guān)聯(lián)字段,所以手動(dòng)設(shè)置。
onDelete=>可選字段,設(shè)置當(dāng)刪除是的動(dòng)作。
onUpdate=>可選字段,設(shè)置當(dāng)更新表時(shí)的動(dòng)作。
以上定義關(guān)系。
從關(guān)聯(lián)表中取數(shù)據(jù):
如果我們已經(jīng)得到了一個(gè)查詢結(jié)果,我們可以通過一下語句去取得這個(gè)結(jié)果相關(guān)聯(lián)的表的查詢結(jié)果:
$row->findDependentRowset($table, [$rule]);
這個(gè)方法一般使用與一多對(duì)應(yīng)的兩個(gè)實(shí)體表中,在多多對(duì)應(yīng)的兩個(gè)實(shí)體表和一個(gè)關(guān)系表如何從一個(gè)實(shí)體表取出另一個(gè)實(shí)體表的數(shù)據(jù),我們會(huì)在下面敘述。
第一個(gè)字段$table是指和這個(gè)表想相聯(lián)系的表對(duì)應(yīng)的類名。第二個(gè)字段是可選的,是我們剛剛說到的rule key,就是這個(gè)關(guān)系的名字,如果省略,則默認(rèn)為這個(gè)表中的第一個(gè)關(guān)系。下面是例子:
<?php
$accountsTable = new Accounts();
$accountsRowset = $accountsTable->find(1234);
$user1234 = $accountsRowset->current();
$bugsReportedByUser = $user1234->findDependentRowset('Bugs');
例子中,我們先讀取了一個(gè)編號(hào)為1234的用戶,然后去查找這個(gè)家伙報(bào)了什么bug,由于zend默認(rèn)是第一個(gè)關(guān)聯(lián),所以這里和Account發(fā)生關(guān)聯(lián)的第一個(gè)就是'Reporter,所以就取出了Reporter的記錄。
如果我們想取出其他的記錄,比如Engineer,可以按照下面的辦法:
<?php
$accountsTable = new Accounts();
$accountsRowset = $accountsTable->find(1234);
$user1234 = $accountsRowset->current();
$bugsAssignedToUser = $user1234->findDependentRowset('Bugs', 'Engineer');
除了使用findDependentRowset之外,我們還可以使用叫做“魔術(shù)方法”(Magic Method)的機(jī)制。之所以這么叫,就是因?yàn)楹孟袷窃谧兡g(shù)一樣。所以方法findDependentRowset('<TableClass>', '<Rule>')就可以等價(jià)于如下:
- $row->find<TableClass>()
- $row->find<TableClass>By<Rule>()
注:這個(gè)機(jī)制是我們最一開始是在Ruby on Rails里面看到的。這里的<TableClass>和<Rule>一定要使用和相關(guān)聯(lián)的類名以及關(guān)聯(lián)名(Rule Key)完全一樣的名字,才可以生效。下面是例子:
<?php $accountsTable = new Accounts(); $accountsRowset = $accountsTable->find(1234); $user1234 = $accountsRowset->current(); // Use the default reference rule $bugsReportedBy = $user1234->findBugs();// Specify the reference rule $bugsAssignedTo = $user1234->findBugsByEngineer();
<?php
$bugsTable = new Bugs();
$bugsRowset = $bugsTable->fetchAll('bug_status = ?', 'NEW');
$bug1 = $bugsRowset->current();
// Use the default reference rule
$reporter = $bug1->findParentAccounts();// Specify the reference rule
$engineer = $bug1->findParentAccountsByEngineer();
從父表取得字段:
剛剛我們介紹了一多關(guān)系中的從一去多的方法,現(xiàn)在我們反過來,從多取一,其實(shí)是從多中的一個(gè)取他相對(duì)應(yīng)的那個(gè)記錄。
類似的我們有這樣的語句:
$row->findParentRow($table, [$rule]);
類似的,$table為類名,而可選參數(shù)$rule填入對(duì)應(yīng)的Rule Key。下面是例子:
<?php
$bugsTable = new Bugs();
$bugsRowset = $bugsTable->fetchAll(array('bug_status = ?' => 'NEW'));
$bug1 = $bugsRowset->current();
$reporter = $bug1->findParentRow('Accounts');
和上面不太一樣的是,上面返回的是一個(gè)多個(gè)記錄的集合,而這次返回的必然是一條記錄。下面的例子是設(shè)置Rule:
<?php
$bugsTable = new Bugs();
$bugsRowset = $bugsTable->fetchAll('bug_status = ?', 'NEW');
$bug1 = $bugsRowset->current();
$engineer = $bug1->findParentRow('Accounts', 'Engineer');
只需要吧Rule填入就好了。相似的,這個(gè)方法也有“魔術(shù)字段”。findParentRow('<TableClass>', '<Rule>')對(duì)應(yīng):
- $row->findParent<TableClass>()
- $row->findParent<TableClass>By<Rule>()
例子:
取得多對(duì)多關(guān)系表的字段:
上面兩個(gè)方法講述了一對(duì)多的使用,下面就是多對(duì)多了。我們使用如下方法取得多對(duì)多關(guān)系表的數(shù)據(jù):
$row->findManyToManyRowset($table, $intersectionTable, [$rule1, [$rule2]]);
這里參數(shù)變成了4個(gè),因?yàn)樾枰黾右粋€(gè)關(guān)系表來存儲(chǔ)多對(duì)多的關(guān)系。
$table是與之發(fā)生多對(duì)多關(guān)系的表的類名,$intersectionTable是中間存儲(chǔ)關(guān)系的關(guān)系表的類名。$rule1和$rule2是上面兩個(gè)數(shù)據(jù)表的Rule Key。省略Rule Key的例子如下:
<?php
$bugsTable = new Bugs();
$bugsRowset = $bugsTable->find(1234);
$bug1234 = $bugsRowset->current();
$productsRowset = $bug1234->findManyToManyRowset('Products', 'BugsProducts');
下面是該方法的全部參數(shù)調(diào)用例子:
<?php
$bugsTable = new Bugs();
$bugsRowset = $bugsTable->find(1234);
$bug1234 = $bugsRowset->current();
$productsRowset = $bug1234->findManyToManyRowset('Products', 'BugsProducts', 'Bug');
這次的“魔術(shù)方法”是,對(duì)應(yīng) findManyToManyRowset('<TableClass>', '<IntersectionTableClass>', '<Rule1>', '<Rule2>')
- $row->find<TableClass>Via<IntersectionTableClass>()
- $row->find<TableClass>Via<IntersectionTableClass>By<Rule1>()
- $row->find<TableClass>Via<IntersectionTableClass>By<Rule1>And<Rule2>()
例子:
<?php $bugsTable = new Bugs(); $bugsRowset = $bugsTable->find(1234); $bug1234 = $bugsRowset->current(); // Use the default reference rule $products = $bug1234->findProductsViaBugsProducts();// Specify the reference rule $products = $bug1234->findProductsViaBugsProductsByBug();
更多關(guān)于zend相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Zend FrameWork框架入門教程》、《php優(yōu)秀開發(fā)框架總結(jié)》、《Yii框架入門及常用技巧總結(jié)》、《ThinkPHP入門教程》、《php面向?qū)ο蟪绦蛟O(shè)計(jì)入門教程》、《php+mysql數(shù)據(jù)庫操作入門教程》及《php常見數(shù)據(jù)庫操作技巧匯總》
希望本文所述對(duì)大家基于Zend Framework框架的PHP程序設(shè)計(jì)有所幫助。
- Zend Framework框架教程之Zend_Db_Table_Rowset用法實(shí)例分析
- Zend Framework教程之Zend_Db_Table_Row用法實(shí)例分析
- Zend Framework教程之Zend_Db_Table用法詳解
- ZendFramework框架實(shí)現(xiàn)連接兩個(gè)或多個(gè)數(shù)據(jù)庫的方法
- Zend Framework教程之連接數(shù)據(jù)庫并執(zhí)行增刪查的方法(附demo源碼下載)
- Zend Framework連接Mysql數(shù)據(jù)庫實(shí)例分析
- 解析如何使用Zend Framework 連接數(shù)據(jù)庫
- zend framework配置操作數(shù)據(jù)庫實(shí)例分析
- Zend Framework入門教程之Zend_Db數(shù)據(jù)庫操作詳解
相關(guān)文章
php配合jquery實(shí)現(xiàn)增刪操作具體實(shí)例
這篇文章主要介紹了php配合jquery實(shí)現(xiàn)增刪操作具體實(shí)例,有需要的朋友可以參考一下2013-12-12
PHP上傳Excel文件導(dǎo)入數(shù)據(jù)到MySQL數(shù)據(jù)庫示例
這篇文章主要介紹了PHP上傳Excel文件導(dǎo)入數(shù)據(jù)到MySQL數(shù)據(jù)庫示例,可以將Excel的數(shù)據(jù)寫入到MySQL數(shù)據(jù)庫中,感興趣的同學(xué)可以了解一下。2016-10-10
laravel ORM關(guān)聯(lián)關(guān)系中的 with和whereHas用法
今天小編就為大家分享一篇laravel ORM關(guān)聯(lián)關(guān)系中的 with和whereHas用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-10-10
在Laravel中使用GuzzleHttp調(diào)用第三方服務(wù)的API接口代碼
今天小編就為大家分享一篇在Laravel中使用GuzzleHttp調(diào)用第三方服務(wù)的API接口代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-10-10
基于curl數(shù)據(jù)采集之單頁面并行采集函數(shù)get_htmls的使用
用第一篇的get_html()實(shí)現(xiàn)簡(jiǎn)單的數(shù)據(jù)采集,由于是一個(gè)一個(gè)執(zhí)行才采集數(shù)據(jù)的傳輸時(shí)間就會(huì)是所有頁面下載的總時(shí)長,一個(gè)頁面假設(shè)1秒,那么10個(gè)頁面就是10秒了。所幸curl還提供了并行處理的功能2013-04-04
WordPress偽靜態(tài)規(guī)則設(shè)置代碼實(shí)例
這篇文章主要介紹了WordPress偽靜態(tài)規(guī)則設(shè)置代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12
在Mac OS上編譯安裝Nginx+PHP+MariaDB開發(fā)環(huán)境的教程
這篇文章主要介紹了在Mac OS上編譯安裝Nginx+PHP+MariaDB開發(fā)環(huán)境的教程,包括使用phpize安裝PHP擴(kuò)展的方法,需要的朋友可以參考下2016-02-02
PHP中cookie和session的區(qū)別實(shí)例分析
這篇文章主要介紹了PHP中cookie和session的區(qū)別,比較詳盡的分析了二者從創(chuàng)建、運(yùn)用到清除的各個(gè)流程的注意事項(xiàng),需要的朋友可以參考下2014-08-08

