2012-06-29 77 views
12

Tôi đang cố gắng tìm hiểu xem tôi có đang sử dụng mẫu DAO chính xác không và cụ thể hơn, sự tồn tại của db trừu tượng sẽ như thế nào khi đến lớp bản đồ của tôi. Tôi đang sử dụng PDO làm đối tượng trừu tượng truy cập dữ liệu, nhưng đôi khi tôi tự hỏi liệu tôi có đang cố gắng trừu tượng hóa các truy vấn quá nhiều hay không.Đối tượng truy cập dữ liệu PHP

Tôi vừa bao gồm cách tôi trừu tượng các truy vấn chọn lọc, nhưng tôi đã viết các phương thức cho tất cả các hoạt động 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 

Vì vậy, hai tôi hỏi:

  1. Đây có phải là việc sử dụng đúng đắn về một DAO, hay tôi hiểu sai mục đích của nó?

  2. Việc trừu tượng quá trình truy vấn ở mức độ này không cần thiết hay thậm chí không phổ biến? Đôi khi tôi cảm thấy như tôi đang cố gắng để làm cho mọi việc quá dễ dàng ...

Trả lời

20

Có vẻ như bạn đang xây dựng một lớp trừu tượng bền vững trên PDO (chính nó là một lớp kiên trì) thay vì data access object . Mặc dù có nhiều hình thức mà DAO có thể thực hiện, mục tiêu là tách logic nghiệp vụ của bạn khỏi cơ chế kiên trì.

Business Logic 
     | 
     v 
Data Access Object 
     | 
     v 
Persistence Layer 

Một DAO với db_connectselect được mô hình hóa quá chặt chẽ sau khi lớp kiên trì. Dạng đơn giản nhất của một DAO chung là cung cấp các hoạt động CRUD cơ bản ở mức đối tượng mà không để lộ các bên trong của cơ chế bền vững.

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); 
} 

Nếu đối tượng doanh nghiệp của bạn là đối tượng mô hình PDO cơ bản, bạn có thể trả lại từ DAO. Lưu ý rằng tùy thuộc vào cơ chế kiên trì cơ bản bạn chọn, điều này có thể không lý tưởng. Tôi đã không làm việc với PDO nhưng giả sử nó tương tự như các công cụ ORM khác để tạo ra các đối tượng PHP chuẩn mà không buộc logic nghiệp vụ vào API PDO. Vì vậy, bạn có thể không sao ở đây.

Nếu bạn đã thực hiện kiên trì bằng cách truy cập trực tiếp vào thư viện mysqli, bạn muốn sao chép dữ liệu vào/từ bộ kết quả thành đối tượng mô hình của riêng bạn. Đây là công việc của DAO để giữ nó ra khỏi logic kinh doanh.

Bằng cách sử dụng giao diện cho DAO, bây giờ bạn có thể triển khai nó cho các khung công tác tồn tại khác nhau: PDO, Doctrine, SQL thô, bất cứ điều gì. Mặc dù bạn không thể chuyển đổi giữa các dự án nhưng chi phí sử dụng giao diện là không đáng kể so với các lợi ích khác của nó, ví dụ: sử dụng mô hình thử nghiệm đơn vị.

+0

Vì vậy, mỗi đối tượng tên miền trong Mô hình miền có thể/nên có đối tượng Dao có liên quan cho các hoạt động CRUD sau đó? – jerry

+0

@saddog - Mỗi đối tượng cấp cơ sở, có. Ví dụ, một 'Order' và danh sách các con' LineItem' của nó có thể được lưu trữ cùng nhau thông qua 'OrderDao'. Thật không may, bạn hiếm khi có thể * cô lập hoàn toàn logic nghiệp vụ từ cách bạn tồn tại các đối tượng mô hình miền. –

+0

Được rồi, điều đó thực sự mang lại một câu hỏi nữa, và sau đó tôi sẽ chấp nhận và cung cấp cho bạn tiền thưởng. Bạn đề cập đến trẻ em LineItem và tôi muốn chắc chắn rằng tôi sẽ xử lý những điều này một cách chính xác trong ứng dụng của tôi.Những đứa trẻ này có ánh xạ tới các bảng trong db (một bảng LineItem) và chỉ được hợp nhất trong đối tượng miền Order bởi Dao không? tức là một phương thức createObject trong DaoUser sẽ là phương thức kết hợp hai đối tượng này lại với nhau? – jerry

0
  1. Nó không nhất thiết cần thiết, nhưng nó chắc chắn thực tế phổ biến. Có rất nhiều thư viện trừu tượng waaaaay hơn những gì bạn đang làm :)
Các vấn đề liên quan