charleschen的麦地

——SomeDay I Will Be Back!
posts - 32, comments - 122, trackbacks - 20, articles - 0
 接着上面的写。

ORM优势和缺点:

优势:ORM自其概念被提出,就得到了无数的响应,花样繁多的应用框架更是应接不暇。可见,他是有其独到的优势的。那么他的优势有哪些那:

首先,ORM最大的优势。
        隐藏了数据访问细节,“封闭”的通用数据库交互,ORM的核心。他使得我们的通用数据库交互变得简单易行,并且完全不用考虑该死的SQL语句。快速开发,由此而来。

第二:ORM使我们构造固化数据结构变得简单易行。
         在ORM年表的史前时代,我们需要将我们的对象模型转化为一条一条的SQL语句,通过直连或是DB helper在关系数据库构造我们的数据库体系。而现在,基本上所有的ORM框架都提供了通过对象模型构造关系数据库结构的功能。这,相当不错。

缺点:
第一:
        无可避免的,自动化意味着映射和关联管理,代价是牺牲性能(早期,这是所有不喜欢ORM人的共同点)。现在的各种ORM框架都在尝试使用各种方法来减轻这块(LazyLoad,Cache),效果还是很显著的。

第二:
         面向对象的查询语言(X-QL)作为一种数据库与对象之间的过渡,虽然隐藏了数据层面的业务抽象,但并不能完全的屏蔽掉数据库层的设计,并且无疑将增加学习成本.

第三:
         对于复杂查询,ORM仍然力不从心。虽然可以实现,但是不值的。视图可以解决大部分calculated column,case ,group,having,order by, exists,但是查询条件(a and b and not c and (d or d))。。。。。。


        世上没有驴是不吃草的(又想好又想巧,买个老驴不吃草),任何优势的背后都隐藏着缺点,这是不可避免的。问题在于,我们是否能容忍缺点。ADA代码虽然易用性很差,但是US.DoD(the department of defense)欣赏他的运算速度;.net平台很不错,但是他是MS的。^_^

 ORM为何而生

          在数月以前,我有幸参加了一个公司内部的组件发布会。令我深感意外的事,一向无人关心的组件发布会这次变得人山人海,在漫长的新版本介绍之后。每个开发组长都跳出来抱怨上一个版本的问题,并且宣布与刚发布的新版本也是无法满足他们的需要的。一切都是如此的混乱,以至领导层不得不采用镇压的方式来平息怒火冲天的人们。
       在会后的那个晚上,我仔细回想了这次冲突。因为据我了解,这一系列的组件非常完美的完成了他所被期待的功能。可是为什么还是会被抱怨如此那。
         我觉得,可能,他(组件)是没有被正确使用了。

不知道还有谁记得James Elliott的那句话,

As good object-oriented developers got tired of this repetitive work, their typical tendency towards enlightened laziness started to manifest itself in the creation of tools to help automate the process. When working with relational databases, the culmination of such efforts were object/relational mapping tools.

    ORM构架只能是一个helper,他定位与此,而不是完整的数据持久层。他的设计者从来就没把他定位于取代一切的超级美女。ORM致力为长久以来的程序员与”重复劳动”的战争而助拳。与任何一个helper一样,他有自己的不足,他有优点也有缺点。
       无数的开发人员试图将使用ORM的框架构架自己项目的数据持久层,很多人感受到了ORM的优势,他们欢心鼓舞。但是很不幸,也有很多人失败或是深受蹉责。
         还有许多人,无奈的编写着很多ORM不适合作的事情。其实想一想,被自己舍弃了的以前的helper工具,难道真的一无是处了?

ORM与DB Helper Library:

      很多人可能都接触过这类的helper,每个公司都有自己的helper。许多Helper提供了很多的强大的功能,封闭交互底层,实体类支持,提供SQL翻译功能。ORM比之这些Helper只是多提供了一层,他尝试封闭的自动化的(或是映射文件)来实现关联。以前,这都是我们手打的。(灵活替换数据库也算ORM优点,
        问题就在与有些人发现封闭的自动化关联满足他们需要了,所以ORM对他而言是成功的。而有些人发现封闭的自动化关联不适合他们的项目,所以ORM被诟病。
          写到这里,我想不用多言了。该结束了。

           我的观点是ORM试图取代helper,为此提供了更多的功能。他为了应付更加严格和复杂的企业需求而不断发展,在很多情况下,这些工具开始具有自身的复杂性,使得开发人员必须学习使用它们的详细规则,并修改组成应用程序的类以满足映射系统的需要,使用它们所面临的复杂性反而盖过了所能获得的好处。在我们的大部分项目中Helper依然是我们构建数据持久层的主力,ORM或许在有些项目(模块)中可以独揽一切,但是ORM(就目前而言)无法面对一切考验。

Feedback

#1楼    回复  引用    

2007-01-08 23:11 by KevinXer [未注册用户]
赞搂主一个,说得太好了~~。。我觉得什么东西都不能用过度,我们之所以用,是为了“偷懒”,但并不代表它是最好的,应该对症下药。

#2楼    回复  引用  查看    

2007-01-09 10:36 by Cameo      
看过~收获不少~支持楼主~

#3楼    回复  引用    

2007-01-09 11:09 by 革命老前辈 [未注册用户]
你们别吵了!
我是基于微软Helper类开发了一套简单的ORM,
既可以用ORM,也可以同时用HELPER,还与数据库类型无关,faasf

#4楼    回复  引用    

2007-01-09 11:09 by 革命老前辈 [未注册用户]
你们别吵了!
我是基于微软Helper类开发了一套简单的ORM,
既可以用ORM,也可以同时用HELPER,还与数据库类型无关,

#5楼    回复  引用    

2007-01-09 17:39 by 张老三 [未注册用户]
存在就是道理,还没见过谁开发出没缺点的东西来,
有缺点可以尝试改进源代码,然后给更多的人用,
这就是开源的精神,过多讨论,只能说明浮躁~

#6楼    回复  引用  查看    

2007-01-13 08:59 by robin[匿名]      
楼主说的ORM的优势是成立的,不过
1.作为程序员,不熟悉sql和数据库是不行的。且不说一些复杂但高效的sql可以解决很多问题,就说性能优化,不熟悉sql和数据库怎么能写出性能过硬的程序。当然你会说这是DBA的工作,但一是不少中小公司都没有独立的DBA,二是会增加程序员和DBA的沟通成本,自己可以搞定为什么还要和别人说半天?所以至少在国内,不熟悉sql和数据库是不行的。

下面说缺点:
1.ORM的性能问题,肯定是不如直接用ADO.NET的。关键看你的系统能否接受这个性能损失。另外如NB,很可能是你用的有问题,因为它里面是有很多的用法的。(当然,要用精NH,这就需要不少学习成本了,这也是个缺点)
2.复杂查询问题:我个人觉得应该自己扩展一个DBHelper来解决。如果你的系统不能接受ORM的查询性能,或ORM实现不了你的查询需求,绕开它肯定是最好的解决方案。毕竟ORM不是完美的,这是它的缺点,但如果有解决方法,用它好的地方,也是个不错的解决方案。

所以我的推测是,用“NHibernate+DbHelper”,可能是个不错的方案。当然用了DbHelper,在迁移数据库时可能会有不兼容的问题了,除非你的DbHelper可以兼容多种DB.不管怎样,尽量用标准的SQL肯定是有好处的。

欢迎交流

#7楼 [楼主]   回复  引用  查看    

2007-01-13 15:33 by charleschen      
@robin[匿名]
大部分ORM框架的实际底层实际就是DbHelper,问题就在于大部分ORM框架未开放其DbHelper,结果给我们造成了很大的问题。

ORM的性能问题其实现在已经很小,几乎可以忽略,但是ORM对数据库的描述时不完全的,必须使用DbHelper来弥补!

复杂查询应用ORM完全是自找麻烦。

其实我在写这篇文章的时候,尽量不想把实际应用带入分析,因为到底怎么用orm每个人都是不一样的,每个人的感受也是不一样的。
写多了只能疲于无聊的论战。

#8楼    回复  引用    

2008-04-17 01:08 by 深秋小雨 [未注册用户]
考虑这么一种情况:
现有一个博客系统,用户可以写日志,可以给日志分类。
那么我们需要两张表如下:
T_BLOG
=========
id
classId
title
content
publishTime


T_BLOG_CLASS
=========
id
className

如果用传统的JDBC编码,PO应该是这么设计的

public class BlogPO{
private String id;
private String blogClassId;
private String title;
private String content;
private Date publishTime;
//setter & getter
}
public class BlogClassPO{
private String id;
private String className;
//getter & setter
}

假设现在我们需要在页面显示日志列表及其分类的名称,我们的DAO中就需要一个查询的方法返回一个List,List里存的应该是BlogPO对象,但是BlogPO没有className这个成员,如何显示className呢?难道再去数据库查询一次?这方法显然不太可取。于是有人想到了VO,创建一个和页面表单对应的VO,然后DAO里的这个查询方法用联接查询返回一个VO,这样只需要一次查询,就能得到页面需要的数据,问题似乎解决了。

时间一久,项目慢慢变得庞大,页面越来越多,成堆的VO等着我们去维护,维护成本越来越高,于是有人开始寻找另外的解决方法,有人想到把BlogPO设计成这样:

public class BlogPO{
private String id;
private BlogClassPO blogClass;
private String title;
private String content;
private Date publishTime;
//setter & getter
}

DAO的查询方法直接返回一个BlogPO,需要className时,可以调用BlogPO.getBlogClass().getclassName()。于是ORM诞生了。

最初的ORM是在加载BlogPO时自动加载BlogClassPO的,后来遇到BlogPO里有些成员是个集合(比如Set)或者是个Blob/Clob字段的情况,在不必要加载时候自动加载它会增加很多开销,于是出现了“延迟加载”技术。再后来…………

自动生成SQL语句我觉得倒是次要的,ORM和传统的JDBC编程最本质的区别是:BlogPO里应该持有一个BlogClassPO成员还是一个String blogClassId成员。

上面全部只是我的猜想,只是今天自己在写blog,不用hibernate而用jdbc来写,遇到这么个问题,然后想了这么多,突然觉得自己明白了ORM的用处。呵呵,YY而已。

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      


相关链接: