写出脏乱差的代码了。悲剧,求可以帮助实现数据关系映射操作的的参考材料。

2013-06-10 22:31:05 +08:00
 raincious
好吧,我猜你可能会说:不要自己写ORM。就像这位Jimmy Bogard说的:

http://lostechies.com/jimmybogard/2012/07/24/dont-write-your-own-orm/


但是我觉得好有意思,于是……我用“不理睬”的解决方案,自己凭借想法实现了个(类似)ORM(的东西)。目前实现的功能比如:

// C
$model = new userModel();
$model->username = 'username';
$model->password = 'password';
$model->insert();

// U
$model = new userModel();
$thing = $model->get(array('userID' => 1)); // R,这里就分出个实例了

$thing->username = 'username';
$thing->password = 'password';
$thing->save();

分实例主要是为了fetch,因为:

$thing = $model->fetch();
foreach($thing AS $user) {
echo $user->username; //只有这样才能实现这样
$user->username = 'new' . $user->username;
$user->save(); // 以及这样
}

// D
$thing->delete();

但是呢,即便是写成这样了(我觉得写的很差),我觉得还差了很多东西。。

这是哪个ORM的代码,我想。。各位看了就明白:https://github.com/raincious/facula/blob/master/libraries/orm/class.simpleorm.php

首先我觉得太浪费内存了,因为fetch每次都会创建一个自己,那么原来的对象就相当于没用了。我想了很久如何复用这个实例,但是怎么都无法满足在一个实例里完成所有get、fetch、save、insert之类的操作。(试过迭代器之类,或者数组ArrayObject,都不完美)

总之就是觉得自己写的不靠谱,脏乱差,于是想求各位有经验的同学来推荐下相关方面的资料(最好是在线的)用来详细了解相关的设计和原理。

谢谢。
3116 次点击
所在节点    PHP
6 条回复
wtbhk
2013-06-11 09:54:41 +08:00
楼主比我写的好多了,我上次那坑因为有多对多的关系,至今没找到好的解决方案(其实是有好的方案但是无法理解)
raincious
2013-06-11 12:08:42 +08:00
@wtbhk 多对多我也没法解决,想想看……就不支持好了……

现在我担心的还是创建的实例太多了。我发完这个帖子之后把代码改了下,用fetchWith的时候一部分实例创建之后会自动注销。但是内存占用还是没降下来。

我只Fetch了10个Row,内存使用就2M了,要是100个Row那真不敢想……。

又或者可能我太过敏了,就算100个row也和10个row区别不大?

反正我这套数据库查询的东西一起用。。我就觉得代码速度慢了一大截,捉鸡啊真。
chemzqm
2013-06-11 12:24:36 +08:00
我觉着关系型数据库查询ORM就是个硬伤,效率低不算,维护更让人恶心,不如拼接sql语句呢。
raincious
2013-06-11 12:40:21 +08:00
@chemzqm 是的,所以有人说ORM是反射计:http://seldo.com/weblog/2011/08/11/orm_is_an_antipattern

所以我目前写这个ORM的另一个目的是评估必要性。

而且说真的,如果不考虑兼容新,拼接SQL语句个人感觉真是最贴心的……
raincious
2013-06-12 11:54:52 +08:00
悲剧,果然很占用内存。

从数据库里取出2000个结果返回为对象实例,未联表,使用了9兆内存。

改为返回数组,使用5兆内存。

所以内存耗费还是挺高的。

但是……速度尚可,两次查询速度接近。我准备忽略这个问题了。反正我的ORM提供了选项,fetch能够在返回对象实例和对象结果数组中作出选择。
hardway
2013-07-13 10:32:06 +08:00
个人很喜欢<a href='http://www.martinfowler.com/eaaCatalog/activeRecord.html'>ActiveRecord</a>模式

我的ORM和楼主差不多,不过fetch这一块是用_callStatic来实现了类似:
User::get($id)
User::find_all(array($c1=>$v1, $c2=>$v2, "condition, limit, order, ..."))
User::find_one(array($c1=>$v1, $c2=>$v2))
User::find_by_firstname($name)
User::find_one_by_firstname($name)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/71923

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX