Posted on 2006-06-07 21:32
idior 阅读(17376)
评论(56) 编辑 收藏 网摘 所属分类:
O/R Mapping,
.Net
O/R M一个相当常见的概念,不过也是一个被很多人误解的概念。O/R M据我所知是从Java社区产生的,而到了.Net社区它的意味就完全变了。首先让我们来看看为什么是O/R M而不是R/O M?其实之所以很多人没有理解O/R M的含义就是因为没有充分的考虑上面这个问题。
以O为主还是以R为主?你是从面向对象的角度分析考虑问题还是从关系的角度分析考虑问题。
从面向对象的角度考虑问题,意味着你可以使用封装,集成,多态这些面向对象的特点来描述和理解你的应用域,因为对象的高度抽象和可理解性,通过它你可以构造出一个用对象来描述领域的模型,这也是领域模型的由来。而一个好的模型必然要考虑到的几点包括对象所包含的责任是否合理,对象与对象之间的关系是否合理等,而高内聚,低耦合就是用来衡量它们的一个技术标准。
可以看出一个好的领域模型,可以让你清楚的了解现实的应用领域,而一个好的领域对象也必然具有高内聚,低耦合的特点,而绝对不是一个数据包。
当我们使用面向对象技术建立好了我们的领域模型,一个问题随之而来,对象如何持久化?对象的生命周期包括多个阶段其中包括第一次被创建出来,被持久化,被从文件(通常是数据库)中取出来,被垃圾回收。显然我们希望能够更多的关注与领域模型而非这些对象生命周期的管理,此时O/R M的需求应运而生,而能够透明的实现对象的持久化和反持久化则更为我们所追求,此时再来看看某些使用O/R M来为一个领域对象实现Save Load的做法是多么与我们的想法背道而驰,这些方法与领域何关?O/R M框架将对象持久化功能从领域对象中分离出来,交由框架负责,而有人竟然反其道而行之,这种现象在.Net社区尤为常见。为什么会这样?因为考虑问题的思路不同。可以这么说在.Net社区O/R M往往被当作R/O M来使用。
从关系型模型的角度来考虑问题,在一接到问题之后,先建立实体关系模型,然后考虑各种约束条件,并通过Server端一系列的存储过程来描述业务逻辑。这种方法曾广泛被采用,然而两相比较孰优孰劣?和大多数人(Martin Fowler等等)一样我更喜欢OO的方式,用对象来描述世界,比起关系和一堆的SQL语言对我来说,显然前者更美,而且没有了继承多态,那样程序将充满了重复代码,并且不利于扩展,可读性就更不用说了。就如Martin Fowler所说要不是因为.Net提供了方便的界面绑定方法,这种纯粹的数据包对象谁会去使用呢?它们的优势就在于那些领域逻辑简单的应用,这也是.Net常见的应用领域。
所以当你不是用对象的方法(不是说你仅仅使用了面向对象语言)来分析解决问题时请离O/R M远一点,这样对大家都好。你不会觉得它奇怪,它也不会被你用的郁闷。
在这里我也顺便谈谈我对DLinq的看法。首先我不得不承认它很Cool,并且我之前对Linq也做过介绍,但是我并不是很喜欢它的方式,至少它存在一种可能被滥用的危险。查询你所需要的数据,然后围绕这些数据做处理,微软仍然坚持它一惯的风格,并且在Linq中,可以说是做到了极致---用Linq查询数据太方便了。如果每个对象都通过这样的方式获得,那么对象之间的关系(Association)将变的杂乱无章。你在设计对象的时候仔细考虑的对象之间的关联关系将被轻易的打乱(领域对象的关联关系是描述领域模型的关键组成部分之一),而且你查询到的纯粹是数据实体,它们并没有行为,你又会靠一个个的xxxManager来管理它们,喔,天哪,又失去了面向对象的优势。所以DLinq本身绝对不是一套O/R M工具,不过利用它实现一套O/R M工具倒是不错的选择。
当面对面向对象和关系型数据库的阻抗失衡时,Java社区更多的考虑的是自动透明的实现将O映射成R的方式,而MS更多的考虑的是将R方便的变成O(数据包类型的O而已)的方式(这点可能跟MS也是数据库厂商有关)。两个方向,你选哪个?
个人观点仅供参考。
BTW 前阵子有个兄弟问我O/R M的性能怎样?呵呵,总是有很多人关注性能问题。那么我先问问大家
你觉得OO性能怎么样?泛型性能怎么样?AOP的性能怎么样?SOA的性能怎么样?呵呵,另人失望的答案,它们的运行效率都比不使用它们的方案低。但是它们能大大加强我们的开发效率,这是一个追求效率的年代 :)
(我可没有鄙视性能的意思)
6.8看过评论后更新
本文的观点可能有很多人有不同意见,这很正常,如我标题所写本文也仅仅是乱谈而已。不过对于使用Hibernate的用户请尽可能的考虑我所说的问题,因为我的观点和Gavin King(Hibernate的作者)的还是基本一致的。同样对于大家所说的表很多的问题,请参考Gavin King的原话。
You should use Hibernate if you have a nontrivial application (definition of nontrivial varies, but I usually think of Hibernate being less applicable to applications with only ten tables or so) that use an object-oriented domain model. Not every application needs a domain model, so not every application needs ORM. But if your application does a lot of business logic - rather than just displaying tabular data on a webpage - then a domain model is usually a good thing.
Hibernate really starts to shine in applications with very complex data models, with hundreds of tables and complex interrelationships. For this kind of application, Hibernate will take away a huge amount of coding effort (perhaps up to 25%, for some applications) and will result in an application that performs better than the alternative handcrafted JDBC. This is possible because some kinds of performance optimizations are very difficult to handcode: caching, outer-join fetching, transactional write-behind, etc.
另外双鱼座在评论中指出"数据规模对采用哪种技术框架没有太大关系,有比较大关系的是业务复杂度", 对此个人深表赞同。
如果你想深入理解O/R M,推荐以下三本书:
Patterns of Enterprise Application Architeture
Hibernate in Action
Domain-Driven Design
相关文章
Feedback
我一直是R->O的赞成者
如果有人在最后有上百个表的实际项目使用了O->R
并且数据库的数据量在至少百万级别
那我才会更相信O->R
要知道数据库得处理冗余 处理并发 处理同步 这些会让class映射出来的table面目全非 然后再用attribute或xml去mapping 饶了我吧 再怎样用ORM,我也对这个Mapping一直持否定态度
另外 用ORM是每个数据库开发者的最终归宿 只是有些ORM让使用者觉得太复杂了 结果望而却步
我觉得随着企业应用的发展,先考虑对象模型会被广泛接受的。
如果仅仅时为了持久化数据对象,orm挺合适,一般用在数据量不大但结构比较繁杂,比如profile session config等等,其实这和xml作持久化也差不了多少。
如果是业务数据,当然是先有关系数据,后有对象,数据对于一个企业来说远比程序重要的多。其实不管面向对象还是面向过程,仅仅是方法,为了代码复用和扩展容易,但不要忘了其目的是为了处理具体业务。具体业务大多是通过关系型数据库来存储的,设计其结构有考虑到很多因素,但这些与软件无关,也就是说软件结构不对业务数据结构造成什么影响。
如果具体作一个项目或者产品,你会理解的更深一些。
不知道大家有没有去看一下ado.net 3.0的相关东西。
你觉得OO性能怎么样?泛型性能怎么样?AOP的性能怎么样?
-------------------------------------------------------
在我的印象中,泛型是不影响性能的。至少在C++中如此。
项目的目的是什么?大家要注意这个根本问题!轻巧简洁的解决问题,而不应该形而上学。
>而且你查询到的纯粹是数据实体,它们并没有行为,你又会靠一个个的xxxManager来管理它们
not quite, DLINQ will support lambda so I think it actually
provides you a much easier way to process data like
ruby.
what if you can use ruby-like (oo+fP) language to process relational data? I believe that is a big progress in programming model.
就个人目前的知识点来看,目前大多数选择o/r 架构的原因应该不是为了用纯面向对像去描述业务逻辑(当然也有,但想信会很少,有很多原因,编写程序复杂只是一方面,对业务的了解,及用oo描述的可行性,等等),而多数原因是编写程序更简单了。可以不用再对很长的sql,或对一个查询写很多个重载的方法。并前类型检察等等。这样会使程序写的更加清晰,不在像以前每个人写自已的sql (当然,有些时候自已写sql的效率要高一些,但在软件越作越大的今天,效率,性能已不在是最主要的--对于大多数行业,而健状性和可维护性显得更为主要一些),要这种前题下如果一味地坚持以 O->R 的型试开发感觉有点学院作风,搞技术创新,做学术研究很好,但如果用在一个公司的项目上,有些冒风险,分析和编码是。因为就目前来说,能比较成功能用O O描述现实世界的业务逻辑的成功按例好像并不多(也许是知识面太少,有很多,本人不知道,各位别骂啊:-)),相反到是听主很多公司的大型软件都是以数据库为中心来描述业务的。
说到DLinq ,前两天在一个小型 的企业网站用到了这东东(虽然没出正试版,但数据特少,就几个表,不会出什么问题,就是出了问题再改过来也好改),用起来的感觉是挺方便,但资料实在太少了点,弄一个小功能有时就得弄半天。
感觉上到没有像楼主说的哪样杂乱无章。也许是数据表少的原故,但最深的印像就是这一次感觉上真正的面像对像编程了(相对于以前操作dataset datatable来讲),给人一种全新的感觉,当然开始不习惯是肯定的了。蛤相信在不久的将来这东东肯定能把初级程序员从slq中解放出来,也许以后招程序员时要把 精通或熟练 sql 这一条去掉.:-)
知识面太窄,说不好大家别拍砖。
to 维生素C.NET
ado.net 3.0 这东东关注了一段时间,最近有些太忙就没太看(在有e 文也不好,国内的资料少了点,是从思归哪大哪得知的, 哪要老大你不忙可以帮忙多介绍)。
别的不敢说,单从linq 一点来讲就应算是 一个里程杯了,感觉有点像odbc 的作用了,要比ado 升级到 ado.net 的影响要大多了(终个人意见)。
BTW 前阵子有个兄弟问我O/R M的性能怎样?呵呵,总是有很多人关注性能问题。那么我先问问大家
你觉得OO性能怎么样?泛型性能怎么样?AOP的性能怎么样?呵呵,另人失望的答案,它们的运行效率都比不使用它们的方案低。但是它们能大大加强我们的开发效率,这是一个追求效率的年代 :)
非常支持你的观点,总是有不少人在做项目前就开始考虑性能问题,一旦觉得某某东西对性能有影响马上不用。那么追求效率,用c,c++甚至汇编去写程序吧肯定效率高。
O/R M这个东西效率是比直接使用ado.net低了一点,但是也没低多少,牺牲那么一点效率换来开发上的便利是值得的。
一石激起千层浪,楼主的文章写的很到位,我也很同意并一直坚持O-R的方式。
工具也不过就是工具,作用完全要看使用者。
我曾经用datarow -> object
现在用NHibernate,方便多了。
//此时再来看看某些使用O/R M来为一个领域对象实现Save Load的做法是多么与我们的想法背道而驰,这些方法与领域何关?
实际上标准的方法是领域对象不包含这些方法,而是在领域之下的数据层实现对领域对象的持久。
O->R在学院里给学生上课,做示例感觉是蛮有道理的,
但在实际的企业项目里面对几十个,上百个表维护,需求不断变化,项目周期紧急的时候。
总是让人感觉有点望而生畏啊!
@headchen
同意你的观点,
O-R Mapping是好,用在小的独立的系统中还不错,基本上所有功能都搞得定。
在一个大系统,如果R全是由O Mapping过来得,真不敢想象需要在其他地方用到R得人,开发O得人和使用R得人都会疯掉。不要说O能搞定所有的问题,那么开发O得人就会彻底疯掉。
论调太多了,搞得搞不清楚O/RM到底要怎样了
Idior能不能写几个例子分别说明一下几种通常的做法,再分析一下每种做法的优劣,有例子更能帮助我等对O/RM常用框架研究较少的菜鸟。
@-天道酬勤
我就不知道为什么你有“望而生畏“的感觉
愿闻其详
我觉得在实际应用的时候,肯定是O和R两边都要考虑,需要一个平衡。不可能单纯的从O->R,或者R->O。
上百个表 能不能O->R 当然可以 问题是否会得不偿失
我需要的是有人证明自己在实际项目中就是O->R 而且表有上百个 数据库在百万数据级
我想问问这些研究O/R M或者R/O M的人到底是做什么用户的
用户摊上了这样的程序员只有哭丧着脸咽下苦果
我们交了一大笔钱,得到的不是完善的软件产品
而是养着程序员永无止境对技术的跟风(包括对这个什么Mxxtin的顶礼膜拜)
将心比心,我们这些用户又是何辜呢!
我在一个中型国企作分管技术,不幸中了某著名国产软件的宣传买了他们的半成品(说是半成品已经是抬举,当然他们自己不承认)
从此就开始暗无天日地听这家软件公司摊派给我们的所谓“架构师”大喷什么J2EE,框架架构,Hibenet,ORM!
但是做出来的东西跟我们的业务南辕北辙,就像玩具,根本不是我们要的,
真有一脚踩在他脸上的欲望,对楼上的诸位也是!
@冻未调
那你要某著名国产软件公司不要再用什么J2EE,框架架构,Hibenet,ORM技术再你做一个软件,看看还像不像玩具.
也许会更差
@冻未调
正因为现在的企业应用中对业务的分析和理解是最重要的部分,所以大家才讨论领域模型和关系模型的映射问题。
另外你的说话方式实在是很差劲,就像你们正在用的软件一样。
《Patterns of Enterprise Application Architeture》确实是一本必看的好书。
我想进一步了解O/R Mapping的具体含意,我一直以为这种模式只是把数据模型和存储方式分开,可以让数据模型表达和处理更灵活.这里的O就是对象化的数据模型,R就是连接的桥梁.有时候O为了适应R作出调整也是难免的(在实现项目已经确定使用了什么数据和组件,这个时候R很大程度上已经确了是不能改变的).
@冻未调
对用户来说是没必要关心这些,因为他们只是使用软件.
但你有没有想过一个软件的健壮性是由那些东西所决定的呢?
什么都不想就直接写代码,我想这软件不会好到那里去.
@冻未调
你这话有点过了
你所谓的软件公司是什么样的产品我不知道,但现在大家讨论的是设计问题,并不是业务逻辑
看了idior的文章和各位高手的评论,想起了多年前在大富翁论坛的那场争论。“二维的平面数据库与多维的业务模型”之间的矛盾让人不得不采用面向对象方式去设计,而按面向数据方式去实现。所以,非常同意蔡克伦的说法,O->R或者R->O不必分得太清。大多数情况下,平衡一下,既照顾到业务实现又保证清晰的数据库结构(也许有一天客户会用这些数据做BI的,必须保证不能让人看不明白)。其实优秀的持久层框架都做得非常好,包括Hibernate,虽然设计的是O->R,很多的微调保证了数据库的清晰。DotNet下的特殊性是界面上的数据绑定的确可以简化界面的设计,传输的介质是数据集而不是对象集合。
@progame
我个人觉得数据规模对采用哪种技术框架没有太大关系,有比较大关系的是业务复杂度。我采用自己的框架做过的项目中,有一个应用就是接近200张表(大部分表是基本不变的),数据最多的表有数百万行(基础数据大约70万行,对每个基础数据每月会增加7倍的数据量)。但是看起来与20张表/数万行的系统没有什么差别。有一些业务的确采用继承和多态来思考非常简单,而采用二维数据集来处理反而相当麻烦。
数据规模对采用哪种技术框架没有太大关系,有比较大关系的是业务复杂度。
非常同意!
O 和R 的平衡也确实是O/R M设计中非常重要的问题。
巧的很,昨天晚上还在和一哥们讨论ORM,比这儿的讨论激烈多了,呵呵。
我们的项目是半ORM,半SQL数据集的,对于复杂的业务逻辑来说,还是ORM来得爽。
@冻未调
首先我对你的感受表示理解。
其次同意是有这样的程序员,对技术跟风。较少真正考虑客户感受。
但是这里讨论的问题跟你说的问题好象没什么关系,ORM对你来说没有什么意义。
就好象你不用关心电器商城是派男的还是派女的来给你安空调一样,只要让你爽就行了;)。
@双鱼座
我的意思不是说这种级别的应用不要ORM 相反 任何数据库应用都应该使用ORM
我否定的是对中大型的数据库应用完全从O->R
如果就关系来说 从表和对象的角度我觉得都问题不大
而对继承来说 大家都知道表的实现有多种方式
这个时候只考虑O而不考虑R是不实际的
有人会说R推迟实现 那么这样O又何尝不是类似前期的一种需求分析呢
如果这样 我觉得就都可以算O->R了 从用例分析开始 就体现的是一个个OBJECT和METHOD了
分析之后 对于domain object,entity class 还是 table其实我觉得已经是一种并行处理了
上面的讨论好像主要集中在O和R上,是不是该讨论下M了:)
@progame
关于继承,我是肯定不会再考虑表的。参见我的文章http://barton131420.cnblogs.com/archive/2005/12/01/288223.html。
其实我说的R->O这个过程是指兼顾数据库结构的清晰度,并不是说完全不考虑其对象层面的实现方式。
@冻未调
但是做出来的东西跟我们的业务南辕北辙,就像玩具,根本不是我们要的,
真有一脚踩在他脸上的欲望,对楼上的诸位也是!
业务出现问题,我觉得,用户方面至少要负60%以上的责任,因为软件是你们的,你没有理由要求开发人员熟悉你们的业务,最根本的原因是你们自己的需求定位出现了问题。
@冻未调
真的有点怀疑你的人品了!打个比方:你被人骗过一次,以后见到人你就骂?况且:系统没做好,难道完全是软件公司的责任?你也不反省反省自己的需求做的怎样?
O/R Mapping也用了,很多问题变得简单了,但是有些问题确实不好解决。
O/R Mapping这个东西,数据量大小/业务复杂与否都可以用,不过在不合适用的地方不用就行了,没必要极端的用。
系统没有被完美的实现是很正常的,只要你清楚这些地方,他没有给系统带来很大影响就行了
ORM不是代码生成,ORM解决的是数据的持久化问题,使应用层和数据层脱离耦合,ORM应该是中间件的概念,或者说是数据端的API,重点在mapping,个人觉得O/R不O/R的也不是非常必要
请问楼主,ORM其它的不说,
关系到整个系统时,你又怎样处理它与UI,Business等层的关系呢,而Business层又是怎么样设计,使business中的object与ORM特别是每个Object统一对应,而没有别扭呢?
比较认同你的观点,前天正与同事讨论这个问题,同事建议映射存储过程
真不知道怎么回答,呵呵
文章指出O/R Map的本质
ms注重数据,而java注重行为。
因此对于数据量大的应用ms比较适用,而对于应用逻辑复杂的应用则java比较合适。但是ms更有优势,个人感觉ms要想向行为方面转变也是一件相当容易的事件,.net与java也没有很大的区别。
但是测重点不同,关注利益也不同,所有ms在一段时间内还是会也“数据”为主,但是会慢慢向行为靠近。
而那时java处境则不妙,毕竟他要转到以“数据”为主是很困难的(毕竟微软是数据库厂商)。
因为orm要配置xml,数据库改表结构那就是惨事。hib需要学习hql,hib速度不怎么好,一下子load了多表数据。orm调试麻烦,需要xml与代码混合观察。orm提供的模型要求我们把对象映射为关系数据库表结构,如果文档做不全或者更新不及时就很难移交程序。
我有个比较好的解决方案,使用speedframework框架,我已经使用它一年多了。
Speed 快速 J2EE 开发框架
Speedframework(http://sourceforge.net/projects/speedframework)是一个完全基于JDBC开发的轻量级持久层框架. 它可以直接调用SQL,也可以直接对POJO进行CRUD操作,代码与ORM相当.调试方便,不用配置,内置JCS缓存,能有效降低数据库压力,它具有以下特点:
1.免配置持久层,免配置可以减少开发中配置带来的烦恼,调试带来的烦恼。
2.完全是jdbc封装操作,性能完全没问题。
3.jcs cache实现,对于数据库操作对象缓存减轻数据库压力。
4.自带分页组件,完全可以直接传入一条sql即可完成困难的分页逻辑,可以由客户自定义。
5.结合表、视图实体逻辑设计模式可以实现xp开发。
6.speed能自动识别表字段pk的自增主键,并可以返回自增字段值。
7.实现了jdbc的批处理封装,存储过程调用等jdbc api常用的封装。
8.降低了入门门槛,有利于初期开发和中后期维护,适用于开发程序员经常更换的团队。
http://sourceforge.net/projects/speedframework/
模型描述语言,毕竟不是面向对象的语言,虽然平时都直接使用通用语言(java c# python...)顶多再加点xml代劳了,但它毕竟只是描述,没有逻辑。试问有谁再描述领域模型的时候会使用到继承多态呢?有谁不会涉及到one-many、many-many之类的关系数据库术语呢?
我想以关系数据库的角度看问题已经深入人心,就算Hibernate也还是充满了one-many、many-many之类的关系数据库术语,因为人们不可能不去考虑对象到关系的具体映射过程,毕竟底层还是关系数据库,orm只是个wrapper,所以注定无法完全面向对象。
而且我强烈怀疑,描述领域模型的时候真的需要继承多态这些东西吗?
所以我觉得orm介于关系数据库和面向对象之间的,拥有面向对象的外皮和关系数据库的实质,是对关系数据库的一层面向对象的wrapper而已。
至于 orm 的性能呢 我觉得是不用担心了,通常orm都采用延迟计算的方式,构造sql语句直到最后一刻才查询数据库,hibernate更是支持存储过程。
另外动态语言(ruby、python) 的 orm 使用的模型描述语言用起来是很爽的。
我想做一个关于ORM论文,看了大作真有茅塞顿开的感觉,但是下面这两本书没找着,不知能不能给小弟发一份,不胜感激^_^ 邮件 t_mail2008@hotmail.com, thank you very much
Patterns of Enterprise Application Architeture
Domain-Driven Design
@woyer
文件相当大,无法发送。不过我可以保证这两本书在网上能找到。你可以试试itpub或google
不推荐使用ORM,业务需求变化后,需要修改数据库数据表存储过程以及Object,还要重新编译。
建议采用SP+XML方式,需求变化后修改量最小。
Why ORM?
ORM用好了是有诸多好处
但是一个不成熟的程序员用一个难以理解的ORM体系的话,你看着吧.....
冻未调说的情形我觉得在些小型甚至中型的软件公司中很容易有这类情况发生
写的很不错,虽然很容易引发争论,但是技术就是这样,有利就有弊,不同技术背景的人有不同视角。不过能写出来给大家分享,就值得支持一下。
我看了超过10以上,从一点都不懂到懂一点点在到清淅了一点点到现在差不多明白了这篇文章所想要表达的意思!!! GOOD ,从看到这篇文章起命使我慢慢的积累了ORM的许多知识! 真的很谢谢 idior ~ 我会继续地一直关注你的文章的
^-^!