2012-05-31 64 views
2

我遵循Zend QuickStart指南,并且被连接到数据库的架构所困惑。我看到4层:Zend框架数据层架构

ModelClass 
ModelClass_Mapper 
ModelClass_DbTable 
Actual MySQL Database 

我使用其中存在一个文件,其具有直接映射到数据库属性,和保存所有的自定义代码的用于钩和数据库动作的扩展类之前的体系结构事件。

我在哪里可以找到为什么它是需要有三个文件是这样一个很好的解释,而不是仅仅有ModelClass继承DBTABLE?

回答

3

ZF快速启动提供了一个数据映射器模式的例子,它似乎与ZF 1.x相当适用。你不需要实现一个Data Mapper来使用Zend_Db。只需使用DbTable模型和Zend_Db_Table_Abstract提供的方法即可获得相当好的功能。

要解释一下:

Application_Model_Guestbook:会是一个简单的域模型(与你互动的对象)。

Application_Model_GuestbookMapper:将数据映射器映射到数据库列的领域模型的propeties。

Application_Model_DbTable_Guestbook:是网关模式,提供数据库和数据库适配器之间的连接。这是您可以指定数据库表的选项以及与其他表的关系的位置。

我花了采埃孚和模型的一点经验之前,我想通了,数据映射器如何应用到我的应用程序。当我开始构建依赖于多个数据库表的对象时,我真的开始理解这些部分如何组合在一起。
'

您会注意到许多有经验的ZF开发人员推荐了Doctrine或其他一些ORM,对于他们来说这可能是正确的选择(并且似乎是一些反射)。我只是觉得我不应该开始使用ORM,除非我至少了解ORM正在做什么的基础知识。

[编辑]

使用fetchall()在碱映射类等效的方法,从我的表中的特定映射器通过在Zend_Db_Table_Abstract的实例的__constructor

public function findAll($order = NULL) { 
     $select = $this->_getGateway()->select(); 
     if (!is_null($order)) { 
      $select->order($order); 
     } 
     $rowset = $this->_getGateway()->fetchAll($select); 
     $entities = array(); 
     foreach ($rowset as $row) { 
      //abstract method required in each table mapper, this instantiates the domain model 
      $entity = $this->createEntity($row); 
      //identiy map allows lazy loading of certain members 
      $this->_setMap($row->id, $entity); 
      $entities[] = $entity; 
     } 
     //returns an array of domain models instead 
     return $entities; 
    } 

的createEntity()方法

public function createEntity($row) { 

     $data = array(
      'id'  => $row->id, 
      'name' => $row->name, 
      'art' => $row->art, 
      'year' => $row->year,     
     ); 

     $entity = new Music_Model_Album($data); 
     //set artist id to reference map for lazy loading 
     $entity->setReferenceId('artist', $row->artist_id); 
     return $entity; 
    } 

好运

+0

好吧,我发现Application_Model_DbTable_Guestbook非常苗条,主要包含诸如表名和外键约束之类的东西,以及通过继承提供通用的非sql依赖方法,如插入,更新等。 –

+0

我仍然对Application_Model_GuestBookMapper的使用感到困惑。在这个例子中,有一些方法,fetchAll(),find(),它从db_table映射到留言簿对象,但是这似乎违反了DRY。不应该这样做,因为Mapper.Property =“StringNameofDBTableProperty”;还是一些这样的? 看起来,重写每个方法的映射效率极低,特别是在表列名称与对象属性名称相同的情况下。 –

+0

在正常使用情况下,您可以重写这些方法,以便您可以创建域模型的实例,而不仅仅是从数据库中获取结果集。很多时候,基类对大多数方法都有效,但是可扩展来处理每个模型需要执行业务逻辑的数据变化。我在我的答案中添加了一个例子。 – RockyFord

0

个人而言,尽管我很喜欢Zend框架,我觉得在数据层库是相当差的。我现在使用的是DoctrineBisna相结合来整合这两者。也许你应该看看这些呢?

0

的溶液的Zend_Db_Table是»表数据网关模式的实现。该解决方案还包含一个实现“行数据网关”模式的类。

你可以看看它的图案Table Data GatewayRow Data Gateway

2

一个很好解释这里给出:http://martinfowler.com/eaaCatalog/dataMapper.html

短报价:

数据映射器是一个软件层它将内存中的对象与数据库分开。它的责任是在两者之间传输数据,并将它们彼此隔离。使用Data Mapper,内存中的对象甚至不需要知道存在数据库;他们不需要SQL接口代码,当然也不需要知道数据库模式。 (数据库模式总是对使用它的对象一无所知。)由于它是Mapper(473)的一种形式,因此数据映射器本身对于域图层甚至是未知的。