很早就应该为IBATIS写点什么,但总疲于工作或者说疲于懒惰,最终未能留下点什么,今日决定写点什么主要出于前一阵子工作的需求--非数据为中心的后台系统的数据库数据持久化;同时,也觉得长年累月的工作之余应该留点什么,不能总都存在大脑之中,久而久之束之高阁(比如STRUTS1.x)。
IBATIS是半自动化的ORM实现,在数据库持久化实现方面独占一席,它的优劣常被比较与面向对象思想的数据库ORM实现HIBERNATE,如今又已推出IBATIS3,完全不兼容IBATIS2,说到此可能有人觉得IBAITS2的时代已经过去了,没有必要再为她写什么了。正因我并非如此认为,再加上近日工作上的一些感触,觉得非常有必要为IBATIS2写点什么(当然也包括SPRING2、HIBERNATE3、EJB3),一方面作为工作总结,一方面弥补未能雁过留声之憾。
技术发展之快,变化之速,为作技术的主人,多多少少总要知道她的来龙去脉,她的本质所在。
IBATIS是半自动化的ORM实现,她的核心在于SQL MAP而非面向对象,借助于使用SQL Map的方式完成对数据库的操作,具备极强的灵活性和可控性,动态SQL也是IBATIS的一大亮点。而如此已推出IBATIS3,完全不兼容与IBATIS2,她的变化点大致在于:基础结构重新设计更倾向于HIBERNATE实现模式、动态SQL更加简化趋向于OGNL表达形式、引入JAVA5 ANNOTATION注解编程以及一个小的细节paramterClass&resultClass均被改为parameterType&resultType等。因此,我们不要指望IBATIS2、3的兼容性。但这并不代表IBATIS2已过时,为什么这么说呢?其一,依旧是SQL MAP方式的半自动化ORM,尽管IBATS3引入了更精简的动态SQL以及Java 5的注释;其二,结构变化但核心功能点依旧不变,尽管存在不兼容性;其三,IBATIS3尚未得到SPRING的支持;其四,遗留系统甚多。也就是说,IBATIS3所能完成的任务,IBATIS2也能。因此,自02年起生存长达八年之久的IBATIS2依旧具备极强的生命力。
说到这里,我不得不提及一下Java5提供的注释功能。曾几何时,人们谩骂硬编码,崇尚配置,配置方式之风肆行。而今,回头观望Java 5的注释功能,却正好走了曾被谩骂的硬编码之道,但也得之宠幸。这是为什么呢?Google推出了好多开源,我记得在GWT这个项目的一些文档中曾这样提及“(大意是)若把配置写在XML配置文件里,当我们需要修改时,除了修改类之外还要修改相应的XML配置文件,顾此失彼时很容易造成两者不一致,为了解决此问题,我们直接将其编码在代码中”,你明白了吗?这就是技术,这就是炒作。当初人们谩骂硬编码,大兴配置文件,而今人们又反其道而行之,指责配置文件存在顾此失彼导致不一致,大兴硬编码。孰是孰非,因“情”而看。正所谓好钢用到刃上,两者都有可取之处,只是要看我们的刀刃在何处!比如为了降低Struts2配置,增强开发者透明度,采用预定规则式的硬编码便是很好的选择;比如为了实现国际化,采用配置文件是俱佳解决方案。而对于Java 5的注解,个人认为,不应该大兴其道与IBATIS、HIBERNATE、EJB等这里数据库持久化之中,因为这不是她们的“刃”,她们的“刃”在于集中控制;Java 5的注解俱佳去处应该类似于JUnit、TestNG这样的场景,无需集中控制&一次性应用,利用注解代替配置。因此,个人推荐配置而非注解方式在各类ORM框架使用中,一家之言,仅供参考。
IBATIS与HIBERNATE的比较也是争执已久,各执一词,终无定论,网上一篇较为全面的ibatis VS hibernate 经典论述和ibatis和hibernate的比较!核心焦点集中在:门槛的高低(IBATIS低&HIBERNATE高)、面向对象思想如何(IBATIS差&HIBERNATE强)、开发效率高低(IBATIS低&HIBERNATE高,但借助于iBator也完全可媲美)、灵活性与可控性(IBATIS高&HIBERNATE低)以及运行效率等(查询可能缓存效果俱佳,但实时性高的非批量insert&update,效率方面依旧是jdbc>jdbcTemplate>iBatis>hibernate--之前的测试)。至于如何选择,也要因“情”而定。不能因为过度崇尚HIBERNATE面向对象、是SQL“盲”的福音,就人云亦云HIBNERNATE,也不能因为IBATIS简单、灵活,忘了HIBERNATE的好,挑了软柿子!关于这个问题,IBATIS的作者也有自己的看法:“If you are starting a new project and you're in full control of your object model and database design, Hibernate is a good choice of O/R tool. If you are accessing any 3rd party databases (e.g. vendor supplied), or you're working with a legacy database, or even just a really poorly designed database, then an O/R mapper might not be capable of handling the situation. That's were an SQL Mapper comes in handy”,故此,除非绝对同一平面方可论处高低,否则,这种争执注定是永无休止的。一句话,争执帮助我们认识事物,解决争执的唯一方法依旧是因“情”而定。
这里我们来粗略看下IBATIS略胜于HIBERNATE的“情”。
1、以数据为中心的系统(多为WEB项目),以下情况:
1.1 遗留系统。多少类似于1.2--表结构不可控性。
1.2 不公开表结构或表结构不可控。系统的部分或全部数据来自现有数据库,处于安全考虑,只对开发团队提供几条Select SQL(或存储过程)以获取所需数据,具体的表结构不予公开。抑或该WEB项目的表取决于已有后台项目建立的,WEB项目开发人员无权掌控表的设计(比如电信的WEB支持系统)。
1.3 系统数据处理量巨大,性能要求极为苛刻。这往往意味着我们必须通过经过高度优化的SQL语句(或存储过程)才能达到系统性能设计指标。
2、非以数据为中心的系统(多为后台项目)
这是促使我开始写此篇博文的重点。相对于WEB的Java后台项目,能否借用J2EE的持久层以及如何设计相应的DAO,这本身就是一个难点。一般来说,后台项目注重性能、注重灵活性、可控性,再者是表结构基本无多余的id字段仅供HiBERNATE使用或者说提供DAO的设计开发人员不能强制后台设计应用者预留HIBERNATE使用的id字段(除非你是项目的整体规划者&设计者,毕竟后台项目关注的是业务表,仅向你要表的DAO操作,不会考虑你的DAO所需的额外字段,关於这点,至少在电信是成立的)!按照“二-八”原则,IBATIS是俱佳选择!那么,作为J2EE 持久层技术应用与非以数据为中心的后台项目是否要考虑采用SPRING,以及如何屏蔽非DAO层开发人员调用DAO感觉不到SPRING的存在,并为SERVICE层提供灵活的事务控制方法,这些都是一个个尝试!
IBATIS2栏目将介绍如何采用IBATIS2&SPRING2的J2EE 持久层技术满足非以数据为中心的后台项目DAO层的实现与灵活的单事务控制,并将陆续简单介绍IBATIS2的使用,升级改造,使新手也可从容使用IBATIS2,在任务可满足性上无任何后顾之忧。当然,也将在HIBERNATE3、EJB3及SPRING2栏目分别陆续介绍她们的核心内容,争取做到雁过拔毛,以弥Struts1.x不曾留下任何脚印之憾(尽管目前依旧维护者一个Struts1.x的遗留系统)!