数据映射器和Zend框架

3

我正在我的Zend Framework Web应用程序中实现数据映射器设计模式,一切都很顺利,我真的很喜欢在Zend中使用数据映射器,而不仅仅是应用Row Gateway模式,但是我在架构方面遇到了问题。 我不确定如何以OOP方式引用和处理我的数据映射器中的外键约束。

因此,我有我的Model类、DbTable类和Mapper类。 我应该将所有外键关系放在我的DbTable类中,在这种方式下,我可以使用findDependentRowset()函数在我的Mapper中检索,还是更好的方法是在我的Mapper中实例化依赖类。 在使用数据映射器模式映射外键时,最佳的OOP实践是什么?


如果你有很多阻抗不匹配的问题,考虑使用ORM,比如Doctrine2。 - Gordon
我已经开始使用数据映射器实现项目,唯一的问题是如何处理外键映射,无论是实例化对象还是让DbTable知道数据库模式。 - Mythriel
我的实现大致如下:Model
  • 与您所说的相同,但没有任何函数,只有用于访问 Model 属性的 setter 和 getter
DbTable
  • 这里没有任何函数,只是子类化 Zend_Db_Table_Abstract 并为表提供 id 和 name
DataMapper
  • 这里是核心 - 我在这里拥有所有的函数,并检索 DbTable 类并使用 Model 类设置属性
我希望我的系统尽可能松耦合,所以问题在于我的应用程序中的外键关系。
- Mythriel
2个回答

4
我会选择DataMapper作为其他两种的替代方案,因为它们本身不应该知道ID,尽管对于关系调用者来说通常是必需的。
Model
- Property accessors and private property data holders
- Functions regarding correct usage of model
- Relatioship callers (calls relationship fetches in the DbTable to get parents or children rows)or returns cached data

DbTable
- Provides all static functions used to query data and instanciate the related Models such as :getById, getByName, getByComplexSearch, etc
- Provides all static relationship loaders such as: getParents, getChildrens and any other version you need

DataMapper
- Does the real meat and provides the getObjects method which accepts either a query part or a full query and loads the data into the ModelObjects and reads it back into a update, insert, delete query when needed
- Datamapper should be in charge of checking for relationship faults when inserting, updating or deleting using transactions if in InnoDB.

这有意义吗?

2
我过去在我的系统中使用了findDependentRowset,但现在不再使用了!在大多数情况下,这是一种资源浪费。表连接应该在SQL语句中完成。
请查看我在这里的答案:Hand made queries vs findDependentRowset 我仍然远离使用Doctrine或Propel(我从未需要过)。也许有一天。(现在使用Doctrine 2。所以...我建议你现在也这样做)

旧答案

在使用Zend Framework几年后,我遇到了以下架构:

1)我有一个抽象映射器,所有我的映射器都扩展它:Zf_Model_DbTable_Mapper

2)我还有一个抽象模型(域对象),类似于行数据网关,但它不是网关。它是通用的域对象:Zf_Model

3)当填充对象图(SQL连接)时,一个映射器委托给负责给定对象的其他映射器。

例子

这个方法来自抽象映射器:

    public function getById($id) 
    {


        $tableGateway = $this->getTable();

        $row = $tableGateway->fetchRow('id =' . (int) $id);

        if (!$row) 
            retur null;

        $row = $row->toArray();

        $objectName = $this->getDomainObjectName();
        $object = new $objectName($row['id']);
        $object->populate($row);

        return $object;    
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接