关于O/R Map的讨论(200分)

好久没来,居然这么热闹啊?哈哈。
在Java的世界,OR mapping一直就是最受关注的技术,目前也是和.net战斗的焦点。
看看数据访问技术在Java世界走过的路,很有趣。
1、最初是JDBC,这个我想大家都没有异议吧?虽然它很成功的统一了数据访问层的界面,但是
它不是面向对象的。这并不奇怪,虽然它是用OO的JAVA语言定义的,但是这个数据访问层不可避
免的是面向关系的语义。因为它仅仅是个底层接口。其后针对这样的问题有不少解决方案。象
DAO这样的J2EE design pattern就是一列。但也只是责任的转移,并没有根本地解决这个问题。
2、再之后就是EJB中的EntityBean了,它在一定程度上解决了“将面向关系的语义改进为面向对
象的语义”的问题,它也很成功。但其致命的缺点就是由于最初的设计失误,使得其承担了本来
不应该由它具备的特性,导致的结果就是性能不足。当然我不是再攻击EntityBean技术,它在很
多时候还是适用的。特别是在大多数数据访问操作都是针对同样数据时,由于应用服务器的高速
缓冲能力,此时的性能还是相当强悍的。
我之所以说是设计失误有以下的原因:
由于最初EJB的设计目标就是对Bean按照职责进行分类,并且使其具备同样的对象模型,并为
client提供同样的视图。特别是后者,导致了设计者们不得不让EntityBean具备了过多的特性。
看看EntityBean的设计目标:
1)提供一个标准的方式以持久化你的domain model
2)封装持久化机制,(也就是完成OR mapping)
3)为了和SessionBean保持一致,EntityBean必须是暴露到网络上的分布式对象,可从任何地方访问。
4)同样是为了和SessionBean保持一致,它必须是具备事务特性的对象。
ok,很明显上述的第三和第四个目标是根本没有必要的。我想绝大多数人都会用SessionBean来
包装EntityBean,也就是client只应访问SessionBean调用企业逻辑,而EntityBean只应由SessionBean
来访问。那么为什么要把EntityBean暴露为网络上的分布式对象呢?另外既然SessionBean包装了
EntityBean ,那么后者是否还有必要具备事务特性呢?显然不必要。然而正是由于3)4)两个设计
目标极大的影响了性能。
为什么会有这样的设计目标?原因就是要保持SessionBean和EntityBean的一致性。对于最初的
设计者而言,他们的想法是:对于每个Bean而言,它应该感到有一个专有的容器为它提供服务,该
容器里也只有它一个Bean,所以它应该暴露为分布式对象对外提供调用接口。所以Bean与Bean之间
完全独立,它可以认为任何其它的Bean都是在另一个服务器上的另一个容器中运行(网络透明/位置无关)
这样的设计我想也是为了强大的可伸缩性能力,因而也使得真正的完全集群,均衡负载成为可能。
付出的代价就是性能。但是EntityBean是否也应该具备这样的特性呢?回到现实世界来说的话,
完全没有必要!
(btw:目前的EJB规范,特别2.x规范针对这样的问题,极大地强化了CMP能力,并引入了Local interface
甚至倡导人们使用local interface,呵呵,java世界技术的进步完全是为了实用,可不是为了广告
另外比较有趣的是:如果大家对JDO也比较了解的话,会发现目前的EntityBean技术极大地借鉴了JDO的思想
甚至实现手段)
3、数据访问技术第三阶段(目前)的发展就是JDO了。我认为它将是阶段性的终点。
JDO可以说是真正地完成了OR mapping。当然我是说它的设计思想,第一版的JDO规范还不完善。
它给予人们的能力就是:一切都是对象,你只需要与对象打交道。
关于JDO有一句著名的话:
Java Data Objects seem to be what Entity Beans should have been.
当然这句话还很有争议。有兴趣的兄弟去theServerSide搜索一下。
想想看,很简单的纯粹的java class就能完成标准的持久化访问,并且我们根本不需要关心其下
的持久化机制,而且性能强劲。不许要裹脚布一般又臭又长的部署描述器,不需要大量的JNDI
lookup查找domain model类。我们直接与封装完好的domain model 对象打交道。JDO自动地为
我们做到了这一切。
由于目前小弟也在学JDO,所以无法深入讨论。不过可以提点建议。
对于学习用的JDO实现,Libelis的JDO实现比较标准,但是只是用于教学用的。你别指望将来
在现实世界中使用它。另外一个是Apache的obj。大家想必知道Apache Jakarta工程在Java世
界的分量吧?我目前也在用它。它的优点就是体系结构非常清晰,容易理解,如果各位剖析
一下它的源代码就知道了,而且是真正为了现实世界的使用而创建的。第三个就是Castor了,
这个玩意儿让我想起原来曹晓刚在哪篇帖子里面提到的:
数据库模式 ——Java Class——XML Scheme
之间的mapping,呵呵,Castor就是专门用来做这个的。而且做得相当的好,只是由于Castor
出现得比JDO规范早得多,所以目前对JDO规范的支持还不完整。它和obj相比,体系结构不是
那么清晰,所以说要让它完善支持JDO规范,任务即使不说艰巨,还是有一定难度。
最后,我也是Jdo的初学者,上面的观点很可能有不妥之处,期望大家多多交流。
 
另外要补充一点,曹兄曾提到过
数据库(关系)模式 ——Java Class——XML Scheme
之间的映射问题。我懒得去翻那个帖子,所以顺便在这里谈谈看法。其它方面曹兄已经说得很好,
我就不提了。这里只是把我所认为相当重要的方面提一下。
确实,这三种都是对数据的表示方法,或者说信息的载体,并且可以完整的一一映射,不会有
信息丢失的情况。但是它们还是有不同的适用领域。先看它们的特性:
数据库模式: 面向数据的存储。
Java Class: 以这种方式表现数据,方便对数据进行操作,
XML Scheme: 与平台无关的数据表示,便于在异质平台之间的交流。
数据库模式我就不说了,目前大概99%的企业信息是存储在数据库里面。它适用的领域就是存储
以及方便查询。Java Class来表现数据,方便对数据进行操作。所以在数据库模式和Java Class
之间的“直接”映射是绝对必要的。但是XML Scheme扮演的角色是什么呢?是否有必要“直接”
在Java Class和XML Scheme之间或者数据库模式和XML Scheme之间映射呢?这正是我要讨论的。
注意:我说的是“直接”。
我的观点很明确,没有必要。我是说同样一份数据在前两者和XML Scheme之间的“直接”映射。
数据是为了操作而存在。用JAVA Class来表现数据方便了对数据的操作,那XML Scheme跟操作
或者说企业逻辑有什么关系?那就是:由于XML的平台无关性,它非常擅长于表现企业逻辑运算
的结果,而不是直接表现存储在数据库中的数据。因为后者根本没有必要。这里我有点极端(稍后
我会谈到在某些特定情况下的它的适用性)
“用XML来表现企业逻辑运算的结果数据”给予了我们什么能力呢?一个就是方便机器间的交流
这一点非常适用于B2B领域。与我们这里谈到的话题相关的就是:用XML来表示远程调用的返回值,
这个在目前的SOAP和XML-RPC上得到了证实。这里我之所以只提到返回值,是因为我们谈论得是用
XML表示数据的话题。至于用XML表示调用参数甚至表示调用本身(如SOAP和XML-RPC所做得那样)虽
然和我们讨论的话题关系密切,但仍然已经属于另外一个话题了。
“用XML来表现企业逻辑运算的结果数据”还给予了我们另一个能力,那就是在WEB应用领域,
分离显示与逻辑。这是个老话题了。大家已经谈得很多。这里就不提了,可以参见以下联接:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1272549

ok,我们已经知道xml适用于“用XML来表现企业逻辑运算的结果数据”了。那么它是否
适用于”直接表现存储在数据库中的数据“呢?也就是我前面提到的是否有必要“直接”
在Java Class和XML Scheme之间或者数据库模式和XML Scheme之间映射呢?我开始的回答是
没有必要,现在我得改正一下,它还是在某些情况下适用的,考虑一下象BBS这样的轻量级
应用,用户的帖子数据保存在数据库中,最理想的方式就是,当查询时,直接用数据库中
直接取得帖子,并直接映射为XML,然后套上XSL发布就行了。这确实是最理想的。ok,看看
这样的特殊情况有什么特点:
首先,它的查询操作远远大于更新。不过这不重要。
其次,它的“企业逻辑运算”量非常之少,几乎可以说没有。这才是最重要的。
我的看法,只有在以下情况下,数据到XML Scheme的直接映射才是有用的:
对数据的要求:在整个应用系统中,对这种数据没有或极少有应用逻辑操作。
这个很容易理解,在大型应用中,即使都是存储在数据库中的数据,仍然有不同的属性
,有些数据和企业逻辑操作紧密相关,有些则不。
对于这样的数据,将其直接映射为XML后,可以套上XSL摸板直接发布为HTML/WML。。。,也
可以不带任何格式信息在机器之间交流。不过我想最常用的方式是,将其直接映射为XML后,再
结合“针对其它数据进行企业逻辑运算”后以XML表示的结果,再套上XSL发布或者直接在机器
间交流。
ok,一点浅见,盼多多指教。
 

TMD,干嘛不一次说完?还有几句废话:
关于XML在服务器端的应用的性能问题,其实如果调整优化得好的话,是不足为虑的。
两个主要的手段:
1、最好不要用DOM,改用SAX。
2、如果要在服务器端使用xsl,可以把它预编译为XSLet,也有人称为translet.这个前面
曹兄已经提到了,其主要原理很简单,预先把XSL文件被解析为JAVA对象,并缓存起来。此
后将重复使用它,也就省了解析这个步骤。(不要小看这个步骤,每次都来一下这个步骤那
性能损失就可观了)。而我们付出了什么代价呢?什么代价也没有。要知道相对于XML数据
文件而言,XSL文件实在可以说忽略不计。比如DFW的xsl文件就那么几个,而每天动态生成
的xml文件有多少?由于这个性能优化方法很多人都还不清楚,所以这里多谈了点。
 
难得oskiller把我想说的话都一次性说完了,让我只有望其颈背得份 [8D]
不知道killer兄能不能另外开帖子详细讲述一下apache OJB?能够听到别人嚼碎后的体会,总比
自己去折腾好多了~
 
曹兄,
您别夸奖我了,我也刚用OJB呢。当我觉得我真的搞懂它了,会把心得放上来,期望大家斧正。
 
我把各位的意见总结了一下,请大家看看是不是这个意思
1.应用程序分成三层:表示层,业务逻辑层,数据层
2.数据层分为:数据访问组件和业务实体
(1)数据逻辑访问组件的作用是:
·正确处理事务处理问题
·执行数据分页
·实现缓存策略(连接池)
·管理和封装锁定模式
(2)业务实体的作用是:
·业务实体提供对业务数据及相关功能(在某些设计中)的状态编程访问。
·业务实体可以使用具有复杂架构的数据来构建。这种数据通常来自数据库中的多个相关表。
·业务实体数据可以作为业务过程的部分 I/O 参数传递。
·业务实体可以是可序列化的,以保持它们的当前状态。例如,应用程序可能需要在本地磁盘、桌面数据库(如果应用程序脱机工作)或消息队列消息中存储实体数据。
·业务实体不直接访问数据库。全部数据库访问都是由相关联的数据访问组件提供的。
·业务实体不启动任何类型的事务处理。事务处理由使用业务实体的应用程序或业务过程来启动。
O/R Mapping是在业务实体层完成.
与客户端交互的应该是业务实体.数据访问组件应是透明的
问题关键点:数据持久化,并发性问题由组件还是数据库解决
 
http://www.delphibbs.com/delphibbs/DispQ.asp?LID=1578522
 
多人接受答案了。
 
顶部