2008-10-24 7 views
7

상황은 다음과 같습니다. 두 가지 모델, 'Action'과 'User'가 있습니다. 이 모델은 각각 '작업'테이블과 '사용자'테이블을 참조합니다.Zend Framework의 기본 동작을 위반하지 않고 테이블을 자동으로 결합

내 작업 테이블에 user_id 열이 있습니다. 지금은 모든 작업과 해당 작업이 할당 된 사용자에 대한 개요가 필요합니다. $action->fetchAll()을 사용할 때는 사용자 ID 만 가지고 있으므로 findDependentRowset()을 호출하지 않고도 사용자 모델의 데이터에 조인 할 수 있기를 원합니다.

내 모델에 fetchAll(), fetchRow()find() 메서드를 사용자 정의하려고 생각했지만 기본 동작이 손상 될 수 있습니다.

이 문제를 해결하는 가장 좋은 방법은 무엇입니까? 어떤 도움이라도 대단히 감사하겠습니다.

+0

Zend_Db_Table_Row :: findDependentRowset 뭐가 잘못() PHP보다 SQL에있는 경우가 더 나은 생각에 액세스하려면? –

+1

findDependentRowset() 및 findParentRow()에 대한 한 가지 반대 의견은 처음부터 관련 행이 모두 필요하다는 것을 알 때 JOIN을 사용하여 두 테이블 모두를 쿼리하는 것보다 한 번에 하나씩 관련 행을 지연로드하는 것이 덜 효율적이라는 것입니다. –

답변

14

내가 설계 및 테이블 관계 젠드 프레임 워크의 기능을 구현 (이 MySQL을하다 가정)을 기억하십시오.

첫 번째 의견은 findDependentRowset()을 사용하지 않는다는 것입니다. 조치에 User에 대한 외래 키 참조가있는 경우 findParentRow()을 사용하십시오.

$actionTable = new Action(); 
$actionRowset = $actionTable->fetchAll(); 
foreach ($actionRowset as $actionRow) { 
    $userRow = $actionRow->findParentRow('User'); 
} 

편집 : 루프에서, 당신은 지금 $ actionRow과 $의 userRow 개체가 있습니다. 개체 필드를 변경하고 개체에 save()을 호출하여 두 개체 중 하나를 통해 변경 내용을 데이터베이스에 다시 쓸 수 있습니다.

액션과 사용자 간의 조인을 기반으로 행 집합을 검색하기 위해 Zend_Db_Table_Select 클래스 (프로젝트를 떠난 후에 구현 됨)를 사용할 수도 있습니다.

$actionTable = new Action(); 
$actionQuery = $actionTable->select() 
    ->setIntegrityCheck(false) // allows joins 
    ->from($actionTable) 
    ->join('user', 'user.id = action.user_id'); 
$joinedRowset = $actionTable->fetchAll($actionQuery); 
foreach ($joinedRowset as $joinedRow) { 
    print_r($joinedRow->toArray()); 
} 

조인 쿼리를 기반으로 한 이러한 행 집합은 읽기 전용입니다. Row 개체에 필드 값을 설정하고 save()을 호출하여 변경 내용을 다시 데이터베이스에 게시 할 수는 없습니다.

편집 : 임의로 조인 된 결과 집합을 쓰기 가능하게 만들 수있는 방법이 없습니다. 조인 된 결과에 따라 간단한 예는 위의 설정을 고려해보십시오

$joinedRow->user_name = 'William'; 
$joinedRow->save(); 

질문 :

이 의 action_id = 1 행에 대한
action_id action_type user_id user_name 
    1   Buy   1  Bill 
    2   Sell   1  Bill 
    3   Buy   2  Aron 
    4   Sell   2  Aron 

다음으로는 사용자 개체에서 나온 필드 중 하나를 변경 : action_id = 2로 다음 행을 볼 때 'Bill'또는 'William'이 표시되어야합니까? 'William'이라면 행 1을 저장하면이 결과 집합의 다른 모든 행에서 'Bill'을 'William'으로 자동으로 업데이트해야한다는 의미입니까? 또는 save()이 자동으로 SQL 쿼리를 다시 실행하여 데이터베이스에서 새로 고친 결과 집합을 가져 오는 것을 의미합니까? 쿼리에 많은 시간이 소요된다면 어떻게 될까요?

또한 객체 지향 디자인을 고려하십시오. 각 행은 별도의 객체입니다. 하나의 객체에서 save()을 호출하면 다른 객체의 값을 변경하는 부작용이 생기는 것이 적절합니까 (객체가 같은 객체 컬렉션에 속해 있더라도)? 그건 나에게 Content Coupling의 형태처럼 보인다.

위 예제는 비교적 단순한 쿼리이지만 훨씬 복잡한 쿼리도 허용됩니다. Zend_Db는 쓰기 전용 결과를 읽기 전용 결과로 알리려는 의도로 쿼리를 분석 할 수 없습니다. 이것이 MySQL 뷰가 업데이트 할 수없는 이유이기도합니다.

+0

감사합니다. 귀하의 설명은 상황을 분명히합니다. 읽기 전용 개체를 반환하는 사용자 지정 메서드를 사용합니다. –

+0

예, 좋은 해결책입니다. –

+0

+1 및 고마워, 나는 이것 같이 무언가를 너무 찾고 있었다. ZF가 RoR의'find (: all, : includes)'와 같은 것을 가지고 있다면 멋지겠습니까? – Gordon

2

언제든지 데이터베이스에서 가입 할 수 있습니다.

CREATE OR REPLACE VIEW VwAction AS 
SELECT [columns] 
    FROM action 
    LEFT JOIN user 
    ON user.id = action.user_id 

은 그럼 그냥
$vwAction->fetchAll(); 

그냥 MySQL의에서보기는 읽기 전용되는 것을

1

보기 SQL 테이블을 만드는 좋은 해결책은 공동 만들 수 있습니까? 간단한 테이블 클래스 후에는

나는 당신의 논리가

관련 문제