1

私はZendFrameworkを使用しており、データレイヤーをドメインレイヤーから分離するデザインパターンに従って、データマッパーのメソッドを実装するときに問題が発生するため、save()ドメインモデルにidプロパティが含まれているかどうかに基づいて挿入と更新を実装しましfind()た。 idパラメータに基づいてドメインオブジェクトを記録しますが、必要な場合はどうなりますか

  1. テーブル内のすべて/一部の行を検索し、すべての列を返します
  2. 同じ行を検索し、mysqlCOUNT値を返します

これらのニーズに継承されたZend_Db_Table_Abstractのクラスを直接使用する必要がありますか、それともすべてのニーズにメソッドを実装する必要がありますか?

自分のニーズと将来のニーズに合うようにデータマッパーの機能を分割する方法について少し混乱しています

4

2 に答える 2

2

個々のファインダーメソッドを追加できます。

class PersonMapper
{
    … // other code

    public function findByLastName()
    {
        // … fetch rowset and map them
    }

    public function countByLastName() 
    {
    …

ただし、複数の列をクエリする必要がある場合、または任意の基準でCRUDを処理する必要がある場合は、すぐに手に負えなくなります。あなたは次のような方法を望んでいません

 public function findByLastNameAndBirthdayAndMaritalStatus()

簡単な解決策はZend_Db_Table_Select、クエリを作成し、それらをData Mapperに渡して、たとえばDataMapperで実行およびマッピングすることです。

public function getSelect()
{
    return $this->personTable->select();
}

public function findBy(Zend_Db_Table_Select $select)
{
    $people = $this->personTable->fetchAll($select);
    // map people to People objects
}

Mapperが代わりにPersonQueryBuilderを返し、受け入れることでこれをさらに抽象化できます。これにより、SQLセマンティクスが内部に隠され、代わりにドメインオブジェクトに対して指定できます。しかし、それはもっと努力です。

リポジトリと仕様パターンもご覧ください。

于 2012-10-10T18:52:31.870 に答える
0

ゴードンが正しい答えを持っている可能性が非常に高いのと同じくらい、私はそれが私の好みと現在のニーズにとって非常に複雑であると感じています。

私はすべてのドメインマッパーにベースマッパークラスを使用しており、可能な限り多くの機能をベースクラスに組み込んでいます。

私はすべてのマッパーでかなりうまく機能する列検索メソッドを使用しています。

//from abstract class Model_Mapper_Abstract

//The constructor of my base class accepts either a dbtable model
// or the name of a table stored in the concrete mapper tablename property. 
 public function __construct(Zend_Db_Table_Abstract $tableGateway = null)
    {   
        if (is_null($tableGateway)) {   
            $this->tableGateway = new Zend_Db_Table($this->tableName);
        } else {    
            $this->tableGateway = $tableGateway;
        }
    }
/**
 * findByColumn() returns an array of entity objects
 * filtered by column name and column value.
 * Optional orderBy value.
 *
 * @param string $column
 * @param string $value
 * @param string $order optional
 * @return array of entity objects
 */
public function findByColumn($column, $value, $order = null)
    {
        //create select object
        $select = $this->getGateway()->select();
        $select->where("$column = ?", $value);
        //handle order option
        if (!is_null($order)) {
            $select->order($order);
        }
        //get result set from DB
        $result = $this->getGateway()->fetchAll($select);
        //turn DB result into domain objects (entity objects)
        $entities = array();
        foreach ($result as $row) {
            //create entity, handled by concrete mapper classes
            $entity = $this->createEntity($row);
            //assign this entity to identity map for reuse if needed
            $this->setMap($row->id, $entity);
            $entities[] = $entity;
        }
        //return an array of entity objects
        return $entities;
    }

少なくともこれがアイデアジェネレータとして役立つことを願っています。SQL Count()また、これと同様のメソッドでステートメントを実装する場合は、select()をビルドするときにZend_Db_Expr()を使用すると簡単になります。

于 2012-10-11T10:16:09.333 に答える