-1

Zend クイックスタートについて少し補足していただけませんか: チュートリアルでは、Mapper を使用して1 つのゲストブックを更新します。複数のゲストブックを更新したい場合はどうすればよいですか? そして、いくつかの条件に基づいていますか?

たとえば、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);
    }
}

ありがとう、

4

1 に答える 1

0

Application_Model_DbTable_Guestbookクイックスタート モデル/マッパーを使用していて、そのデータ マッパー パラダイムに忠実であり続けたい場合は、プロパティ ('name'、'primary'...) 以外には何もありません。DbTable モデルは、その単一のテーブルのデータベース アダプターとして存在します。

削除機能はマッパーに配置されます。

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 (1 つのデータベース列を 1 つのモデル プロパティに) にマップするため、実際にはマッパーの適切な表現ではありません。

Data Mapper が輝き始めるのは、複数のデータベース テーブルを単一のドメイン モデルにマップする必要がある場合です。ドメイン モデル (Application_Model_Guestbook) は、delete() が呼び出されるたびに複数のデータベース テーブルに影響を与える可能性があることを理解すると、delete() 関数の構造が重要になります。

マッパーで削除するにはどうすればよいですか?

まず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;
    }

2番目:Application_Model_GuestbookMapper::deleteByCreatedBefore()出力を受け入れるようにリファクタリングしますfetchAll()(実際には、出力を受け入れるdelete()関数を構築する方が簡単です:Guestbookオブジェクトの配列)

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

ドメイン オブジェクトをオブジェクトとして削除することは、オブジェクトの削除が他のオブジェクトまたは永続化 (データベース) パラダイムにどのように影響するかを考慮する必要があるため、より重要になります。ある時点で、他のオブジェクトがまだ存在する場合に削除を成功させたくないという状況に遭遇するでしょう。

あくまで一意見ですが参考になれば幸いです。

于 2012-12-26T11:23:12.063 に答える