2011-11-22 3 views
1

우리 애플리케이션의 매핑 구조를 작업하는 동안 코드 일관성 문제가 발생했습니다. Zend_Db_Select 클래스 ($ select-> from ('table') -> where ('id = ?, 1)와 같은 함수를 사용하여 선택 쿼리를 만드는 것은 쉬운 일이지만 업데이트/삭제 쿼리에는 작동하지 않습니다. select를 빌드하는 것처럼 Zend_Db_Update 나 Zend_Db_Delete와 같은 클래스가 아니므로 아래 코드에서 볼 수있는 것처럼 Zend_Db_Select 클래스를 확장했습니다.이 코드는 Zend_Db_Select 클래스를 확장하는 사용자 정의 클래스를 보여줍니다 이 기본되지 않는 이유는Zend_Db_Select 업데이트/삭제 쿼리의 경우

<?php 
class Unica_Model_Statement extends Zend_Db_Select 
{ 
    public function __construct($oMapper) 
    { 
     parent::__construct($oMapper->getAdapter()); 
     $this->from($oMapper->getTableName()); 
    } 


    /** 
    * @desc Make a string that can be used for updates and delete 
    *  From the string "SELECT `column` FROM `tabelnaam` WHERE `id` = 1" only the part "`id = `" is returned. 
    * @return string 
    */ 
    public function toAltString() 
    { 
     $sQuery = $this->assemble();  // Get the full query string 
     $sFrom = $this->_renderFrom(''); // Get the FROM part of the string 

     // Get the text after the FROM (and therefore not using the "SELECT `colname`" part) 
     $sString = strstr($sQuery,$sFrom); 

     // Delete the FROM itself from the query (therefore deleting the "FROM `tabelnaam`" part) 
     $sString = str_replace($sFrom, '', $sString); 

     // Delete the word "WHERE" from the string. 
     $sString = str_replace('WHERE', '', $sString); 

     return $sString; 
    } 
} 

################################################ 
# Below code is just to demonstrate the usage. # 
################################################ 

class Default_IndexController extends Zend_Controller_Action 
{ 
    public function indexAction() 
    { 
     $person = new Unica_Model_Person_Entity(); 
     $statement = new Unica_Model_Statement($person->getMapper()); 
     $statement->where('id = ?' , 1); 
     $person->getMapper()->delete($statement); 
    } 
} 

class Unica_Model_Person_Mapper 
{ 
    public function delete($statement) 
    { 
     $where = $statement->toAltString(); 
     $this->getAdapter()->delete($this->_tableName,$where); 
    } 
} 

모두가이 클래스를 사용하여 잘 작동하지만 사용되는 방법을 보여 하단에 최소한의 예제 코드와 함께. 우리가 어쩌면 뭔가가 있다면 우리가 궁금해. 가지고 있습니까 갱신/선택을위한 클래스를 삭제하고이 클래스를 사용하면 다른 곳에서 문제가 발생합니까?

조언을 주시면 감사하겠습니다. 사전에 감사합니다,

Ilians

답변

2

클래스는 괜찮습니다 당신은 미래에 너무 많이 진화시키지 않을 것입니다. 귀하의 접근 방식은 Zend_Db_Select 클래스의 자동 견적에서 이익을 얻는 것이라고 가정합니다. "은을 사용하여, (이후 엔티티 객체를 폐기 일부 데이터를받는 것

  • 내 소견 그러나 그것은 수정하거나 확장해야 경우 확장 문제 이어질 수 일부 디자인 함정있다 from 절).
  • select 쿼리의 SQL 출력을 직접 조작하기 때문에 위험 할 수 있습니다. 형식이 변경되고 where 절에 더 많은 요소를 포함해야하는 경우 코드가 변경 사항을 적용하기 위해 상당히 "진흙 투성이"가 될 수 있습니다.

내 접근 방식은 코드에서 직접 where 절을 사용하는, 그리고 그것을 필요의 어디를 인용 것입니다. 그것은 나에게 덜 깨끗한 것처럼 보이지 않습니다. 다음과 같은 뭔가 :

private function myDelete($tableName, $fieldName, $fieldValue) 
{ 
    $this->db->delete($tableName, $fieldName . ' = ' . $db->quote($fieldValue)); 
} 

편집 : 결국

$db->delete('tablename', 'id = ' . $db->quote('1')); 

, 당신은 방법 또는 클래스에 그것을 심지어 추상, 그런 식으로, 사방에 뭔가를 $db->quote() 전화를 확산하는 것을 방지하기 위해 수 : where 부분에 여러 절을 포함 시키면 조금 복잡해지며 특정 응용 프로그램에 따라 유연성이 얼마나 달라질 수 있습니다.도움이

private function myDelete($tableName, array $fields) 
{ 
    $whereClauses = array(); 
    foreach ($fields as $fieldName => $fieldValue) { 
     $whereClauses[] = $fieldName . ' = ' . $db->quote($fieldValue); 
    } 
    $this->db->delete($tableName, implode(' AND ', $whereClauses)); 
} 

$this->myDelete('tablename', array('id' => '1', 'name' => 'john')); 

희망, 답장을 보내

+0

감사합니다, 당신은 오른쪽 따옴표에 대해 위치 : 예를 들어, 여러 "AND로"절에 대한 가능한 솔루션은 다음이 될 수 있습니다. 나는 프로그래머가 모든 것을 인용하는 것을 귀찮게하지 않아도되도록 자동으로 모든 것을 인용하려고 노력하고있다. (그가 잊어 버렸다하더라도 그것은 안전하다.) 그러나 myDelete 함수는 어디에서 여러 값으로 작동합니까? Like : "id = 3 OR adress = 'test'AND 언어! = 'EN' – Ilians

+0

WHERE 절이 얼마나 복잡한 지에 따라 코드를 어느 정도 수정해야합니다. – dinopmi

+0

나는 비슷한 접근법을 시도했지만 유사한 배열 키의 문제에 봉착했다. 상황 : 배열 ( 'id'=> 3, 'ID'=> 4 ) 는 posibilities 어레이 ( 보다 활성화하기 위해 비록처럼 사용 "ID =? => 3 'ID =? => 4 ) – Ilians

1

내가 Zend_Db_Select이 CUD 방법을 제공하지 뒤에 정확한 이유를 잘 모릅니다. 명백한 설명은 입니다.을 선택한다는 것은 동적 쿼리 구축을 위해서만 사용해야한다는 것을 의미합니다. 삽입, 업데이트 및 삭제하려면 Zend_Db_TableZend_Db_Table_Row 또는 일반 Zend_Db_StatementZend_Db_Adapter 또는 프록시 방법을 사용하십시오. 당신이 확신하는 경우 그렇게 말

그러나, 나는 Zend_Db_Select을 확장하고 (당신이 처음에하고 싶은 일을 나던 다른 구성 요소와 같은) 그것에게 당신의 필요를 조정 아무 문제가 없다고 생각

관련 문제