对CMP应正确看待,难道真的一无是处?
浏览完论坛上的帖子,感觉很多大侠对CMP的使用在观点上都存在偏颇,这对后来者和J2EE新手纯粹就是误导。在我看来,系统规模不大或中等的情况下,使用合适的IDE进行EJB2.0版的CMP开发,效率高,代码质量好,运行稳定,对速度的影响也没有象有些人描述的那样恐怖。我不清楚为什么大家都一窝蜂似的抛弃CMP而转投一些五花八门的持久性方案。
浏览完论坛上的帖子,感觉很多大侠对CMP的使用在观点上都存在偏颇,这对后来者和J2EE新手纯粹就是误导。在我看来,系统规模不大或中等的情况下,使用合适的IDE进行EJB2.0版的CMP开发,效率高,代码质量好,运行稳定,对速度的影响也没有象有些人描述的那样恐怖。我不清楚为什么大家都一窝蜂似的抛弃CMP而转投一些五花八门的持久性方案。
是为了使系统结构精益求精,还是为了显示技术实现与众不同?可能本人经验浅薄,能力和认知有限,直到现在也没碰到过Schema设计中有非常复杂的多对多、甚至只对某个字段的映射情况,我想如果有人碰到这种情况的话,多半是因为系统分析没做细致,数据库表结构也没经过优化到BNF3。我认为现在流行的AppServer中,各厂商对CMP的实现都还可以,在性能调优方面,在灵活性设置方面,我实在感觉不到那些JDO实现方案或Hibernate有什么明显的优势。
别人说的并不重要,重要的是自已两者都去试一下,对比对比,看哪一种更适合你。我个人感觉, 跟其它O/R Mapping 比, CMP还需要很多地方要完善, 但绝不是你说的一无是处。
另外,我也不得不承认很多人在使用CMP并没有考虑到CMP的粒度问题,毕竟CMP由于效率问题的限制,只支持粗粒度的Object,而Hibernate等,他们可以支持粗细两种。
所以大家使用CMP时,请一定正确使用粒度问题,在这一点上,还请Banq 赐教.我还没有开始研究petstore的代码, 垦请Banq具体说一下, 例如: 一张表与一个CMP对应 不好的话,应如何去重构呢?谢谢!
如果用AggregatEntity/DependentObject, 来解决以上问题,原理有点象VO, 进行抽象封装,但是如果我调aggregatEntity中的Setter方法, 它会调各个DependentObject中的Setter方法,我不太明白的是,各个DependentObject中的Setter方法如何实现,不会是BMP或是JDBC SQL吧?
如果不是,那是如何实现的呢?
我不太理解你提的DependedObject是不是就是说关联的CMP对象。反正按我的理解CMP中所有的Setter和Getter方法到最后都是基于JDBC实现的,但是并不是说每次调用都做一次数据库访问,AppServer会根据某种策略进行批量DB操作。
<<我不太理解你提的DependedObject是不是就是说关联的CMP对象
DependentObject不是关联的CMP对象。
我只是自已把自已问住了,如果DependentObject不用JDBC SQL实现,那如何利用EJB中O/R Mapping 的优势, 如果DependentObject不用JDBC SQL实现,那还要CMP做接口类于嘛?
上个贴子写的不对,现在改一下也UP一下。
如果DependentObject不用JDBC SQL实现,那如何利用EJB中O/R Mapping 的优势? 如果DependentObject用JDBC SQL实现,那还要Aggregate EntityBean做什么?
如何在CMP中实现一Bean对一表的重构?
这个问题不是我们能讨论清楚的。
关于EJB Entity Bean、JDBC 以及Hibernate选择,可以看看老外这篇文章:
http://www.meagle.com:8080/hibernate.jsp
如果说不使用Session Facade模式的话,我认为EB还是一个很有意义的的东西,因为EB是唯一直接支持跨RMI的持久化方案。但是由于EB的效率和减少跨RMI的网络调用的原因,EB已经完全被封装到SB的后面,EB的分布式调用的功能,EB的安全验证功能,EB的容器事务功能完全被前面的SB给做了,结果EB就只剩下了唯一的ORM功能了,单就ORM这一点来说EB实在是一个非常非常糟糕的东西。那么EB还有什么功能值得我非去用它不可呢?
用 Session Bean + DAO + Hibernate 来取代 Session Bean + Entity Bean,不但能够极大降低软件设计难度,软件开发难度,软件调试难度和软件部署难度,而且还可以提高允许效率,降低硬件要求。
不要把EB直接拿来和Hibernate做比较,两者不是一个范畴的东西,而应该整体比较两种方案:
Session Bean + DAO + Hibernate
Session Bean + Entity Bean
我找不出来第二方案有哪怕一点方面能够比第一方案好的。
呵呵,这篇文章以前看过,不过笔者只认同EJB中的 stateless-Session beans and messaging beans。
我提的问题在EJB实现中的确很难说清楚,不过我个人认为:Sun提出的aggregate entitybean模式仅仅是对BMP说的,如果用在CMP中,就自相矛盾了。
总的来说,CMP局限性太多,因此才有这么多J2EE Core Patterns 来解决很多EJB中的性能问题。CMR也不好,越多的CMP,越差的性能,而且CMP还不能脱离数据库中表的外键使用。
to bruce
" 一张表与一个CMP对应 不好的话,应如何去重构呢?"
使用CMR很方便的前提条件是对数据表设计有限制的。
如果使用CMR,那么就将两个表的对应关系单独设计成一张表,如:
|
这两种表是一对多关系,这将两个表一对多关系设计在address一个表中,这是过去我们统计喜欢作的,但是使用CMR时,最后单独设计一张表,如下:
|
关于CMP性能,我还要补充两句,
为什么“J2EE Core Patterns 来解决很多EJB中的性能”?
因为EJB是个框架组件技术,这种技术在以前一般人没有碰到过,把它当做API使用,API没有框架那样对应用继承介入那么深入。
要想用好EJB,必须了解EJB机制,使自己的应用系统符合EJB本身的节拍,可以说是符合客观规律吧,不再象以前编程那样,由程序员天马行空,想怎么做就怎么做,使用EJB就必须使用这些模式,按照这个框架做,否则违反规律必导致性能降低。
这些都是出于保证项目质量、实现重用性角度考虑的,所以喜欢自由,有个性的程序员是不喜欢EJB的。
但是在大规模生产中,我们更需要的是规则和稳定易懂的程序代码。这已经谈开去了。
总之,EJB不是API,是框架,用框架就是要有限制,这种限制是靠设计模式来实现的。这样J2EE项目的架构设计就非常重要,这些都是架构设计的内容。
再贴一次我个人对Hibernate的定位和认识:
Hibernate是JDBC和实体Bean之间的一个选择,虽然它在开发上与图形化CMP开发相比,节省了一些setXXX字段的编程工作量,但是Hibernate和CMP还是不同重要级别的技术。
Hibernate是替代Jdbc或连接池直接操作的技术,现在还有人津津乐道在研究JDBC 3.0的,象JDBC这样低层的技术除了Hibernate这样的产品研究者比较关注以外,对于一般应用者已经没有价值,这在研究方向上就发生了问题,在J2ee领域,后人总是不断站在前人的框架或层结构基础上的,就象使用Html已经没有必要知道Windows的图形API一样,J2EE领域现在关心的是如何软件如何最大重用,如何划分更细腻的层次,Hibernate无疑是持久层一项好的技术。
Struts+Hibernate确实很诱人,Struts将难以对象化的表现层实现了对象封装,其中ActionForm实际是VO变种,而持久层Hibernate输入输出参数都是VO,这样原来两个
很难实现对象化的层次被对象化了,确实是一个令人激动的事情,以后再有J2EE初学者,就要告诉它们,你们可以不学JDBC这些低层的技术了,直接从Hibernate和Struts
开始学吧,他们会觉得J2EE不再那么难了,可惜我们这些入道早点的“前辈”就要不断煎受取舍的痛苦了。
当然,Struts_Hibernate架构中,没有提供层次来防止很重要的业务逻辑层,因为这一般是由EJB的Sesssion Bean来完成,当然,也可以由
Web层的javaBeans来实现,如同OFbiz, Jive那样做一样,但是对象池等缓冲性能优化、事务锁机制、集群分布式技术都要自己实现,这些当然没有
由EJB容器实现的Session Bean来得干净,而CMP虽然不是一种O/R技术,但是作为由容器实现的技术和Session Bean的标准结合,因此我愿意采取
以下这样的技术:
|
谢谢Banq的回复,
把一对多,多对多的关系用一个关联表来处理的确是个好办法,不过我还是要仔细想想。
<<这样做有两个好处:
<<1.符合CMP的CMR内部实现机制,性能好;
<<2.方便关系重整。
1。我想不仅关联表对CMR有性能上的改善,而且对一些数据库里join 有很多外键的表的时候,性能也会提高。
2。关联表使持久层对所有的表和各种关系都同样对待,简化开发与重构。
由此我们可以探讨一下引入关联表的优势.