您是否可以帮助扩展一点关于Zend快速入门:在教程中,我们使用Mapper更新单个留言簿。如果我想更新多个留言簿该怎么办?基于某些条件呢?
例如,我有一个动作要删除所有在2012-12-21之前创建的留言簿。我应该更新什么来实现这个目标?
我的方法有意义吗?
// application/models/GuestbookMapper.php
class Application_Model_GuestbookMapper
{
public function deleteByCreatedBefore($date)
{
$this->getDbTable()->deleteByCreatedBefore($date);
}
}
// application/models/DbTable/Guestbook.php
class Application_Model_DbTable_Guestbook extends Zend_Db_Table_Abstract
{
public function deleteByCreatedBefore($date) {
$where = $this->getAdapter()->quoteInto('created < ?', $date);
$this->delete($where);
}
}
谢谢,
如果你正在使用快速启动模型/映射器,并希望保持真实的数据映射器范式,你不会有任何在你的Application_Model_DbTable_Guestbook
除了属性('name', 'primary'…)。DbTable模型将作为该单个表的数据库适配器存在。
你的delete函数将放在映射器中。
class Application_Model_GuestbookMapper
{
public function deleteByCreatedBefore($date)
{
$where = $this->getDbTable()->quoteInto('created < ?', $date);
//delete() returns num of rows deleted
$this->getDbTable()->delete($where);
}
}
这可以工作,但可能不是实现所需功能的最佳/最安全的方法。
这个特定的Data Mapper示例非常简单,可能对某些人有些误导。当数据库行和域模型(Application_Model_Guestbook)映射1到1(一个数据库列到一个模型属性)时,Mapper的Guestbook示例实际上并不是一个很好的映射器表示。
当您需要将多个数据库表映射到单个域模型时,Data Mapper开始发挥作用。了解到您的域模型(Application_Model_Guestbook)在每次调用delete()时可能不得不影响多个数据库表,因此delete()函数的结构非常重要。如何使用映射器完成删除操作?
First: update Application_Model_GuestbookMapper::fetchAll()
接受一个$where
参数,我通常设置这种类型的函数接受一个数组设置列和值。
//accepted parameters: Zend_Db_Table::fetchAll($where = null, $order = null, $count = null, $offset = null)
//accepts array (column => value )
public function fetchAll(array $where = null)
{
$select = $this->getDbTable()->select();
if (!is_null($where) && is_array($where)) {
//using a column that is not an index may effect database performance
$select->where($where['column'] = ?, $where['value']);
}
$resultSet = $this->getDbTable()->fetchAll($select);
$entries = array();
foreach ($resultSet as $row) {
$entry = new Application_Model_Guestbook();
$entry->setId($row->id)
->setEmail($row->email)
->setComment($row->comment)
->setCreated($row->created);
$entries[] = $entry;
}
return $entries;
}
第二:重构您的Application_Model_GuestbookMapper::deleteByCreatedBefore()
以接受fetchAll()
的输出(实际上,只需构建一个delete()函数来接受输出:留言簿对象数组)
//accepts an array of guestbook objects or a single guestbook object
public function deleteGuestbook($guest)
{
if (is_array($guest) {
foreach ($guest as $book) {
if ($book instanceof Application_Model_Guest){
$where = $this->getDbTable()->quoteInto('id = ?', $book->id);
$this->getDbTable()->delete($where);
}
}
} elseif ($guest instanceof Application_Model_Guest) {
$where = $this->getDbTable()->quoteInto('id = ?', $guest->id);
$this->getDbTable()->delete($where);
} else {
throw new Exception;
}
}
将域对象作为对象删除将变得更加重要,因为您必须考虑删除对象将如何影响其他对象或持久性(数据库)范例。在某些情况下,您可能会遇到这样的情况:如果其他对象仍然存在,您不希望删除成功。
这只是我的一个意见,但我希望它有所帮助。