数据映射器,仅用于 CRUD 操作?

Posted

技术标签:

【中文标题】数据映射器,仅用于 CRUD 操作?【英文标题】:Data Mapper, only for CRUD operations? 【发布时间】:2012-12-16 17:42:08 【问题描述】:

我最近开始阅读有关数据映射器的文章,我发现的所有文章都只演示了 CRUD 操作,例如:

$user = new User('John', 'Joe', 'john@hotmail.com');
$userMapper->insert($user);

// or this...
$user = $userMapper->fetchById(239);

他们肯定应该做得更多吗?

目前在我的应用程序中,我使用 DAO(或类似的东西),例如,当我需要一个 $user 对象时,我的一个工厂创建了一个 $userDAO 对象并将其注入到我的 $user 对象中。并从我的$user 对象中进行查询,我只是这样做:

$this->userDAO->getNumActiveOrders($this->userId);

它将在$userDAO对象中进行查询并返回结果。

经过大量阅读,我的实现似乎是错误的,因为域对象不应该知道 DAO,反之亦然。我是对还是错?

如果这样做是错误的,那么我认为数据映射器必须用于更多的 CRUD 操作?

所以如果我想知道一个用户有多少活跃订单,我可以这样做:

$userMapper->getNumActiveOrders($userId);

这样对吗?

如果我想在我的 $user 对象中设置该值,我必须执行以下操作:

$user->setNumActiveOrders($userMapper->getNumActiveOrders($userId));

使用我的 DAO 实现似乎比使用数据映射器要快得多,并且使用的代码更少,但我可能错误地实现了数据映射器。

任何建议都会非常感谢。

【问题讨论】:

【参考方案1】:

经过大量阅读,我的实现似乎是错误的,因为域对象不应该知道 DAO,反之亦然。我是对还是错?

没错。

如果这样做是错误的,那么我认为数据映射器必须用于更多的 CRUD 操作?

DataMapper is to map data from a Database to Domain Objects 的用途。由于对象图通常不像关系数据库系统中的数据那样结构化,因此您需要某种映射器将关系数据从数据库获取到您的对象中,反之亦然。 DataMappers尝试解决Impedance Mismatch的问题。

所以如果我想知道一个用户有多少活跃订单,我可以这样做:

$userMapper->getNumActiveOrders($userId);

这样对吗?

是的,你可以这样做。但您也可以查询用户对象,例如

echo $user->getActiveOrders();

然后您的用户对象可能会有某种Lazy Loading mechanism 来获取活动订单。

如果我想在我的 $user 对象中设置该值,我必须执行以下操作:

$user->setNumActiveOrders($userMapper->getNumActiveOrders($userId));

没有。您只需设置活动订单。数字可以从它们中得出。如果计数是您想在数据库中插入的东西,您可以在 Mapper 中处理。

使用我的 DAO 实现似乎比使用数据映射器要快得多,并且使用的代码更少,但我可能错误地实现了数据映射器。

这很正常,因为 DAO 只查询数据库,不做任何映射。

【讨论】:

感谢您的回复。是“映射”这个词吸引了我。无论我看到多少例子,我仍然无法完全掌握它。使用延迟加载机制是否意味着静态/全局调用?由于 DAO 用于查询,而 Mapper 用于映射,这是否意味着它们可以以某种方式一起使用?喜欢将它们作为一个对象加入吗? @user1925055 您的 DataMapper 将知道 DAO,因此它可以从/向数据库加载和持久化。至于延迟加载:不,您不需要静态和全局。一种可能的解决方案是使用 Active Orders 的占位符对象创建 User 对象,该对象将从数据库中加载数据并将其自身替换为映射的 Active Orders 的集合。按照我提供的链接获取更多选项。

以上是关于数据映射器,仅用于 CRUD 操作?的主要内容,如果未能解决你的问题,请参考以下文章

MVC,映射器将 ViewModel 传递给 CreateView 的问题

双层设备映射器 - 自定义 dm-crypt

带有 EF 和自动映射器的 OData:无法比较..'。仅支持原始类型、枚举类型和实体类型

MyBatis数据库连接的基本使用-补充Mapper映射器

Zend 框架 - 为啥我应该使用数据映射器/Db_Table_Row?

根据映射器代码中的某些逻辑,将映射器中的一些数据(行)写入单独的目录