2011-01-30 1 views
22

확장 질문 : DbTable이 데이터 조작을위한 대부분의 기본 작업을 처리 할 수있는 곳에서 데이터 매퍼/Db_Table_Row를 사용해야하는 이유는 무엇입니까?젠드 프레임 워크 - 왜 데이터 매퍼/Db_Table_Row를 사용해야합니까?

내가 현재 데이터베이스 조작을 위해 ZF의 V1.11

을 배우고, 나는 각 테이블에 대한 DBTABLE를 만들었습니다. 예를 들어, "사용자"테이블은 추가 코드가없는 Application_Model_DbTable_Users로 표시됩니다. 데이터를 조작 할 때

, 내가 사용할 수 있습니다

<?php 
$uTable = new Application_Model_DbTable_Users(); 
$newUid = $uTable->insert(array('name'=>'Old Name', 'email'=>'')); 
$user = $uTable->find($newUid)->current(); 

// Then I can use $user which is instance of Table_Row 
$user->name = "New Name"; 
$user->email = "[email protected]"; 
$user->save(); 

내 질문은, 내가 행 클래스를 정의해야 할 때

// By, adding this to the DbTable class 
protected $_rowClass = 'Application_Model_User'; 
(Table_Row을 가정하는 ZF-자습서에 DataMapper로 함)

각 엔티티에 대해 Row 클래스를 사용하면 어떤 이점이 있습니까? 누구든지 나를 위해 모범 사례를 가리킬 수 있습니다.

+0

http://stackoverflow.com/questions/373054/ - 전자 메일을 보내거나 암호 변경 논리를 사용자에게 고유 한 테이블 행 클래스에서 구현할 수 있다는 아이디어를 제공합니다. –

답변

41

자신 만의 Table_Row를 정의 할 필요는 없습니다. 그러나 많은 경우 특히 유용 할 수 있습니다. 특히 특정 사용자 행에 대한 특정 메서드 나 속성을 정의하려는 경우에 유용합니다. 또한 코드의 가독성을 향상시킬 수 있습니다. 당신이 사용자의 행 개체를 얻을 때 그런 다음 전체 이름을 얻을 수

public function getFullName() { 
    return $this->firstName . ' ' . $this->lastName; 
} 

:

사용자 테이블의 경우 예를를 들어, 당신은 사용자 정의 사용자 행에 getFullName()를 호출하는 방법을 정의 할 수 있습니다 사용자의, 당신은 할 수 : 당신은 사용자 테이블에 일부 부모 테이블이있을 때

$user = $uTable->find($newUid)->current(); 
$fullName = $user->getFullName(); 

두 번째 예이며, 같은 주소로. 이 경우 사용자 행에 getAddress에라는 방법을 정의 할 수 있습니다 : 다음과 같이

public function getAddress() { 
    return $this->findParentRow('Application_Model_DbTable_Addresses'); 
} 

을이 시나리오에서는 현재 사용자에 대한 주소 행 개체를 얻을 것입니다 :

$user = $uTable->find($newUid)->current(); 
$addressRow = $user->getAddress(); 

또 다른 예를은 사용자 정의 삭제 또는 instert 메소드를 만들려는 경우입니다. delete() 메소드를 사용하여 관리자를 삭제하지 않으려한다고 가정합니다.

$user = $uTable->find($newUid)->current(); 
$rowsDeleted = $user->delete(); // would be 0 if $user is admin 

:

public function delete() { 
     if ('admin' === $this->userRole) { 
       return 0; 
     } 
     return parent::delete(); 
} 

이 방법, 당신은 관리자 사용자를 삭제할 수 없습니다하는 것과 사용자의 행 개체에() 삭제 호출하여 다음과 같이 그럼 당신은 Zend_Db_Table_Row에서 삭제 방법을 과부하 수 이것들은 여러분 자신의 행 클래스를 정의하는 유용성을 보여주는 단지 세 가지 기본 예제 일뿐입니다. 물론 그들은 필요하지 않습니다. 그러나, 내 자신의 경험에서 그들은 매우 편리합니다.

+0

굉장! 설명과 함께 실제 생활 예제 코드 주셔서 감사 : - –

+0

+1 사실, 아주 좋은. –

+0

# 373054의 대답에서 사용자를위한 sendMailTo 함수가 있습니다. Db_Row 클래스에서 데이터베이스와 관련없는 함수를 유지하는 것이 좋습니다. 사용자와 관련된 이러한 비즈니스 로직은 어디에 있어야합니까? –

20

요컨대, 그것은 격리에 관한 것입니다.

Zend_Db_Table은 테이블 데이터 게이트웨이의 구현입니다. 하나의 클래스를 통해 특정 테이블 뷰에 대한 CRUD 액세스를 채널링합니다.일반적으로 Table Module과 함께 사용됩니다. 게이트웨이에서 처리하는 레코드에 대한 비즈니스 논리를 포함하는 클래스입니다.

Zend_Db_Table_RowRow Data Gateway Pattern의 구현입니다. 여기에서 반환 된 객체는 데이터베이스 레코드와 똑같이 보이며 해당 데이터와 함께 작동하는 비즈니스 로직을 포함하지만 출처 인 테이블 (ActiveRecord)에서 CRUD 논리를 포함하지 않지만 집계합니다.

로우 데이터 게이트웨이는 object relational impedance mismatch을 너무 많이 사용하지 않는 한 괜찮습니다. 객체가 관계형 데이터베이스에서 지속되는 방식과 객체 세계에서 어떻게 보일 것인지는 종종 매우 다른 것들입니다. Domain Model을 사용할 때 비즈니스 오브젝트는 대개 데이터베이스에 저장되는 것과 다른 방식으로 구조화됩니다. 따라서 데이터베이스에서 쉽게 CRUD 할 수 없습니다. 이것은 DataMapper이 나오는 곳입니다.

DataMapper는 Domain 개체를 Recordset에 매핑하거나 그 반대로 매핑합니다. 이렇게하면 도메인 객체와 데이터베이스 구조가 분리되므로 응용 프로그램을 더욱 유지 관리 할 수 ​​있습니다. 두 레이어를 분리 된 상태로 유지하고 두 레이어를 모두 모델링하는 방법에 유연성을 제공합니다 (지속성 및 도메인).