Я пою шаблон Data Mapper в Zend Framework. Пока это хорошо, но теперь я дошел до того, что мне нужна ваша помощь / мнение. Итак, давайте начнем с кода:
У нас есть таблица с несколькими людьми:
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``), );
Теперь я стараюсь выбирать всех людей, имеющих коричневые волосы. Я использую следующий метод в ServiceLayer
public function getPeopleByHaircolor($hair) { return $this->getMapper()->fetch('haircolor = ?', $hair); }
Метод в Mapper выглядит следующим образом:
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; }
Я думаю, что я следую шаблону Data Mapper с помощью этих методов …
Теперь проблема:
Я хочу выбрать Лица, у которых есть коричневые волосы И моложе 20 лет. Итак, как я могу это сделать? Моя попытка:
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; }
Но если вы получите больше переменных, например «люди с коричневыми волосами, моложе 20yrs и с именем« Foo Bar », мне нужно все больше и больше методов и / или foreach.
Мой вопрос:
Как вы это сделаете в шаблоне Data Mapper? Если я использую собственный SQL-запрос, например $ serviceLayer-> mapper-> table-> qry ('SELECT …'), это нарушает шаблон Data Mapper? Мне не нравятся эти дополнительные петли foreach, и мне кажется, что я делаю что-то неправильно, поэтому я написал этот вопрос.
Действительно, для двух условий нецелесообразно запрашивать одно условие, а затем фильтровать на другом, пока вы повторяете. Это не дает вам четкого подхода к более чем двум условиям. И реализация адаптеров разбиения на страницы становится довольно грязной.
Мне кажется, что проблема заключается в том, что метод mapper fetch()
поддерживает только одно условие. Так:
Измените подпись для поддержки множества условий.
Кроме того, вы можете создать отдельный метод сопоставления для каждого метода расширенной выборки, например: fetchByHairAndAge($hair, $age)
и т. Д.
В моем ограниченном опыте работы с картотеками данных я нашел следующий подход к работе достаточно хорошо для сценариев, с которыми я столкнулся до сих пор:
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; }
Сначала создавая экземпляр объекта домена, у меня есть возможность установить фильтры и другие переменные, которые может отобразить преобразователь данных из объекта, когда он вводится в устройство отображения.
Для меня это был превосходный подход до сих пор по сравнению с несколькими методами mapper, которые возвращают объект домена.