2012-06-29 3 views
12

필자는 DAO 패턴을 올바르게 사용하고 있는지, 더 구체적으로는 매퍼 클래스에 도달 할 때까지 추상 db 지속성을 유지해야 하는지를 파악하려고합니다. PDO를 데이터 액세스 추상화 개체로 사용하고 있지만 때로는 쿼리를 너무 많이 추상화하려고하는지 궁금해합니다.PHP 데이터 액세스 객체

내가 선택한 쿼리를 추상화하는 방법을 포함 시켰지만 모든 CRUD 작업에 대한 메서드를 작성했습니다. 그래서

class DaoPDO { 

    function __construct() { 

     // connection settings 
     $this->db_host = ''; 
     $this->db_user = ''; 
     $this->db_pass = ''; 
     $this->db_name = ''; 


    } 

    function __destruct() { 

     // close connections when the object is destroyed 
     $this->dbh = null; 

    } 


    function db_connect() { 

     try { 

      /** 
      * connects to the database - 
      * the last line makes a persistent connection, which 
      * caches the connection instead of closing it 
      */ 
      $dbh = new PDO("mysql:host=$this->db_host;dbname=$this->db_name", 
          $this->db_user, $this->db_pass, 
          array(PDO::ATTR_PERSISTENT => true)); 


      return $dbh; 

     } catch (PDOException $e) { 

      // eventually write this to a file 
      print "Error!: " . $e->getMessage() . "<br/>"; 
      die(); 

     } 


    } // end db_connect()' 



    function select($table, array $columns, array $where = array(1=>1), $select_multiple = false) { 

     // connect to db 
     $dbh = $this->db_connect(); 

     $where_columns = array(); 
     $where_values = array(); 

     foreach($where as $col => $val) { 

      $col = "$col = ?"; 

      array_push($where_columns, $col); 
      array_push($where_values, $val); 

     } 


     // comma separated list 
     $columns = implode(",", $columns); 

     // does not currently support 'OR' arguments 
     $where_columns = implode(' AND ', $where_columns); 



     $stmt = $dbh->prepare("SELECT $columns 
           FROM $table 
           WHERE $where_columns"); 


     $stmt->execute($where_values); 

     if (!$select_multiple) { 

      $result = $stmt->fetch(PDO::FETCH_OBJ); 
      return $result; 

     } else { 

      $results = array(); 

      while ($row = $stmt->fetch(PDO::FETCH_OBJ)) { 

       array_push($results, $row); 

      } 

      return $results; 

     } 



    } // end select() 


} // end class 

, 내 두 가지 질문 :

  1. 이것은 DAO의 올바른 사용, 아니면 나는 그것이 목적의 오해는 무엇입니까?

  2. 이 정도까지 쿼리 프로세스를 불필요하거나 드문 경우가 있습니까? 나는 일을 너무 쉽게 만들려고 노력하는 것 같은 가끔

답변

20

그것은 더보기보다 . DAO가 취할 수있는 많은 형태가 있지만 목표는 비즈니스 로직을 지속성 메커니즘과 분리하는 것입니다. db_connectselect과 함께

Business Logic 
     | 
     v 
Data Access Object 
     | 
     v 
Persistence Layer 

DAO를 너무 가깝게 지속 층 본따서. 제네릭 DAO의 가장 간단한 형태는 지속성 메커니즘의 내부를 노출시키지 않고 객체 수준에서 기본 CRUD 작업을 제공하는 것입니다.

interface UserDao 
{ 
    /** 
    * Store the new user and assign a unique auto-generated ID. 
    */ 
    function create($user); 

    /** 
    * Return the user with the given auto-generated ID. 
    */ 
    function findById($id); 

    /** 
    * Return the user with the given login ID. 
    */ 
    function findByLogin($login); 

    /** 
    * Update the user's fields. 
    */ 
    function update($user); 

    /** 
    * Delete the user from the database. 
    */ 
    function delete($user); 
} 

비즈니스 개체가 기본 PDO 모델 개체 인 경우 DAO에서 반환 할 수 있습니다. 선택한 지속성 메커니즘에 따라 이상적이지 않을 수도 있음을 기억하십시오. 필자는 PDO로 일한 적이 없지만 비즈니스 로직을 PDO API에 묶지 않고 표준 PHP 객체를 생성하는 다른 ORM 도구와 유사하다고 가정합니다. 아마 여기 괜찮을거야.

mysqli 라이브러리에 직접 액세스하여 지속성을 구현하는 경우, 예를 들어 데이터를 결과 집합과 자신의 모델 개체로 복사 할 수 있습니다. 이것은 DAO가 비즈니스 로직에서 벗어나게하는 일입니다.

DAO 용 인터페이스를 사용하면 이제 PDO, Doctrine, 원시 SQL 등 다양한 지속성 프레임 워크에 대해 DAO를 구현할 수 있습니다. 프로젝트 중간에서 방법을 전환 할 가능성은 없지만 인터페이스를 사용하는 비용은 다른 이점과 비교할 때 무시해도됩니다. 단위 테스트에서 모의를 사용합니다.

+0

그래서 도메인 모델의 각 도메인 객체는 CRUD 연산을위한 관련 Dao 객체를 가질 수 있습니까? – jerry

+0

@saddog - 각 루트 수준 개체, 예. 예를 들어'Order'와'LineItem' 자식 목록은'OrderDao'를 통해 함께 저장됩니다. 안타깝게도 도메인 모델 객체를 유지하는 방법과 비즈니스 로직을 거의 완전히 분리 할 수는 없습니다. –

+0

좋아요, 실제로 질문이 하나 더 생기면 제가 받아 들여 현상금을 드리겠습니다. LineItem 하위 항목에 대해 언급하고 있으며이를 애플리케이션에서 올바르게 처리하고 싶습니다.이 아이들은 db (LineItem 테이블)의 테이블에 매핑되고 Dao에 의해 Order 도메인 개체로 통합됩니까? 즉, DaoUser의 createObject 메소드가이 두 객체를 함께 가져 오는 것입니까? – jerry

0
  1. 이 반드시 필요한 건 아니지만, 확실히 일반적인 관행입니다 ... 생각합니다. 많은 도서관이있다 그 추상적 절대로 안돼요 더 당신이 data access object보다는 (자체 영속 계층 인) PDO 위에 지속성 추상화 계층을 구축하는 것 같은 당신이 :)하고있는 것은