2011-07-08 30 views
7

Tôi đang hát Mẫu bản đồ dữ liệu trong khung công tác Zend. Điều này hoạt động tốt cho đến nay, nhưng bây giờ tôi đã đến một điểm mà tôi cần sự giúp đỡ/ý kiến ​​của bạn. Vì vậy, chúng ta hãy bắt đầu với Mã số:Mẫu bản đồ dữ liệu: Truy vấn phức tạp từ Lớp dịch vụ

Chúng tôi có một bảng với nhiều người:

CREATE TABLE `persons` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(50) NOT NULL, 
    `age` int(3) NOT NULL, 
    `haircolor` varchar(20) DEFAULT NULL, 
    PRIMARY KEY (`id``), 
); 

Bây giờ tôi cố gắng chọn tất cả mọi người, có mái tóc màu nâu. Tôi sử dụng phương pháp sau đây trong ServiceLayer

public function getPeopleByHaircolor($hair) { 
    return $this->getMapper()->fetch('haircolor = ?', $hair); 
} 

Phương pháp trong Mapper trông như thế này:

public function fetch($condition, $value) { 
    $resultSet = $this->getTable()->fetchAll($this->getTable()->select()->where($cond, $value)); 
    $entries = array(); 

    foreach($resultSet as $row) { 
    $entry = new Default_Model_Person(); 
    $entry->id = $row->id; 
    $entry->name = $row->name; 
    [...] 
    } 
    return $entries; 
} 

Tôi nghĩ mình làm theo mẫu với các phương pháp này liệu Mapper ...


Bây giờ vấn đề:

Tôi wa nt để chọn Người, có mái tóc nâu VÀ trẻ hơn 20 tuổi. Vậy làm thế nào tôi có thể làm điều đó? thử của tôi:

public function getTeens($hair) { 
    $rows = $this->getMapper()->fetch('haircolor = ?', $hair); 
    $return = array(); 
    foreach($rows as $row) { 
    if((int)$row->age < 20) $return[] = $row; 
    } 
    return $return; 
} 

Nhưng nếu bạn nhận được nhiều biến, như "những người có mái tóc nâu, trẻ hơn 20yrs và với tên 'Foo Bar", tôi cần ngày càng nhiều phương pháp và/hoặc vòng foreach.


Câu hỏi của tôi:

Làm thế nào bạn sẽ làm điều này trong các mẫu dữ liệu Mapper? Nếu tôi thực hiện một truy vấn SQL nguyên gốc như $ serviceLayer-> mapper-> table-> qry ('SELECT ...'), điều này có phá vỡ Mẫu Mapper dữ liệu không? Tôi không thích những vòng lặp foreach bổ sung đó và cảm thấy như tôi đang làm điều gì sai, vì vậy tôi đã viết câu hỏi này.

Trả lời

6

Thật vậy, đối với hai điều kiện, bạn không thể truy cập vào một điều kiện và sau đó lọc theo cách khác trong khi bạn lặp lại. Nó khiến bạn không có cách tiếp cận rõ ràng cho hơn hai điều kiện. Và việc triển khai bộ điều hợp phân trang trở nên khá lộn xộn.

Dường như với tôi rằng vấn đề là phương thức ánh xạ của bạn fetch() chỉ cho phép một điều kiện duy nhất. Vì vậy:

  1. Sửa chữ ký để hỗ trợ một loạt các điều kiện.

  2. Ngoài ra, bạn có thể tạo ra một phương pháp ánh xạ riêng biệt cho mỗi tăng cường lấy phương pháp, ví dụ: fetchByHairAndAge($hair, $age) vv

+8

tùy chọn thứ 2 thích hợp hơn, vì cho phép tìm kiếm bất kỳ điều kiện nào làm rò rỉ logic miền vào bộ điều khiển và yêu cầu kiến ​​thức về cấu trúc db bên ngoài lớp. Tùy chọn thứ 2 cũng xác định rõ ràng API. –

+0

@Tomas: Thật vậy. Độc đáo giải thích. +1 –

+0

Cảm ơn bạn đã đề xuất! –

1

Theo kinh nghiệm hạn chế của tôi với người vẽ bản đồ dữ liệu tôi đã tìm thấy các phương pháp sau đây để làm việc khá tốt cho các tình huống mà tôi đã gặp phải cho đến thời điểm này:

public function getPeopleByHaircolorAndAge($haircolor, $age, $limit=null, $offset=null) 
{ 
    $people = new PersonCollection; 
    $people->filterByHaircolor($haircolor); 
    $people->filterByAge($age); 
    $people->setLimit($limit); 
    $people->setOffset($offset); 

    $personCollectionMapper = new PersonCollectionMapper; 
    $personCollectionMapper->fetch($people); 

    return $people; 
} 

Bằng cách khởi tạo đối tượng miền trước tiên tôi có thể đọc từ đối tượng khi nó được tiêm vào người lập bản đồ.

Với tôi, đây là cách tiếp cận vượt trội so với việc có nhiều phương thức lập bản đồ trả về đối tượng miền.

+0

nếu tôi cần thêm nhiều điều kiện, tôi sẽ phải thêm một phương thức get ..... mới, với nhiều tham số, nó không thể đọc được, có nội dung trùng lặp. –

Các vấn đề liên quan