java帝国之战
断电的威胁
强大的Java帝国自成立一来,一直顺风顺水,可是外人不知道的是,帝国也有个致命的弱点,那就是害怕一种叫做“断电”的攻击。
每次攻击来临,帝国辛辛苦苦制造出Java对象都会瞬间死亡,变成孤魂野鬼,在电脑里四处游荡,最终悄无声息地消失在空气中。
这是没有办法的事情,帝国生存所依仗的Java对象都必须在内存中才能工作,而内存最怕“断电” !
这件事情变成了国王的一件心病,茶不思饭不想。
某日朝会,国王又把这个难题抛给了下面战战兢兢的各位大臣。
线程大臣说: “大王,我们能不能跳过内存,直接使用硬盘来操作Java对象?”
IO大臣最近压力最大,已经好几天没合眼了:“不懂别瞎BB,你知道硬盘有多慢吗,比内存慢几万甚至10几万倍,用硬盘怎么干活?还有人类的冯诺依曼体系要求了,数据必须在内存中CPU才能操作。 ”
线程大臣脑洞打开:“要是发明一个硬盘,容量无限大,速度和CPU一样,那CPU不就直接操作硬盘了,还要内存干什么?!”
国王叹了口气: “别吵了,谁要是发明一个这样的硬盘,我会授予他100次Java帝国诺贝尔奖!你们知道人类的摩尔定律吗?集成电路上的晶体管每隔18个月便会增加一倍,性能也会提升一倍。可是这硬盘不行啊,就像手机上的电池一样,一直以来都像老牛拉破车,慢慢吞吞地在发展,这么多年都没有重大的突破。”
IO大臣说:“大王不用灰心,臣最近想出了一个办法,叫做序列化,可以把内存中那些重要的对象转化为二进制文件存储到硬盘上,这样就不怕断电了”
“等到电力恢复以后,还能再让他们回到内存吗?”
“那是自然,我们可以反序列化,把二进制文件变成Java对象,继续在内存中干活。”
国王大喜,颁布命令,要求臣民们都必须学会IO大臣发明的序列化。
数据库联合酋长国
序列化虽然解决了一部分问题,但是臣民们很快发现了它的弱点:效率低。
Java对象少的时候还行,如果需要大规模地对Java对象进行存储、查询的时候那几乎不能用。比如说想选取 age > 28的所有Person对象,那就得把所有序列化的Person对象都装入内存,一个个的比较年龄,这实在是太费劲了。
IO大臣这次也辙了,只好建议国王去国外考察,看看人家遇到这个问题是怎么解决的。
国王放下高傲的身段,派出了多个使团,分别出访了C++, Python, Ruby, C#...等王国。
一个月后,使团陆续返回,带回的消息惊人得一致:使用关系数据库存储大规模数据。
“关系数据库? ”国王听说过这个东西,在Java帝国东边的大海上,有一个叫做数据库的岛屿,那里有几个很大的部落,好像有什么Oracle, Db2, SQLServer ,MySql之类,他们组成了一个联合酋长国。
IO大臣说: “关系数据库就是用类似二维表格的方式来存储数据,臣听说他们从70年代末开始就开始发展,由于有强大的理论基础,像什么关系代数,关系演算,现在发展的非常成熟,可以进行大规模的数据存储和查询,还可以支持我们梦寐以求的事务操作呢。奥对了,他们搞出了一个叫SQL的东西,屏蔽了具体的实现细节和各个数据库之间的差异。”
线程大臣还在记恨IO大臣一个月前的讽刺,马上柔中带刚,皮笑肉不笑地甩出一个炸弹: “这个酋长国看起来挺好啊,只是IO大臣提到他们用二维表格的方式来存储数据,而我们这里是Java对象,好像不太匹配啊。”
国王上钩,向IO大臣发难: “一个是表格的行和列,一个是对象的属性,我们怎么把对象存储到表格中?”
IO大臣胸有成竹地说: “这需要我们的臣民自己写代码,把对象属性变成数据库的行/列,人家别的王国都是这么干的,这种办法还有一个很好听的名称叫Object-Relational Mapping,只是现在这种Mapping需要我们手工来做罢了,你要想大规模的查询和存储数据,总不能一点代价都不付出吧。 ”
国王说: "那就这么办吧, IO大臣,你去负责和数据库联合酋长国谈判,让他们和我们Java帝国协调一个接口出来,名称就叫......"
IO大臣马上接口: “Java Database Connectivity ,简称JDBC,如何?”
“好!就用这个名称,你去谈判一定要坚守住帝国的底线,那就是我们只负责定义接口,具体的JDBC实现必须由各个数据库去提供!你要是搞不定,就别回来见我。退朝!”
表面风光的EJB
半年以后,Java帝国和数据库联合酋长国就JDBC达成一致,双方签署了正式的协议,帝国的臣民们欢欣鼓舞,纷纷开始使用JDBC作为持久化的工具。
可是这JDBC的劣势也很明显:这是一个非常“低级”的接口, 程序员需要处理太多的细节,冗余代码太多,写个简单的查询就得一大堆代码伺候,打开connection,创建statement,执行sql,遍历resultset,还得记住关闭connection,要不然会资源泄露......
此时Java帝国正准备向企业级应用进军,需要支持安全,事务,分布式、可伸缩性,高可用性.....等高级功能,这些脏活累活操作系统不想做,应用程序也不想干,那到底扔给谁呢?
帝国一合计,提出了一个令人耳目一新的概念:中间件(middleware ) ,专门负责底层操作系统和上层应用程序都不愿意做的事情。
帝国充分发挥了制定标准的特长,搞了一套J2EE的规范出来,其中包罗万象,涵盖了大部分企业开发的需求,把通用的,复杂的服务交给中间件提供商去搞定,让开发人员集中在业务逻辑的开发上。
这其中有个标准就是EJB,帝国大肆宣传:只要使用了EJB,再也不用写那些烦人的JDBC代码了,数据的创建,读取,甚至查询都可以用面向对象的风格搞定。更牛的是这些EJB实例可以在一个集群上分布式运行。
在Websphere, Weblogic, Jboss等应用服务器的支持和鼓噪下,J2EE在初期热度非凡,帝国横扫企业级市场,别的王国只有看热闹的份。
Java帝国的臣民们享受着外界羡慕的目光,骄傲地使用EJB进行开发,然后扔到应用服务器中执行。
但是其中的辛苦和委屈只有自己知道:开发繁琐,难于测试,性能低下,除了表面的风光,已经剩不下什么了。
轻量级O/R Mapping框架
2001年,帝国有个叫Gavin King的,终于无法忍受金玉其外败絮其中的EJB,自己偷偷另起炉灶,搞了一个O/R Mapping的框架出来,名称很有意思,叫做Hibernate。
冬眠?好像到了冬天让内存的数据进入数据库冬眠,春天来了从冬眠中醒来,再次进入内存工作。
Gavin宣称使用Hibernate ,你可以把Java的属性用声明的方式映射到数据库表,完全不用你操心connection, sql这些细节。
帝国刚开始没在意,觉得这就是个玩具,哪能和强大的EJB相比?
好东西永远都不缺市场,一传十、十传百,Hibernate很快成了气候,使用简单、灵活,特别是脱离了那些庞大,昂贵的Websphere, weblogic容器也能使用。一下子捕获了很多臣民的心。
同年另外一个叫做iBatis的O/R Mapping框架也出现了,又拉走了一大批EJB臣民。
2004年 Rod Johnson给了EJB以致命一击,他写了一本《Expert One-on-OneJ2EE Development without EJB 》 ,公然宣扬不使用EJB,而要使用更加轻量级的框架,也就是他鼓捣出的Spring。
帝国宣称这是一本禁书,禁止出版发行。可是人的意志总是挡不住历史的潮流,抛弃重量级的EJB,使用更加轻量级的Spring成了大势所趋。
这个Spring不但自己提供了轻量级的访问数据库的方法JDBCTemplate,还能轻松的集成Hibernate, iBatis等一批工具。慢慢的竟然成为了事实的标准,在帝国流行开来。
终极之战