Ibatis,hibernate–能者见能,智者见智慧
估计SSH是当下最流行的框架了,一些朋友有时会聊到公司的技术架构,或者是有时要我帮着推
荐一些人,这个词90%的机会会出现,Spring+Struts+Hibernate是个不错的技术框架,其中S
pring作为轻量级的业务层框架,已经非常成功的取代了以前大家不是很情愿的EJB的开发框架
,除了关于支持分布式的问题上,可能会让人犹豫一下,其他基本上听不到对spring说不的时
候,当然通过JTA的方案解决分布式的问题也已经有一些不错的成功案例,Struts作为MVC中最
成功的开源项目框架也是相当成功,作为显示层开发的框架也是相当的得到认知的,所以这里
我们对以上两个框架,并不做太多的讨论,这里我们主要需要探讨的是关于hibernate的应用
。也就是持久层的框架的选择。
首先Hibernate是一个非常优秀的O/R Mapping的项目,在O/R mapping这个方面hibernate确
实是最优秀的框架之一,但是我们的项目中持久层确实只是做O/R mapping这个作用么,如果
仅是如此,确实我们可以选择Hibernate无可厚非,毕竟人家是最优秀的项目之一,为什么不
去选择她叻,但是事实并非如此,在我们的项目中,特别是业务逻辑比较复杂的系统中,这些
项目不是一个简单的信息系统,不是简单的把表里的数据显示出来而已,而且,一些工业对象
中table Object的概念是弱化的,他们的object多是Domain Objet,那么在这样的项目里,
你的hibernate是否还觉得是用的很得心应手叻,在我经历的项目中,我们使用hibernate没有
多少是很成功的,当然也有比较成功的项目,比如信息发布系统,这样的小项目还是比较成功
的,但是一旦domain Object的建模比较复杂,或者是业务流程比较复杂的项目中,就感觉到
不是很成功了,首先功能性上,Hibernate的SQL弱概念性就造成这样的硬伤,由于Hibernate
使用Hql作为他的查询语法,虽然Hibernate的Hql也是以SQL语法作为基础,但是毕竟没有sql
语句那样让人做到更收发自如,遇到复杂饿查询语句,我们不得不费劲心事的去想对象关系的
弥补,有时到最后才发现Hibernate居然转换不出我们需要的那句sql语句,从而放弃Hql的解
决方案,而从新回到我们需要的sql方案,
其二,那些复杂的关系mapping,我们的项目中究竟有多少使用的地方,Hibernate作为最优秀
的O/R Mapping的架构,他的对象层次关系的处理和实现上确实是做的很有考究的,不过这个
功能在我们的项目中真正能够用到的又有多少叻,在我使用的项目中,我们最多也就用两层的
关系,而且就是两层的关系的使用中也是相当的慎重的,lazy loading和二级缓存的出现解决
了一部分我们的顾虑,但是的不足以消沉我们的完全疑问,你的性能真的能够和我们的直接写
的SQL来比较嘛,也许你会以二级缓存作为你回应的答案,但是我觉得这个是很回答是很脆弱的
,用好二级缓存是一个很深的问题,你需要根据你的项目的各个模块的使用方式和对象的市盈
率来给你的二级缓存提供一个配置依据,也许等你很花时间的分析出使用几率的问题后才发现
,哦,原来这个二级缓存配上也是没有用处的,比如说,我们的一个通用的search功能,这个
表的domain object涉及到两个或者是三个以上,这个需求在工业项目中是很常见的,毕竟那
种每次查询仅一个domain object的信息管理系统是工业应用中很少的,这时你需要怎么来配
置你的二级缓存才能到达比较好的性能了。也许你会说,如果是这样,如果是这样的应用,我
们可以直接在hql里写上我们domain object的关系就可以叻。如果仅是这样,我们可以看到,
这个和写我们的sql有什么差异叻,出来语法有不同而已,既然是这样,做同样一件事,我们去
要花更多的时间去学习一个新的语法,还要花更多的时间去研究二级缓存的策略叻。也许这时
候,你还会说,虽然我是做了多余的事情,但是我取出数据了可以不需要自己把他转变成对象
了,Hibernate已经帮我做了呀,如果是这样的话,我们仔细回到最开始说的问题,好像问题
又绕回来了,你究竟是为了使用Hibernate的时候功能,当你花了这么多的功夫,损失了很多
的功能性,易用性,最后却仅仅只是回到了Hibernate可以作个Mapping,把我们的结果集自动
转变成一个对象而已,如果仅是这个而已,那么我们的项目框架的选择是不是出现了错误叻。
这个自动转换成对象的功能是不是能过弥补我们损失的那么多了,result 2 object这样的动
作,一个稍微有些bean和rulstset编程知识的人,都可以自己写出通用的组件出来,有必要我
们如此这般的搭上这么多的损失么。所以,我们的在做价格评估的POC的时候,大胆的放弃了Hi
bernate,而使用Ibatis,
我们可以这样来介绍ibatis,Ibatis提供OR Mappng机制,面对业务层
开发的成员员而言,他们面对的是纯java对象,这一点是Ibatis和Hibernate极其相似,同时
,针对具体的数据库对象操作而言,ibatis是针对sql操作的,这样给面对数据库的持久层编
程人员而言,Ibatis可以操作强大的sql语句,Ibatis通过对sql的编程工作量和数据库移植性
上的让步,为系统的强大功能性提供了更大的空间。Ibatis在为了支持强大的功能性而选择了S
QL的处理,在O/R mapping的功能性上和SQL的支持做了均衡,这样,O/R Mapping上没有Hibe
rnate那么强大,但是是用SQL作为查询语句的,而大大提高了程序的功能性,同时直接支持pr
ocedure,支持动态语句,参数绑定,支持大对象,二级缓存,以及Spring的集成,所以从整
个和项目的结合度上,Ibatis更是贴近我们的开发,他是一个功能强大的DB持久层的包,和一
个O/R Mapping的包,这样我们在使用过程中对查询更能收发自如,同时在O/R Mapping中,我
们有可以很方便的把我们的object和SQL的参数得以绑定,或者是通过resultset方便的转换成
我们需要的Object。大家以前在做SQL和JDBC编程的时候,应该都有体会,直接用SQL功能强大
,但是参数的绑定比较痛苦,需要我们写一堆的setParameter的语句,其实有时所有的参数来
自于同一个对象,但是我们还必须不厌其烦的把每个都get到,然后在set到parameter里,在I
batis里不要我们在这样做痛苦的事情了。我们只需要做个简单的告诉我们的sql选择器我们的
paramter大对象的类型是什么,就可以了,接下来直接把对象传给他就可以,如此而已,同样
的对于resultset的结果集出来,ibatis如出一辙似的,通过resultClass或者是resultMap方
便的把result转变成一个object或者是一个object的List。给我们贴心的舒适。同样在性能方
面,Ibatis支持二级缓存,而且可以把针对这每个sql去配置二级缓存的策略,甚至可以直接
在我们sql的二级缓存策略里配置上,更新缓存的先决action,这样可以更好的把我们的持久
层的cache独立到持久层里,而在我们的业务层代码里不必加上cache何时更新的代码,在这点
上也是ibatis做的比hibernate更贴近项目使用的一个方面。不过由于ibatis是基于sql语句的
,而hibernate是基于hql,所以在数据库无依赖性这个方面,hibernate要强于mysql,不过
这点,我们可以通过我们的开发来弥补上这点,毕竟ibatis推荐所有的sql都是在xml里定义出
来的。还有一点ibatis的优越一点就是对动态语句的支持,ibatis在sql-mapping的配置中提
供了动态语句的支持,有兴趣的朋友可以参考,以上仅是个人在架构选型中对持久层架构Hiber
nate和Ibatis一些个人的体会,当然一百个读者,一百个莎士比亚,每个人的考虑点不同,项
目经验会有不同的体验了,用题头的话,能者见能,智者见智,在软件工程要相信,没有最好
的,最有最合适的,合适自己项目开发的,才是最好的。
===============================================================
Inthirties关注Oracle数据库 维护,优化,安全,备份,恢复,迁移,故障处理