我有一个名为Cat
的表,以及一个名为Cat
的PHP类。现在我想创建一个CatDataMapper
类,以便Cat extends CatDataMapper
。
我希望Data Mapper类提供执行ORM以及创建,编辑和删除Cat的基本功能。
为此目的,也许知道这种模式的人可以给我一些有用的建议吗?我觉得提供像update(),delete(),save()这样的函数会有点简单。
我意识到数据映射器有这个问题:首先你创建了Cat的实例,然后初始化所有的变量,比如name,furColor,eyeColor,purrSound,meowSound,atte者等等。在设置好所有内容后,你调用从CatDataMapper继承的save()函数。这很简单;) 但现在,真正的问题是:你在数据库中查询猫并获得一个包含大量猫数据的无聊结果集。
PDO具有一些ORM功能来创建Cat实例。让我说我使用它,或者甚至说我有一个带有关联数组的mapDataset()函数。但是,只要我从数据集中获取Cat对象,就会有冗余数据。同时,20个用户可以从数据库中获取相同的cat数据并编辑cat对象,即重命名cat,并保存()它,而另一个用户仍然需要设置另一个furColor。当所有人都保存他们的编辑时,一切都搞砸了。
呃...好吧,保持这个问题非常简短:这里有什么好的做法?
答案 0 :(得分:12)
Data Mapper是一个软件层 分隔内存中的对象 来自数据库。它的责任 是在两者之间传输数据 并将它们与每个人隔离开来 其他。使用Data Mapper在内存中 物体甚至不需要知道 存在的数据库;他们不需要SQL 接口代码,当然没有 了解数据库模式。 (该 数据库架构总是一无所知 使用它的对象。)因为它是一个 Mapper的形式(473),数据映射器 本身甚至都不为人所知 层
因此,Cat不应该扩展CatDataMapper,因为这会创建一个is-a关系并将Cat绑定到持久层。如果您希望能够以这种方式处理Cats的持久性,请查看ActiveRecord或任何其他数据源架构模式。
使用域模型时,通常使用DataMapper。一个简单的DataMapper只是在一个字段到字段的基础上将数据库表映射到等效的内存中类。但是,当出现对DataMapper的需求时,通常不会有这样简单的关系。表格不会将1:1映射到您的对象。相反,多个表可以形成一个Object Aggregate而反之亦然。因此,实现只是 CRUD方法很容易成为一个挑战。
除此之外,它是更复杂的模式之一(在PoEA中涵盖15页),通常与Repository pattern等组合使用。请查看本页右侧的相关问题栏以了解类似问题。
关于有关多个用户编辑同一个Cat的问题,这是一个名为Concurrency的常见问题。一个解决方案是locking the row,而有人编辑它。但就像所有事情一样,这可以lead to other issues。
答案 1 :(得分:2)
如果您依赖于Doctrine或Propel之类的ORM,基本原则是创建一个静态类,从数据库中获取实际数据(例如Propel将创建CatPeer),以及然后,Peer类检索的结果将“水合”到Cat对象中。
水化过程是将“无聊的”MySQL结果集转换为具有getter和setter的漂亮对象的过程。
因此,对于检索,您可以使用CatPeer::doSelect()
之类的内容。然后,对于一个新对象,您首先要实例化它(或从数据库中检索和实例):
$cat = new Cat();
插入操作就像执行一样简单:$cat->save();
这等同于插入(或者如果对象已经存在于db中则更新... ORM应该知道如何区分例如,使用存在或不存在主键的新对象和现有对象。
答案 2 :(得分:2)
在PHP中实现数据映射器非常困难< 5.3,因为你无法读/写protected / private字段。加载和保存对象时有几个选择:
第一种方法有可能破坏新版本,并且是非常粗糙的黑客,第二种方法被认为是(非常)不好的做法。
第三个选项也被认为是不好的做法,因为你不应该为所有字段提供getter / setter,只提供需要它的字段。您的模型从纯DDD(域驱动设计)角度“受损”,因为它包含仅由于持久性机制而需要的方法。 这也意味着现在你必须描述字段的另一个映射 - > setter方法,在字段旁边 - >表格列。
PHP 5.3引入了使用反射访问/更改所有类型字段的功能:
http://hu2.php.net/manual/en/reflectionproperty.setaccessible.php
有了这个,您就可以实现真正的数据映射器,因为为所有字段提供mutator的需求已经停止。
答案 3 :(得分:1)
PDO具有一些ORM功能 创建Cat实例。让我说我用 那,或者甚至说我有一个 需要一个mapDataset()函数 关联数组。但是,一旦 我从数据集中获取了我的Cat对象,我 有冗余数据。同时, 二十个用户可以拿起相同的 cat数据来自数据库并进行编辑 猫对象,即重命名猫, 并保存()它,而另一个用户 关于设置另一个的事情 furColor。当他们全部保存他们的 编辑,一切都搞砸了。
为了通常跟踪数据的状态,将使用IdentityMap和/或UnitOfWork跟踪映射实体上的所有不同操作......以及请求周期结束时,操作将是进行。
答案 4 :(得分:0)
保持答案简短: 你有一个Cat的实例。 (也许它扩展了CatDbMapper或Cat3rdpartycatstoreMapper) 你打电话:
$cats = $cat_model->getBlueEyedCats();
//then you get an array of Cat objects, in the $cats array
不知道你使用了什么,你可能会看一些php框架以便更好地理解。