返回介绍

持久化:Java 帝国反击战

发布于 2025-02-16 11:28:23 字数 5046 浏览 0 评论 0 收藏 0

1 断电的威胁

强大的 Java 帝国自成立一来, 一直顺风顺水, 可是外人不知道的是,帝国也有个致命的弱点, 那就是害怕一种叫做“断电”的攻击。

每次攻击来临, 帝国辛辛苦苦制造出 Java 对象都会瞬间死亡, 变成孤魂野鬼,在电脑里四处游荡,最终悄无声息地消失在空气中。

这是没有办法的事情, 帝国生存所依仗的 Java 对象都必须在内存中才能工作, 而内存最怕“断电” !

这件事情变成了国王的一件心病,茶不思饭不想。

某日朝会, 国王又把这个难题抛给了下面战战兢兢的各位大臣。

线程大臣说: “大王, 我们能不能跳过内存,直接使用硬盘来操作 Java 对象?”

IO 大臣最近压力最大,已经好几天没合眼了:“不懂别瞎 BB,你知道硬盘有多慢吗,比内存慢几万甚至 10 几万倍, 用硬盘怎么干活?还有人类的冯诺依曼体系要求了,数据必须在内存中 CPU 才能操作。 ”

线程大臣脑洞打开:“要是发明一个硬盘,容量无限大,速度和 CPU 一样,那 CPU 不就直接操作硬盘了,还要内存干什么?!”

国王叹了口气: “别吵了,谁要是发明一个这样的硬盘,我会授予他 100 次 Java 帝国诺贝尔奖! 你们知道人类的摩尔定律吗?集成电路上的晶体管每隔 18 个月便会增加一倍, 性能也会提升一倍。可是这硬盘不行啊, 就像手机上的电池一样,一直以来都像老牛拉破车,慢慢吞吞地在发展,这么多年都没有重大的突破。”

IO 大臣说:“ 大王不用灰心, 臣最近想出了一个办法,叫做序列化, 可以把内存中那些重要的对象转化为二进制文件存储到硬盘上,这样就不怕断电了”

“等到电力恢复以后,还能再让他们回到内存吗?”

“那是自然, 我们可以反序列化,把二进制文件变成 Java 对象,继续在内存中干活。”

国王大喜,颁布命令,要求臣民们都必须学会 IO 大臣发明的序列化。

2 数据库联合酋长国

序列化虽然解决了一部分问题, 但是臣民们很快发现了它的弱点: 效率低。

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 实现必须由各个数据库去提供! 你要是搞不定,就别回来见我。 退朝!”

3 表面风光的 EJB

半年以后,Java 帝国和数据库联合酋长国就 JDBC 达成一致,双方签署了正式的协议, 帝国的臣民们欢欣鼓舞, 纷纷开始使用 JDBC 作为持久化的工具。

可是这 JDBC 的劣势也很明显: 这是一个非常“低级”的接口, 程序员需要处理太多的细节, 冗余代码太多,写个简单的查询就得一大堆代码伺候,打开 connection,创建 statement, 执行 sql, 遍历 resultset, 还得记住关闭 connection,要不然会资源泄露......

此时 Java 帝国正准备向企业级应用进军, 需要支持安全,事务,分布式、可伸缩性,高可用性.....等高级功能, 这些脏活累活操作系统不想做, 应用程序也不想干,那到底扔给谁呢?

帝国一合计,提出了一个令人耳目一新的概念: 中间件(middleware ) , 专门负责底层操作系统和上层应用程序都不愿意做的事情。

帝国充分发挥了制定标准的特长, 搞了一套 J2EE 的规范出来,其中包罗万象,涵盖了大部分企业开发的需求, 把通用的,复杂的服务交给中间件提供商去搞定, 让开发人员集中在业务逻辑的开发上。

这其中有个标准就是 EJB, 帝国大肆宣传: 只要使用了 EJB, 再也不用写那些烦人的 JDBC 代码了,数据的创建,读取,甚至查询都可以用面向对象的风格搞定。 更牛的是这些 EJB 实例可以在一个集群上分布式运行。

在 Websphere, Weblogic, Jboss 等应用服务器的支持和鼓噪下,J2EE 在初期热度非凡, 帝国横扫企业级市场,别的王国只有看热闹的份。

Java 帝国的臣民们享受着外界羡慕的目光,骄傲地使用 EJB 进行开发,然后扔到应用服务器中执行。

但是其中的辛苦和委屈只有自己知道: 开发繁琐,难于测试,性能低下,除了表面的风光,已经剩不下什么了。

4 轻量级 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-One J2EE Development without EJB 》 , 公然宣扬不使用 EJB, 而要使用更加轻量级的框架,也就是他鼓捣出的 Spring。

帝国宣称这是一本禁书,禁止出版发行。可是人的意志总是挡不住历史的潮流, 抛弃重量级的 EJB, 使用更加轻量级的 Spring 成了大势所趋。

这个 Spring 不但自己提供了轻量级的访问数据库的方法 JDBCTemplate, 还能轻松的集成 Hibernate, iBatis 等一批工具。慢慢的竟然成为了事实的标准, 在帝国流行开来。

5 帝国的反击

在一次早朝上 IO 大臣简直是气急败坏了:“陛下,再不禁止 Spring ,Hibernate ,iBatis 的使用, 我们的 EJB 就要被抛弃了。”

国王说: “你禁止得了吗,上次你禁止 Rod 的那本书,民间的小抄还不是疯狂流行? 最近的起义风起云涌,按下葫芦浮起瓢,扑灭了这个,那个又起来了。倒不如任他们去,毕竟也大大地繁荣了我们 Java 帝国啊”

线程大臣立刻拍马屁: “陛下的心胸真是如同大海般广阔,不过臣倒有一计, 既然官方 EJB 标准抵不过 Hibernate 的事实标准, 我们要不就把 Gavin King 招安了算了,为我所用。”

国王表示赞同,命令线程大臣负责招安以及后续工作。

Gavin 之前已经加入 JBoss 部落,现在代表 JBoss 正式进入 JCP,也算是被招安了。 他早就有改造官方标准的雄心壮志, 带领着帝国的 EJB 团队推出了 EJB3.0 , 成功地向 Hibernate 看齐, 其中有些注解简直一模一样,极大的简化了开发。 各大厂商重新开始摇旗呐喊,为 EJB3.0 站台背书。

只是这个 EJB3.0 有个致命缺陷: 没法离开容器(Websphere, weblogic ,JBoss 等)运行, 臣民们已经适应了轻量级开发, 已经抛弃了重量级的应用服务器,在 Spring 的带领下,他们再也不需要一个容器来运行 EJB 了, 帝国的这次声势浩大的反击战被化于无形。

不过在 EJB3.0 中悄悄埋下了一个副产品,叫做 Java Persistence API(JPA), 充分地反应了帝国的小算盘, 既然我在实现层面无法打败你们,那我就制定我最擅长的标准, 用标准整合 O/R Mapping, 一统天下,唯我独尊!

在帝国的力推之下, Hibernate , EclipseLink ,OpenJPA 等知名产品都提供了针对 JPA 的实现, 可是帝国的官员们悲哀地发现: 现在臣民们又爱上了写 SQL 语句的 MyBatis, 唉,这民意真是难以琢磨啊。

国王最终决定改换策略,无为而治,放下官方的架子,只要是有利于帝国的,不再阻碍, 任其发展,趁机招安。

帝国反击战就此落幕,持久化工具之战以民间的最终胜利告终。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文