使用Zend_Db和多个表

时间:2010-05-29 15:32:25

标签: php oop zend-framework zend-db

我有一个规范化的数据库,用于存储互联网上文​​件的位置。文件可能有多个位置分布在不同的站点上。我将URL存储在两个部分(Site.UrlStart,FileLocation.UrlEnd)。 UrlEnd是该文件的唯一部分(对于该站点)。

简化的Db结构:

http://img231.imageshack.us/img231/9134/dblayout.jpg

我正在使用Zend_Db作为我的ORM(如果是这样),其中包含从Zend_Db_Table_Abstract继承的表的类。

问题是检索位置数据(例如url)需要使用多个表,并且据我所知,我要么必须使用两个表类(从而暴露我的表结构)或散布sql在我的应用程序中,这些都听起来很吸引人。

我能看到的唯一解决方案是创建一个像Zend_Db_Table_Abstract(也许从它继承?)的façade,并隐藏数据实际上在两个表上的事实。

我的问题如下:

  • 我是否正在朝着正确的方向创建一个外观类(还有其他选择)吗?
  • 外观类是否应继承自Zend_Db_Table_Abstract

1 个答案:

答案 0 :(得分:10)

除了非常简单的用例之外,Zend Db Table并不是一个真正的ORM。它意味着与系统中的每个表密切相关。因此,每个表都有一个Zend_Db_Table类。

要管理更大的图片,您需要其他类型的课程。

所以,是的,你在使用一种外观方面是正确的。

但是,我不会让它继承Zend_Db_Table_Abstract,因为它有一套非常不同的职责。

可能值得研究一下Data Mapper模式 - 它有点像一个外观(Martin Fowler,Patterns Of Enterprise Architecture)。每个“域类实体类型”(每个表不一定一个)都有一个Mapper,而且对于整个类型的系列,可能是另一个额外的映射器。

Data Mapper模式的一个简单示例在Zend Framework的介绍页面上: http://framework.zend.com/manual/en/learning.quickstart.create-model.html

注意Application_Model_GuestbookMapper 如何使用 Application_Model_DbTable_Guestbook - 并且不会扩展它。

然而,这是一个非常简单的例子,有时会给你留下比答案更多的问题。

了解如何将数据库映射到模型的另一个很好的资源是Scott Ambler的

在线文章:http://www.agiledata.org/essays/mappingObjects.html

它涵盖了处理数据到数据以及对象到对象和数据到对象之间关系的过程: http://www.agiledata.org/essays/mappingObjects.html#MappingRelationships

它还触及了数据映射器模式,是少数几个可以很好地解释如何将类层次结构映射到数据库表的地方之一。

Eric Evans也描述了“存储库”的使用,它是位于模型和数据层之间的外观。如果使用Data Mappers制作完全成熟的ORM似乎令人生畏,这可能是一个快速的起点。您通常每个重要的域实体都有一个存储库(即聚合根实体,'葡萄串的茎')。

查看有关存储库的更多信息: http://books.google.co.uk/books?id=7dlaMs0SECsC&lpg=PP1&dq=Domain-Driven%20Design&pg=PA147#v=onepage&q&f=false

基本上,Repository有一个FindById()类型的方法,然后可以封装在它的façade后面使用你的三个Zend Db Table对象。您的模型可以立即开始使用“回购”。然后,有一天,如果你想添加更多花哨的ORM东西,你只需将它换成回购门面,你的模型甚至不需要知道它。

如果这三个表代表实现独立生活的实体,那么最好有三组类来管理每个生命周期。如果是这种情况,那么您将使用“服务”(特别是Eric Evans的模式中的另一个)来管理他们的交互。服务是一个放置似乎不适合任何一个实体的操作的地方。

请参阅:http://books.google.co.uk/books?id=7dlaMs0SECsC&lpg=PP1&dq=Domain-Driven%20Design&pg=PA106#v=onepage&q=service&f=false

主要的一点是在心理上让自己脱离Zend Db Table的统治地位 - 它只是一个次要的玩家,代表db表而不是更多。