이 문서의 예에서는 Zend Framework의 Zend_Db_Table 테이블 연결 사용법을 설명합니다. 참고하실 수 있도록 공유해 드리며 자세한 내용은 다음과 같습니다.
소개:
RDBMS에는 테이블 간의 관계, 일대다 대응, 다대다 대응 등 다양한 관계가 있습니다.
Zend 프레임워크는 이러한 관계를 구현하는 데 도움이 되는 몇 가지 방법을 제공합니다.
관계 정의:
다음은 이 기사에 사용된 예에 대한 관계 정의입니다.
<?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') ) );
예제에는 4개의 클래스가 정의되어 있습니다. 계정, 제품, 버그, 버그제품. 그 중 Accounts, Products, Bugs는 3개의 엔터티 테이블이고 BugsProducts는 관계 테이블입니다.
이 세 항목을 다시 분석해 보겠습니다. 계정에는 여러 개의 버그가 있고, 버그와 제품에는 다대다 관계가 있습니다.
$_dependentTables는 개체와 연결된 개체 이름입니다. 여기서는 연결된 데이터베이스 이름 대신 개체 이름을 써야 합니다.
$_referenceMap 배열은 다른 테이블과의 관계를 정의하는 데 사용됩니다. 여기서 해당 테이블과의 관계 및 어떤 종류의 관계가 있는지 설정할 수 있습니다. 가장 먼저 설정해야 할 것은 Rule Key인데, 위 예시에서는 'Reporter', 'Engineer' 등이 해당됩니다. Rule Key의 기능은 실제로 관계의 이름으로, 다른 데이터베이스 테이블 이름이나 다른 객체 이름과 동일할 필요는 없습니다. 표시를 위해 나중에 이 규칙 키의 역할을 확인할 수 있습니다.
각 규칙에는 다음과 같은 정의가 있습니다. (특별한 지침은 없으며 모두 위와 같이 '보고자' 관계로 설명됩니다.)
columns=> 위의 Report_by'는 데이터베이스에 있는 Bugs 테이블의 Report_by 필드입니다. 여기에는 필드가 하나만 있지만 여러 필드를 설정할 수도 있습니다.
refTableClass=> 이 테이블과 관련된 테이블을 설정하는 데 사용됩니다. 여기서는 테이블 이름 대신 대상 테이블의 개체 이름을 사용해야 합니다. 예에서는 'Account' 개체와 연결되어 있습니다.
refColumns =>접속이 발생한 테이블의 필드를 설정합니다. 두 개 이상 작성할 수 있습니다. 여러 필드와 관련된 경우 열과 일치해야 합니다. 이 설정은 실제로 선택 사항입니다. 비어 있으면 관련 필드가 관련 테이블의 기본 키로 자동 설정됩니다. 위의 예에서는 기본키가 관련 필드로 사용되지 않으므로 수동으로 설정합니다.
onDelete=> 선택 필드, 삭제 시 동작을 설정합니다.
onUpdate=> 선택적 필드, 테이블 업데이트 시 작업을 설정합니다.
위의 내용은 관계를 정의합니다.
관련 테이블에서 데이터 가져오기:
이미 쿼리 결과를 얻은 경우 다음 문을 사용하여 이 결과와 연결된 테이블의 쿼리 결과를 가져올 수 있습니다.
$row->findDependentRowset($table, [$rule]);
이 방법은 일반적으로 일-다에 해당하는 두 개의 엔터티 테이블과 다-다에 해당하는 하나의 관계 테이블을 사용하는데, 한 엔터티 테이블과 다른 엔터티 테이블에서 데이터를 검색하는 방법은 다음과 같습니다. 아래에 설명되어 있습니다.
첫 번째 필드 $table은 이 테이블과 연결된 테이블에 해당하는 클래스 이름을 나타냅니다. 두 번째 필드는 선택 사항이며 방금 언급한 규칙 키입니다. 이는 관계의 이름입니다. 생략할 경우 기본적으로 테이블의 첫 번째 관계가 됩니다. 다음은 예입니다.
<?php $accountsTable = new Accounts(); $accountsRowset = $accountsTable->find(1234); $user1234 = $accountsRowset->current(); $bugsReportedByUser = $user1234->findDependentRowset('Bugs');
예제에서는 먼저 사용자 번호 1234를 읽은 다음 이 사람이 보고한 버그가 무엇인지 알아냈습니다. 기본적으로 zend가 첫 번째 연결이므로 여기서는 첫 번째 연결입니다. Account와 연결된 것은 'Reporter'이므로 Reporter 레코드가 제거됩니다.
Engineer와 같은 다른 레코드를 꺼내려면 다음 방법을 따를 수 있습니다.
<?php $accountsTable = new Accounts(); $accountsRowset = $accountsTable->find(1234); $user1234 = $accountsRowset->current(); $bugsAssignedToUser = $user1234->findDependentRowset('Bugs', 'Engineer');
findDependentRowset을 사용하는 것 외에도 " 매직 메소드") 메커니즘. 그렇게 불리는 이유는 마술처럼 보이기 때문이다. 따라서 findDependentRowset('
- $row->find
- $row - >find
참고: 이 메커니즘은 Ruby on Rails에서 처음 나타났습니다. 여기의
<?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();
상위 테이블에서 필드 가져오기:
이제 일대다 관계에서 일대다로 이동하는 방법을 소개했습니다. 우리는 이를 역으로 수행합니다. 즉, 다수 중 하나를 취한다는 것은 실제로 다수 중 하나에서 해당 레코드를 취한다는 것을 의미합니다.
마찬가지로 다음 명령문이 있습니다.
$row->findParentRow($table, [$rule]);
마찬가지로 $table은 클래스 이름이고 선택적 매개변수 $rule은 해당 규칙 키로 채워집니다. 다음은 예시이다.
<?php $bugsTable = new Bugs(); $bugsRowset = $bugsTable->fetchAll(array('bug_status = ?' => 'NEW')); $bug1 = $bugsRowset->current(); $reporter = $bug1->findParentRow('Accounts');
위와 다른 점은 위에서 반환한 것은 여러 레코드의 집합이고, 이번에 반환한 것은 하나의 레코드여야 한다는 점이다. 다음 예는 규칙을 설정하는 것입니다.
<?php $bugsTable = new Bugs(); $bugsRowset = $bugsTable->fetchAll('bug_status = ?', 'NEW'); $bug1 = $bugsRowset->current(); $engineer = $bug1->findParentRow('Accounts', 'Engineer');
규칙만 입력하세요. 마찬가지로 이 방법에도 "마법의 장"이 있습니다. findParentRow('
- $row->findParent
- $row->findParent
예:
다대다 관계 테이블의 필드 가져오기:
上面两个方法讲述了一对多的使用,下面就是多对多了。我们使用如下方法取得多对多关系表的数据:
$row->findManyToManyRowset($table, $intersectionTable, [$rule1, [$rule2]]);
这里参数变成了4个,因为需要增加一个关系表来存储多对多的关系。
$table是与之发生多对多关系的表的类名,$intersectionTable是中间存储关系的关系表的类名。$rule1和$rule2是上面两个数据表的Rule Key。省略Rule Key的例子如下:
<?php $bugsTable = new Bugs(); $bugsRowset = $bugsTable->find(1234); $bug1234 = $bugsRowset->current(); $productsRowset = $bug1234->findManyToManyRowset('Products', 'BugsProducts');
下面是该方法的全部参数调用例子:
<?php $bugsTable = new Bugs(); $bugsRowset = $bugsTable->find(1234); $bug1234 = $bugsRowset->current(); $productsRowset = $bug1234->findManyToManyRowset('Products', 'BugsProducts', 'Bug');
这次的“魔术方法”是,对应 findManyToManyRowset('
- $row->find
- $row->find
- $row->find
例子:
<?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();
希望本文所述对大家基于Zend Framework框架的PHP程序设计有所帮助。
更多Zend Framework教程之Zend_Db_Table表关联实例详解相关文章请关注PHP中文网!