Hos*_*han 22 php database design-patterns zend-framework zend-db-table
扩展问题:为什么我应该使用数据映射器/ Db_Table_Row,因为DbTable能够处理大多数数据操作的基本任务.
我目前正在学习ZF v1.11
对于数据库操作,我为每个表创建了DbTable.例如,"users"表由Application_Model_DbTable_Users表示,其中没有附加代码.
在操作数据时,我可以使用:
<?php
$uTable = new Application_Model_DbTable_Users();
$newUid = $uTable->insert(array('name'=>'Old Name', 'email'=>''));
$user = $uTable->find($newUid)->current();
// Then I can use $user which is instance of Table_Row
$user->name = "New Name";
$user->email = "email@addr.com";
$user->save();
Run Code Online (Sandbox Code Playgroud)
我的问题是,何时需要定义一个行类(假设在ZF-Tutorials中将Table_Row称为DataMapper)
// By, adding this to the DbTable class
protected $_rowClass = 'Application_Model_User';
Run Code Online (Sandbox Code Playgroud)
为每个实体设置Row类有什么好处?任何人都可以指出我的最佳做法.
Mar*_*cin 41
您不需要定义自己的Table_Row.但是,它在许多情况下可能很有用,特别是如果要为给定用户行定义某些特定方法或属性.它们还可以提高代码的可读性.
例如,在Users表的情况下,您可以在自定义用户行中定义一个名为getFullName()的方法,如下所示:
public function getFullName() {
return $this->firstName . ' ' . $this->lastName;
}
Run Code Online (Sandbox Code Playgroud)
然后,当您获取用户行对象时,要获取用户的全名,您只需执行以下操作:
$user = $uTable->find($newUid)->current();
$fullName = $user->getFullName();
Run Code Online (Sandbox Code Playgroud)
第二个示例是当您有一些父表到Users表时,例如Addresses.在这种情况下,您可以在用户行中定义一个名为getAddress的方法:
public function getAddress() {
return $this->findParentRow('Application_Model_DbTable_Addresses');
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您将获得当前用户的Address行对象,如下所示:
$user = $uTable->find($newUid)->current();
$addressRow = $user->getAddress();
Run Code Online (Sandbox Code Playgroud)
另一个例子是,当你想要创建自定义删除或instert方法时.让我们假设您要确保不想使用delete()方法删除管理员用户.然后你可以从Zend_Db_Table_Row重载delete方法,如下所示:
public function delete() {
if ('admin' === $this->userRole) {
return 0;
}
return parent::delete();
}
Run Code Online (Sandbox Code Playgroud)
这样,您就无法通过在用户行对象上调用delete()来删除管理员用户:
$user = $uTable->find($newUid)->current();
$rowsDeleted = $user->delete(); // would be 0 if $user is admin
Run Code Online (Sandbox Code Playgroud)
这些只是三个基本示例,显示了定义自己的行类的有用性.但当然他们没有必要.但是,根据我自己的经验,它们非常方便.
Gor*_*don 20
简而言之:它是关于隔离的.
Zend_Db_Table
是表数据网关的实现.它通过一个类将CRUD访问引导到特定的表视图.它通常与表模块一起使用,例如,包含网关处理的记录的业务逻辑的类.
Zend_Db_Table_Row
是行数据网关模式的实现.这里,返回的对象看起来与数据库记录完全相同,它们包含处理该数据的业务逻辑,但它们不包含CRUD的逻辑,包含它们来自的表(即ActiveRecord),但聚合它们.
只要没有太多的对象关系阻抗不匹配,行数据网关就可以了.一个对象如何在一个关系数据库中持久化以及它在对象世界中的外观通常是完全不同的东西.使用域模型时,业务对象的结构通常与存储在数据库中的方式不同.因此,您无法轻松地从数据库中对它们进行CRUD.这就是DataMapper发挥作用的地方.
DataMapper负责将Domain对象映射到Recordsets,反之亦然.这使您的应用程序更易于维护,因为它将您的Domain对象与Database结构分离.它使它们保持分离,并为您提供更多灵活性,以便对两个层(持久性和域)进行建模.