Расширенный вопрос: Почему я должен использовать data mapper / Db_Table_Row, где DbTable способен обрабатывать большинство основных задач для обработки данных.
В настоящее время я изучаю ZF v1.11
Для манипуляции с базами данных я создал DbTable для каждой таблицы. Например, таблица «users» представлена Application_Model_DbTable_Users без дополнительных кодов.
При манипулировании данными я могу использовать:
<?php $uTable = new Application_Model_DbTable_Users(); $newUid = $uTable->insert(array('name'=>'Old Name', 'email'=>'')); $user = $uTable->find($newUid)->current(); // Then I can use $user which is instance of Table_Row $user->name = "New Name"; $user->email = "email@addr.com"; $user->save();
Мой вопрос: когда мне нужно определить класс строк (предполагается, что Table_Row упоминается как DataMapper в ZF-Tutorials)
// By, adding this to the DbTable class protected $_rowClass = 'Application_Model_User';
Каковы преимущества наличия класса Row для каждого объекта? Может ли кто-нибудь указать мне на лучшие практики для этого.
Вам не нужно определять собственный Table_Row. Однако это может быть полезно во многих случаях, особенно если вы хотите определить некоторые конкретные методы или свойства для данной строки пользователя. Они также могут улучшить читаемость вашего кода.
Например, в случае таблицы «Пользователи» вы можете определить метод с именем getFullName () в пользовательской строке пользователя как:
public function getFullName() { return $this->firstName . ' ' . $this->lastName; }
Затем, когда вы получаете объект строки пользователя, чтобы получить полное имя пользователя, вы просто выполните:
$user = $uTable->find($newUid)->current(); $fullName = $user->getFullName();
Второй пример – когда у вас есть таблица родительских таблиц, например Адреса. В этом случае вы можете определить метод getAddress в строке пользователя:
public function getAddress() { return $this->findParentRow('Application_Model_DbTable_Addresses'); }
В этом случае вы получите объект Address row для текущего пользователя следующим образом:
$user = $uTable->find($newUid)->current(); $addressRow = $user->getAddress();
Другим примером может быть создание пользовательских методов delete или instert. Предположим, вы хотите, чтобы вы не хотели удалять пользователя admin с помощью метода delete (). Затем вы можете перегрузить метод удаления из Zend_Db_Table_Row следующим образом:
public function delete() { if ('admin' === $this->userRole) { return 0; } return parent::delete(); }
Таким образом, вы не сможете удалить пользователя администратора, просто вызвав delete () для объекта строки пользователя:
$user = $uTable->find($newUid)->current(); $rowsDeleted = $user->delete(); // would be 0 if $user is admin
Это всего лишь три основных примера, показывающих полезность определения ваших собственных классов строк. Но, конечно, они не нужны. Однако, по собственному опыту, они весьма удобны.
В двух словах: речь идет об изоляции.
Zend_Db_Table
– это реализация шлюза данных данных. Он передает CRUD доступ к определенному представлению таблицы через один класс. Он обычно используется с табличным модулем , например классом, который содержит бизнес-логику для записей, обрабатываемых шлюзом.
Zend_Db_Table_Row
– это реализация шаблона шлюза данных строк . Здесь возвращаемые объекты выглядят точно так же, как и запись в базе данных, и они содержат бизнес-логику для работы с этими данными, но они не содержат логику для CRUD с таблицей, из которой они были (это будет ActiveRecord), но агрегируют их.
Строковые шлюзы данных являются точными, если у вас нет слишком большого несоответствия реляционного импеданса объекта . Как объект сохраняется в реляционной базе данных и как он должен выглядеть в объектном мире, часто бывают разные вещи. При использовании модели домена ваши бизнес-объекты обычно структурируются по-другому, чем они хранятся в базе данных. Таким образом, вы не можете легко CRUD их из базы данных. Здесь DataMapper вступает в игру.
DataMapper берет на себя ответственность за сопоставление объектов домена с наборами записей и наоборот. Это упрощает ваше приложение, поскольку оно отделяет объекты домена от структуры базы данных. Он сохраняет их разделенными и дает вам больше гибкости в том, как моделировать оба уровня (постоянство и домен).