Zend数据映射器设计

我正在使用Zend Framework,并遵循将数据层从域层分离出来的设计模式,在实现Data映射器的方法时引发问题,所以我实现了save() ,它根据域模型是否包含id属性来插入和更新和find()哪些返回记录域对象基于id参数,但如果我需要

  • 搜索表中的所有/某些行并返回所有列
  • 搜索相同的行并返回一个mysql COUNT值
  • 我应该直接使用继承了Zend_Db_Table_Abstract的类来满足这些需求,还是应该为每个需求实现方法?

    我对如何划分符合我需求和未来需求的Data Mapper的功能有点困惑


    您可以添加单个查找器方法,例如

    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语义,而让你指定你的域对象。 尽管如此,这是更多的努力

    另请参阅存储库和规范模式。


    尽管Gordon很可能有正确的答案,但我发现目前我的口味和需求过于复杂。

    我为我的所有域映射器使用了基本映射器类,并且尽可能多地将基本类功能放到了基类中。

    我使用了按列查找方法,在我的所有映射器中工作得很好:

    //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()会更容易。

    链接地址: http://www.djcxy.com/p/56235.html

    上一篇: Zend Data Mapper design

    下一篇: ACL with Domain Object and Data Mapper?