简体   繁体   English

Zend框架 - 我为什么要使用数据映射器/ Db_Table_Row?

[英]Zend framework - Why should I use data mapper / Db_Table_Row?

Extended Question: Why should I use data mapper / Db_Table_Row, where as DbTable is capable of handling most of the basic tasks for data manipulation. 扩展问题:为什么我应该使用数据映射器/ Db_Table_Row,因为DbTable能够处理大多数数据操作的基本任务。

I am currently learning ZF v1.11 我目前正在学习ZF v1.11

For Database manipulation, I created DbTable for each tables. 对于数据库操作,我为每个表创建了DbTable。 For example, "users" table is represented by Application_Model_DbTable_Users with no additional codes in there. 例如,“users”表由Application_Model_DbTable_Users表示,其中没有附加代码。

When manipulating data, I can use: 在操作数据时,我可以使用:

<?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();

My Question is, when would I need to define a row class (assuming Table_Row is referred as DataMapper in ZF-Tutorials) 我的问题是,何时需要定义一个行类(假设在ZF-Tutorials中将Table_Row称为DataMapper)

// By, adding this to the DbTable class
protected $_rowClass = 'Application_Model_User';

What are the benefits of having a Row class for each entity? 为每个实体设置Row类有什么好处? Can anyone point me to best practices for this. 任何人都可以指出我的最佳做法。

You do not need to define your own Table_Row. 您不需要定义自己的Table_Row。 However, it maybe useful in many cases, particularly if you want to define some specific methods or properties for a given user row. 但是,它在许多情况下可能很有用,特别是如果要为给定用户行定义某些特定方法或属性。 They can also improve readability of your code. 它们还可以提高代码的可读性。

For example in your Users table case, you could define a method called getFullName() in a custom user row as: 例如 ,在Users表的情况下,您可以在自定义用户行中定义一个名为getFullName()的方法,如下所示:

public function getFullName() {
    return $this->firstName . ' ' . $this->lastName;
}

Then when you obtain user row object, to get the full name of the user, you just do: 然后,当您获取用户行对象时,要获取用户的全名,您只需执行以下操作:

$user = $uTable->find($newUid)->current();
$fullName = $user->getFullName();

Second example is when you have some parent table to the Users table, such as Addresses. 第二个示例是当您有一些父表到Users表时,例如Addresses。 In this case you could define a method called getAddress in a user row: 在这种情况下,您可以在用户行中定义一个名为getAddress的方法:

public function getAddress() {
    return $this->findParentRow('Application_Model_DbTable_Addresses');
}

In this scenario, you would get an Address row object for a current user as follows: 在这种情况下,您将获得当前用户的Address行对象,如下所示:

$user = $uTable->find($newUid)->current();
$addressRow = $user->getAddress();

Another example , would be when you want to create custom delete or instert methods. 另一个例子是,当你想要创建自定义删除或instert方法时。 Lets assume that you want to make sure you do not want to delete an admin user using delete() method. 让我们假设您要确保不想使用delete()方法删除管理员用户。 Then you could overload delete method from Zend_Db_Table_Row as follows: 然后你可以从Zend_Db_Table_Row重载delete方法,如下所示:

public function delete() {
        if ('admin' === $this->userRole) {
              return 0;
        }
        return parent::delete();
} 

This way, you would not be able to delete an admin user just by calling delete() on a user row object: 这样,您就无法通过在用户行对象上调用delete()来删除管理员用户:

 $user = $uTable->find($newUid)->current();
 $rowsDeleted = $user->delete(); // would be 0 if $user is admin

These are just three basic examples showing usefulness of defining your own row classes. 这些只是三个基本示例,显示了定义自己的行类的有用性。 But of course they are not necessary. 但当然他们没有必要。 However, from my own experience they are quite handy. 但是,根据我自己的经验,它们非常方便。

In a nutshell: it's about isolation. 简而言之:它是关于隔离的。

Zend_Db_Table is an implementation of the Table Data Gateway. Zend_Db_Table是表数据网关的实现。 It channels CRUD access to a specific table view through one class. 它通过一个类将CRUD访问引导到特定的表视图。 It is usually used with a Table Module , eg a class that contains the business logic for the records handled by a gateway. 它通常与表模块一起使用 ,例如,包含网关处理的记录的业务逻辑的类。

Zend_Db_Table_Row is an implementation of the Row Data Gateway Pattern . Zend_Db_Table_Row行数据网关模式的实现 Here, the returned objects look exactly like a database record and they contain the business logic to work with that data, but they don't contain the logic to CRUD with the table they are from (that would be an ActiveRecord) but aggregate them. 这里,返回的对象看起来与数据库记录完全相同,它们包含用于处理该数据的业务逻辑,但它们不包含CRUD的逻辑以及它们来自的表(即ActiveRecord),而是聚合它们。

Row Data Gateways are fine as long as you don't have too much object relational impedance mismatch . 只要没有太多的对象关系阻抗不匹配,行数据网关就可以了。 How an object is persisted in a relational database and how it should look like in an object world are often quite different things. 一个对象如何在一个关系数据库中持久化以及它在对象世界中的外观通常是完全不同的东西。 When using a Domain Model , your business objects are usually structured in a different way than they are stored in the database. 使用域模型时 ,业务对象的结构通常与存储在数据库中的方式不同。 Thus, you cannot easily CRUD them from the database. 因此,您无法轻松地从数据库中对它们进行CRUD。 This is where DataMapper comes into play. 这就是DataMapper发挥作用的地方。

A DataMapper takes the responsibility of mapping Domain objects onto Recordsets and vice versa. DataMapper负责将Domain对象映射到Recordsets,反之亦然。 This makes your application more maintainable because it decouples your Domain objects from the Database structure. 这使您的应用程序更易于维护,因为它将您的Domain对象与Database结构分离。 It keeps them separated and gives you more flexibility in how to model both layers (persistence and domain). 它使它们保持分离,并为您提供更多灵活性,以便对两个层(持久性和域)进行建模。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM