着样好啊!好象很多项目都没有用 ENTITY BEAN,而用 HIBERNATE OR JDO 来实现数据持久层

解决方案 »

  1.   

    谢谢!我觉得数据模型还是要抽象的,EntityBean还是有必要的,只不过都是BMP(DAO/Impl)模式的,其中涉及数据持久的部分都用hibernate?就是说没有CMP我的理解对不对?
      

  2.   

    Hibernate 与CMP的对比:
    以下这篇文章是Gavin King写的,非常有趣,充分体现了Hibernate的设计理念,也展现了为什么Hibernate如此成功:
    下面是对Hibernate开发工作的个人想法,正是这些工作使得Hibernate如此迅速的得到广泛的欢迎。
    1、飞快的版本发布
    保持活跃的开发速度,经常进行版本发布,甚至几天之内就从前一个版本开发到下一个版本。这样是保证软件远离Bug的最好的办法,也可以让用户感到很放心,确信Hibernate的开发十分活跃,另外这样做也有一大好处,就是可以发现哪些功能是用户真正需要的。
    2、回归测试 
    我想现在整个Java社区一定都很重视自动回归测试。如果软件的功能和设计有比较大的修改,那么一个综合性的test suite对于软件可维护性和稳定性来说实在是太重要了。我们应该有这样的意识:如果对软件的一个新功能没有进行回归测试,我们根本就不该去做它。
    3、把一个功能做到最好
    要么不做,要做,就一定做到最好。那些我们做不到最好的功能,我们根本不去做,扔给其他软件去做吧。
    4、避免过度设计
    浪费大量的时间和精力进行软件功能的抽象和扩充软件的灵活性,还不如多花点时间来解决你的用户面临的实际问题呢!简单一点! 软件能跑起来就OK,不要尝试去解决你的用户根本不关心的问题。就算你的软件设计的不够优雅也没有关系,反正还是initial阶段嘛!以后再refactor,你应该关注的问题是及时的把有用的功能给做出来。
    5、集权
    在你需要由民主投票来下决定之前,至少你已经把软件轮廓做好了。软件开发需要由一两个开明的人来领导,这样可以保证软件开发的连贯性而不至于产生太大的分歧,可以保证开发团队集中火力把要实现的功能做到最好。我觉得,OSS软件最大的风险就是意见不统一,摊子铺的太大,结果最后搞的什么都没有做好。
    6、文档
    没有什么比文档更重要的了。如果你的用户不知道你的软件有这么一个功能,就等于没有这个功能,干脆把它去掉得了,省得给源代码增加复杂度。
    7、避免标准化
    好的标准可以带来软件的互用性和可移植性,坏的标准能够窒息软件创新!“支持XXX标准”根本就不是真实的用户需求,特别是当这个XXX标准是那些在其位不谋其政“所谓”的专家委员会制订出来的。(译者按:莫非指Sun,IBM等几个big name?)最好的软件是在不断的尝试,不断的出错,不断的经验积累的过程中产生的。事实上的标准往往更加贴近用户需求。
    8、10分钟之内把Hibernate跑起来
    潜在的Hibernate的用户在他们下载了Hibernate,第一次使用的时候根本就不可能花半个小时那么多时间来安装、配置和 troubleshooting,他们早就丧失了对Hibernate的兴趣了。我们的口号就是新用户(假设有足够的JDBC知识)5分钟之内把 Hibernate的Demo跑起来,而他们能够在1个小时之内写出“Hello World”式的最简单的Hibernate程序并且正常运行。
    9、开发人员的责任感
    用户总是不可避免的碰到问题,开发团队有责任有义务提供帮助。用户让我们知道了文档的漏洞,用户让我们知道了测试用例的小bug。此外,没有用户来用我们的Hibernate,我们还开发它做什么,不是浪费时间吗!
    有个关于bug的笑话:用户根本不介意发现新功能的bug(译者按:Windows的用户好像都是如此),只要你能迅速的改掉bug。“责任感”意味着 bug修复应该在1周之内。从收到bug报告到bug修复代码提交到CVS上要做到平均在24小时左右,这才是一个理想的目标。
    10、易用的、可更新的wiki网页
    (译者按:wiki是Hibernate网站用的一个web发布框架)
      

  3.   

    通过对Hibernate和CMP原理和实现方式等方面的了解认识,我想hibernate至少比CMP2.0有以下优点:
    一、 兼容性。 规范一模一样,实现各有不同,这是CMP的现状。因为EJB并不是一个产品,而是Java服务器端服务框架的规范,众多软件厂商根据它来实现EJB服务器,这就留下了兼容性的隐患,很可能出现在一个厂商的服务器上开发的产品拿到另一个厂商的服务器上就出现问题的情况。用第三方O-R Mapping工具可以解决这个问题。
    二、 保护智力投资。“在了解了Orion, Weblogic, JBoss的CMP实现后,我不愿意再去学习Websphere 或者Resin的实现了。”这是一位资深的Java开发人员在谈论CMP时讲到的,CMP的实现更可分为多种服务器方式,要针对不同的EJB服务器去学习相应的CMP实现方法实在是费时费力。
    三、 性能。
    (一) local v.s. remote。hibernate、JDO、Castor都是本地调用,CMP2.0虽然也有Local接口,但是Web层还是需要通过Remote接口访问EJB层的数据,序列化、网络调用、创建大量的对象,都是性能降低的原因。
    (二) transaction。J2EE提出了一个全新的事务模型(method-based descriptor),对程序员的开发确实是个“简化”,但这样的结果是什么?性能极度降低!互锁!没有办法,我们只有再去调节各个方法的Transaction属性,然后又出现,新的互锁...
    新的事务模型是不成功的。它试图简化问题,却引入了更为严重的问题。各家厂商的Transaction实现也不尽相同,有的支持Optimistic Lock,有的在VM中同步Entity对象,又是兼容性的一大敌。
    hibernate没有试图创造一个更新的模式,相反,它沿用了传统数据库的Transaction编程模式,在对J2EE的Transaction伤透脑筋后看到它,真是十分亲切,感觉自己确实在编程,而不是碰运气填代码了。
    四、 动态Query。
    Entity Bean很难实现动态Query,这是因为它基于代码自动生成技术,即最终的执行代码是在部署编译时生成的。hibernate则有根本的改变,它基于reflection机制,运行时动态Query是很自然的事。另外,hibernate几乎支持所有的SQL语法,传统数据库可以做的它就可以做。
    五、 发展速度。
    很多开发人员希望,有一天Entity Bean会变得很好。但至少目前来看,Entity Bean是一个不完善的产品,它是大公司政治斗争和妥协的产品,而且习惯性将一些问题“无限期搁置”,典型的例子就是Query(之所以不提其他问题,是因为其他都是Entity Bean的致命伤…)
    形成强烈反差的是,hibernate的核心程序员只有一人,但它改进的速度确是Entity Bean无法企及的。
    六、 继承和多态。
    OO语言的精华在Entity Bean这里是行不通的,我曾经自我安慰将Entity Bean看做一个“内存中的数据表”,才找到了一点平衡。
    但当我看到hibernate时,又开始不平衡了。Hibernate拥有继承、多态等多种OO的实现理念和方法,应用时非常符合OO语言的特性。
    七、 多表关联。
    CMP在JBuilder里面开发很方便,不过在JBuilder里面也只是1个表映射1个CMP,如果表非常多,并且很多表之间存在关联呢?
    在数据库里面有80多张表的情况下,其中绝大部分的表都会用到连接查询,如果是用CMP映射的话,必须把这些所有的关联关系都设计成CMR,那就意味着,这80多个CMP必须在一个EJB Deginer里面设计,并且只能打成一个jar包。这是非常恐怖的事情,稍微错一点点,全都完蛋了。
    现在CMP都不会直接暴露给客户端,用Session Bean来封装Entity Bean,那么CMP的事务功能,安全性检查都没有必要,光是一个O/R Mapping的功能,就不一定非用CMP不可。用Session Bean+JDO(O/R Mapping)一样可以实现分布式。更准确的来说,甚至业务对象都可以不用Session Bean,前面加上一层Session Facade就可以分布式了。另外,在代码维护方面,CMP2.0也有一些缺点是可以弥补的。
    大量的接口文件和配置文件,开发和维护的工作量很大。
    解决途径:采用xdoclet,可以自动产生众多的接口和配置文件,甚至facade, delegate等高级模式。
    至少目前来看,hibernate在代码维护方面的缺点有:
    hibernate提供了自动生成mapping文件“框架”的工具,但还需要手工调节。而这类开发,能想到的最佳模式就是xdoclet的(代码+注释)的模式了。幸好,hibernate的程序员已经向xdoclet项目增加了hibernate的模块。现在需要的是等待xdoclet的下一个 release。 
    从整体方案来看,如果说不使用Session Facade模式的话,我认为Entity Bean还是一个很有意义的的东西,因为Entity Bean是唯一直接支持跨RMI的持久化方案。但是由于Entity Bean的效率和减少跨RMI的网络调用的原因,Entity Bean已经完全被封装到Session Bean的后面,Entity Bean的分布式调用的功能,安全验证功能,容器事务功能完全被前面的Session Bean给做了,结果Entity Bean就只剩下了唯一的ORM功能了,单就ORM这一点来说Entity Bean实在是一个非常糟糕的东西。那么Entity Bean还有什么功能值得我非去用它不可呢?
      

  4.   

    用 Session Bean + DAO + Hibernate 来取代 Session Bean + Entity Bean,不但能够极大降低软件设计难度,软件开发难度,软件调试难度和软件部署难度,而且还可以提高允许效率,降低硬件要求。
    不要把Entity Bean直接拿来和Hibernate做比较,两者不是一个范畴的东西,而应该整体比较两种方案:
    Session Bean + DAO + Hibernate
    Session Bean + Entity Bean
    很难找出第二方案有哪怕一点方面能够比第一方案好的。
    CMP可以使用CMR来表示多表之间通过外键关联的关系。但是你仍然会遇到即使没有键关联的表仍然需要连接查询的情况,这是一个非常普遍的现象。
    如果是Hibernate,可以在HQL里面定义outer join,BMP也可以写JDBC,而CMP没有任何办法来解决该问题,除非把需要的连接查询都定义为CMR,但那样的话,凡是有需要连接查询,或者有键关联的表都必须打在一个包里面。你如果不打在一个jar包里面,如何能够建立CMR?不是我们想放在一个jar里面,而是不得不放在一个jar里面。基本上CMP还是非常笨拙的。
    CMP的另一大缺点是不能动态SQL,前面已经提到了。一个SQL就要定义一个EJBFinder方法,在编译的时候就确定死了。在实际应用中,经常会遇到不确定查询条件的查询,比如说用户在页面上用下拉列表来选择查询的条件,用户既有可能什么限制条件都不选,也有可能选择某几个条件。这时候你怎么办?假设有n个查询条件,你要写 C1n + C2n + C3n +...+ Cnn(C是组合公式的符合,n是下标,1...n是上标)个EJBFinder方法才行,很恐怖吧。
    其实JDBC的PrepareStatement也不能很好的解决这个问题,因为它是按照1,2这样的次序来set参数的。用Statement是肯定不行的,会严重影响数据库,甚至会导致数据库down掉。但是Hibernate就解决的不错,因为它可以按照 :name 这样的形式来设定SQL中的Placeholder,这样set参数就可以按照参数名称传递,因为次序不是死的,在程序里面就很容易根据用户选择的查询条件,动态的产生SQL,动态的set参数了。
    CMP2.0还有一个大问题是不支持order by,当然你可以在Java里面对取出来的集合排序,但是速度和数据库里面就排好序速度不在一个数量级了。Hibernate不但可以order by,还可以group by,having,子查询,真是没有办法比下去了。
    其实对于动态SQL和排序问题,特定的App Server也可以做,但那不是CMP2.0的规范罢了,所以为了可移植性,也不敢随便去用。
    在项目开发时,开发和运行效率以及灵活性是非常重要的指标。由于Entity Bean天生是一种粗粒度的使用方式,这就必定使它在装载的时候有较长的响应时间,也不能自如的支持懒装入的方式,使用成细粒度会使程序变得复杂,以及远程调用细粒度的entity bean是一种非常可怕的行为, 太慢了。
    Hibernate正好满足开发和运行效率以及灵活性,说来说去,它可以称做一个OO化的JDBC, 这样大家就不会对Hibernate产生误解及恐惧心理。它支持粗细两种粒度方式,运用起来灵活自如,前提是你必知道如何使用,一个entity bean实现要N种重复的方法, 诸如ejbRemove,ejbstore,ejb....,光类也有一大堆,象Home Interface, Romote Interface..., 如果需要Primary class,Hibernate只需要一个就行了。
    CMP在进行O/R Mapping方面只是做了最基础的工作而已,完全用CMP做数据层,会发现在把数据库应该做的工作全部都搬到App Server里面来重新实现一遍,有这必要吗?
    CMP是把EJBQL写死在ejb-jar.xml里面的,所以n个条件就需要(c0n+c1n+...cnn )2的n次方个EJBFinder方法,简直没有办法说。
    JDBC实现PrepareStatement的动态SQL构造不是不能够,而是非常麻烦,需要写一个非常非常大的if elseif else嵌套的判断。
    Hibernate实现起来特别简单,(其实OJB也实现了PrepareStatement的动态SQL构造)这本身并不复杂,但是需要多写些代码而已,由于CMP把EJBQL写死在配置文件里面了,连选择的余地都没有。
    总体来看,Hibernate完全符合我在第三章末提到的我们需要的开发模式的几项标准,即:
    一、 开源和免费的License,我可以在需要的时候研究源代码,改写源代码,进行功能的定制。这样就不需要投入大量的资金去购买EJB组件了。
    二、 轻量级封装,避免引入过多复杂的问题,调试容易,也减轻程序员的负担。简单的设计,快速的开发,这正是我们所需要的。
    三、 具有可扩展性,API开放,当本身功能不够用的时候,可以自己遍码进行扩展。
    四、 开发者活跃,产品有稳定的发展保障。
    同时,HIbernate也解决掉了CMP的大部分缺陷,而且方式之优雅令人赞叹。Hibernate的文档也是非常非常有特色的地方,它不仅仅是Hibernate的功能介绍那么简单,它实际上是一个持久层设计的最佳实践的经验总结,文档里面的例子,文档里面的总结全部都是最佳设计的结晶。我认真的把Hibernate读下来的感觉就是,不单单把Hibernate的关键点掌握住了,而且对持久层的设计的经验都长了一大块,以前可从来没有觉得持久层的设计还有那么多的学问,也由此感觉到Gavin绝对是一个大牛人。
    当然选择Hibernate最最重用的原因是Hibernate是一个我能够完完全全驾驭的了的软件。Hibernate的源代码非常少,而且写的非常简洁,我总觉得挺奇怪的,这么少的源代码能够实现这么多的功能,是个奇迹。通过对几种开发方式的深入接触,我觉得用Hibernate让我特别放心,我能够驾驭它,而不像那些过于复杂的软件,本身框架就复杂的很,再加上不开源,出了问题也不知道怎么回事。
    后来的实践证明,选择Hibernate是正确地。在整个开发过程中,Hibernate逐渐显现出了它强大的优势和魅力,真正是轻量级的、开发灵活的、全局易控的。
      

  5.   

    兄弟!你这些文章我都看过,我已经决定采用HIBERNATE做数据持久层...谢谢!重新看过这些文章,我搞清楚了一个问题:CMP是和Hibernate互斥的...我就是不明白是不是有没有必要取消所有Entity,照你的说法Session Bean + DAO + Hibernate 来取代 Session Bean + Entity Bean,那么BMP的Entity也要消失,业务逻辑直接面对持久层?那叫什么OOP设计模式阿?我在想是不是应该Session Bean + Entity(BMP) + DAO + DAOImpl(hibernate) ?
      

  6.   

    求解:做过EJB + hibernate的大侠指点!
      

  7.   

    在Hibernate和CMP的问题上,我有点看法,我觉得对数据库的简单操作可以交给CMP完成,这是因为现在的开发工具对CMP的支持都很好,能很快地开发应用系统。
    但对于比较复杂的操作,以前是交给BMP来做,现在交给Hibernate好了。
    ==============
    在技术上,我们不应该带有感情色彩,你不能因为某技术的一点(一些)不好就全盘否定,CMP的确有些不足,但它在很多地方是优秀的!仍然值得你去学习,去使用。
    我现在理想的模式就是:
    SessionBean + CMP/DAO+Hibernate
      

  8.   

    你也把BMP否了?那就要用sessinbean + Session Facade做映射对不?CMP适用的是哪些应用?简单的一张数据库表对应一个Entity的模式?
      

  9.   

    BMP在我看来,它只是CMP的一个补充。它只是为了解决CMP刚性太强的问题,因此它的特点是过于柔性.我不知道你做过BMP没有,它说穿了是什么?就是SESSIONBEAN+JDBC。
    我觉得BMP在没有HIBERNATE或者其他替代技术出现之前,它可以完成CMP完成不了的东西,是非常好的一个补充。但有了HIBERNATE之后,我想像不出它的存在价值。
      

  10.   

    也对...我们说的是一个问题,只不过角度不同而已...我当然做过BMP,我的理解还是用BMP来做OO映射,hibernate做的是替代JDBC的功能...其实用hibernate也要有OO的映射关系,好像也部分替代了BMP的映射的步骤,我要重新考虑设计思路.一直理解hibernate就是个JDBC,呵呵...
      

  11.   

    无论是CMP\BMP\HIBERNATE,这些技术都是为了帮助我们更快速地建立更稳定更高效更易于维护的系统。
    注意我说的:更快速、更稳定、更高效、更易于维护。这都是你在选择技术的时候要考虑的问题。
    我看过我们公司以前做的一套系统,是JSP+JDBC搞定的,别的都没得说,但就是一点:没法维护了。我在想,如果设计人员当时用了EJB或者其他的技术,现在维护起来要方便多了。但转念一想,这样的话,其他的毛病不是又出来了?
      

  12.   

    那就来简单说说罢!我原来一直用Entity Bean做对象的封装,如果完全改用hibernate,会不会有线程安全、EJB容器的分布式、JAAS等等问题出现阿?
      

  13.   

    上面转的文档里面对比的都是CMP和hibernate,我深表赞同!BMP完全被取代的话,那至少我的对象就不能通过JNDI找到,这就是最简单的问题...
      

  14.   

    别小看JSP+Javabean,确实适合快速开发,当然是你要用比较好的设计...我就见过一套什么新技术都没用的,但是里面体现出的思想确实很先进,没有用Struts但是实现了MVC, JDBC部分里面还有很多hibernate里面的思路...不过遗憾的是这套东西没有完整的文档,被后面的开发人员搞得乱七八糟呵呵...
      

  15.   

    我不知道你说的“线程安全、EJB容器的分布式、JAAS”是指什么。
    其实你用HIBERNATE跟你以前没有区别!因为没有对象跟HIBERNATE打交道,除了SESSION BEAN。
    因此“BMP完全被取代的话,那至少我的对象就不能通过JNDI找到,这就是最简单的问题...”这个问题也不存在!
      

  16.   

    算了!结了!我还有问题等我研究透hibernate再提!