ORM漫谈
还是以前那句话,我不喜欢ORM这个词,但是更多的时候又不得不用。
看到园友写的“ ORM是进化还是倒退?”的文章,禁不住想说上几句。其实进化(或者进步?)或者倒退(或者退化?)是没有一个清晰标准的,追求这个进步或者倒退实在也没有什么意义。但是这个标题很惹人,很多年轻人很容易受到蛊惑,所以我必须站起来提醒一下他们。
ORM可以理解成object-relation-mapping,其实结构就是api-database-model。很多人理解的ORM就是database→model→api。事实上这样很自然,一直以来大家都是从数据库设计开始一个系统的。所以各种基于数据库的代码生成器非常盛行,以至于linq2sql和ADOEF(或者有人叫linq2entity)也是数据库先行。但是我之前所经历的ORM却反而鲜见这种模式,所以我一直都没有习惯过来。
最早接触ORM这个词,还是在1999~2001年前后混迹大富翁论坛的时候(那应该也是大富翁论坛最鼎盛的时候)。有一群牛人把java中的一些概念搬到Delphi上,的确让人大开眼界。现在去看,还能看到过去的一些痕迹。没有多久,Delphi上有了正式的ORM产品。首先出炉的是一个叫ModelMaker的MDA工具,有自己的Modeling GUI,从建模到api,浑然一体。MM以后,Bold for Delphi也慢慢火起来,这个基于UML的东东没有自己的Modeling GUI,但是可以使用当时流行的Rose或Together建模的成果。无论是MM还是BFD,都完全当数据库是一个透明的东西。这一类ORM模式是model→api→database,你几乎没有机会干预数据库的定义、生成 和操作。我说这是“纯”的orm。纯倒是纯了,彻底的OO了,但是你回头看一下生成的数据库,无字天书,比现如今sharepoint生成的数据库还丑陋。遇到想做数据挖掘的用户,只能是欲哭无泪了。在这方面,我承认其后来者ECO有了明显的改善,所以我一直相信ECO是一个伟大的产品,只是我用不起而已。
我认识Hibernate是在2003年,后来我一直当Hibernate是JDO的一个非EJB解决方案。Hibernate的确是按配置行事,先有数据库,当时仍然需要手工写一堆entity代码。一群懒人不屑做一些简单重复的事情,自动生成这些配置文件,从此开了“代码自动生成”的先河。哈哈,如果你讨厌“自动代码生成”,去找这些家伙们算账吧,他们身在曹营心在汉,搞java的居然做这么m$的事情,受点委曲也是应该的。所以,Hibernate是一个兼顾database的方案,也是database→model→api,尽管这个api其实是一堆配置。
你烦了当数据库变化以后,model和api的自动同步,我可以接受。不过想一想呢,同步model和api总是有一些好的解决方案。如果你用面向过程的方式,model是没有了,不需要同步了,但是那些api可都是一堆堆的sql语句,我不知道你可以用什么方式来同步。所以,无论OO也罢,PO以罢,进化也好,退化也好,都不是你想讨论的。你无非想要一个比较敏捷一点的方案罢了,如果你喜欢OO,当然你会选择ORM;反之,如果你喜欢PO,你也可以创造一个PRM(procedure-relation-mapping,我相信这个东东一定是可以做到的)。所以,不要告诉我什么OO与Database不匹配的话题,虽然我中意OO但我从来都认为db4o不会成功。database和OO所解决的问题完全不在一个领域,两者的功能是无法相互替代的。
我可是在.net下用了N年的ORM,虽然跌跌撞撞也罢,至少我明白我要的是什么,而市面上的东西其中缺什么。对于我来说,好的ORM产品必须具备以下因素:
- 必须一切从模型开始,无论你是UML也罢,ER也罢,都可以。有Modeling GUI也好,没有的话Hosting一个Addin到IDE也行。
- 必须有自动代码生成,并且既能生成api代码,也能生成sql脚本。当你的数据模型变化以后,改完model,你只需要按几个键,然后所有的一切都有工具帮你搞定(当然包括数据库结构重定义和测试数据自动导入)。
- 功能上必须提供足够的数据操作,性能可靠。必须支持引用、继承和关联三种关系,且继承关系必须是一表一类。
- 除了能传递数据,还必须能够传递“条件包”,当然,运行时的东东,可以是linq的expression也可以是hibernate的criteria。这是分层操作和分布式操作所必须的。
- 虽然通用的方式是以实体为类型、数据行为实例,也可以是以实体为组件(component),而隐含行,但需要确保引用、继承和关联关系。
检查一下ADOEF,头一条就不符合,所以我只能放弃。ORM不会为我提供最好的性能、最好的设计,但是因为其敏捷性,会为我提供最好的产能,特别是在业务复杂的时候。如果不是为了产能,ORM也没有什么生命力。
别嚷嚷ORM不是万能的。谁都没有说过有什么东西是万能的。如果你都不访问数据库,你当然不需要ORM了,所以不会有人说ORM是万能的。只有傻瓜才相信有人真的说过。