随着 Oracle, Sybase, SQL Server ,DB2,  Mysql 等人陆陆续续住进数据库村, 这里呈现出一片兴旺发达的景象, 无数的程序在村里忙忙碌碌, 读写数据库,   实际上一个村落已经容不下这么多人了, 数据库村变成了数据镇。

这一天, 数据库镇发生了一件大事: 它连上了网络!

外部的花花世界一下全部打开,  很多程序开始离开这个拥挤的城镇, 住到更加宜居的地方去。

可是他们的工作还是要读写数据库, 大家都在想办法能不能通过网络来访问数据库镇的数据库。

其中移居到Tomcat村的Java 最为活跃, 这小子先去拜访了一下Mysql ,    相对于Oracle, Sybase 等大佬, Mysql 还很弱小, 也许容易搞定。

Java 说: “Mysql 先生, 现在已经网络时代了, 您也得与时俱进啊, 给我们开放下网络接口吧。 ”

Mysql  说: “还网络时代, 你们这些家伙越来越懒了, 都不愿意到我们家里来了! 说说吧, 你想怎么开放?  ”

Java 说: “很简单, 您听说过TCP/IP还有Socket 没有?   没有吗?!  没关系, 您的操作系统肯定知道, 它内置实现了TCP/IP和socket,   您只需要和他商量一下, 需要申请一个ip , 确定一个端口, 然后您在这个端口监听,  我每次想访问数据了, 就会创建一个socket ,向你发起连接请求, 你接受了就行了。 ”

“这么麻烦啊?”

“其实也简单, 您的操作系统会帮忙的, 他非常熟悉,  再说只需要做一次就行, 把这个网络访问建立起来, 到时候很多程序都会来访问您, 您会发财的。 ”

“不会这么简单吧, 假设说, 我是说假设啊,  通过socket我们建立了连接, 通过这个连接, 你给我发送什么东西?  我又给你发什么东西?”  Mysql非常老练, 直击命门。

“呃, 这个....  ”

Java 其实心里其实非常明白, 这需要和Mysql定义一个应用层的协议, 就是所谓的你发什么请求, 我给你什么响应

例如:

客户端程序先给Mysql 打个招呼,  Mysql也回应一下, 俗称握手。

怎么做认证、授权, 数据加密, 数据包分组。

用什么格式发送查询语句,   用什么格式来发送结果。

如果结果集很大, 要一下子全发过来吗?

怎么做数据缓冲?

......

等等一系列让人头痛的问题。

本来Java是想独自定义, 这样自己也许能占点便宜, 没想到Mysql  直接提出来了。

“这样吧 ” Java 说 “我们先把这个应用层的协议定义下来, 然后您去找操作系统来搞定socket如何? ”

“这还差不多 ” 。 Mysql 同意了。

两人忙活了一星期, 才把这个应用层协议给定义好。

然后又忙了一星期, 才把Mysql 这里的socket搞定。

Java 赶紧回到Tomcat村,  做了一个实验:  通过socket和mysql 建立连接,  然后通过socket 发送约定好的应用层协议,    还真不错, 一次都调通了,   看来准备工作很重要啊。

(刘欣注: 这是我的杜撰, mysql 的网络访问早就有了, 并不是java 捷足先登搞出来的)

搞定了Mysql ,  Java 很得意, 这是一个很好的起点, 以后和Oracle, SQL Server, Db2等大佬谈判也有底气了。

尤其是和mysql 商量出的应用层协议,   mysql 也大度的公开了, 这样一来, 不管是什么语言写的程序,管你是java, pyhton, ruby , php......   只要能使用socket,   就可以遵照mysql 的应用层协议进行访问,  mysql 的顾客呈指数级增长, 财源滚滚。  尤其是一个叫PHP的家伙, 简直和mysql 成了死党。

Oracle, Db2那帮大佬一看, 立刻就红了眼, 不到Java 去谈判, 也迫不及待的定义了一套属于自己的应用层访问协议。

令人抓狂的是, 他们的网络访问协议和Msyql 的完全不一样 !  这就意味着之前写的针对mysql 的程序无法针对Oracle , Db2通用,  如果想切换数据库, 每个程序都得另起炉灶写一套代码!

更让人恶心的是, 每套代码都得处理非常多的协议细节,   每个使用Java进行数据库访问的程序都在喋喋不休的抱怨: 我就想通过网络给数据库发送SQL语句, 怎么搞的这么麻烦?

原因很简单, 就是直接使用socket编程, 太low 了 ,  必须得有一个抽象层屏蔽这些细节!

Java 开始苦苦思索, 做出一个好的抽象不是那么容易的。

首先得有一个叫连接(Connection)的东西, 用来代表和数据库的连接。

想执行SQL怎么办? 用一个Statement来 表示吧。   SQL返回的结果也得有个抽象的概念: ResultSet 。

他们之间的关系如图所示:

从Connection 可以创建Statement,    Statement 执行查询可以得到ResultSet。

ResultSet提供了对数据进行遍历的方法, 就是rs.next() , rs.getXXXX ....      完美!

对了, 无论是Connection, 还是Statement, ResultSet ,  他们都应该是接口,而不能是具体实现。

具体的实现需要由各个数据库或者第三方来提供, 毫无疑问, 具体的实现代码中就需要处理那些烦人的细节了!

Java 把这个东西叫做JDBC,  想着自己定义了一个标准接口, 把包袱都甩给你别人, 他非常得意。

第一个使用JDBC, 叫做学生信息管理的程序很快发现了问题,   跑来质问Java: “你这个Connection 接口设计的有问题!”

Java 说: “不可能, 我的设计多完善啊!”

“看来你这个规范的制定者没有真正使用啊,  你看看, 我想连接Mysql, 把Mysql 提供的jdbc实现(mysql-connector-java-4.1.jar )拿了过来,   建立一个Connection : ”

“这不是挺正常的吗? 你要连接Mysql , 肯定要提供ip地址, 端口号,数据库名啊” Java 问到。

“问题不在这里, 昨天我遇到mysql了, 他给了我一个号称性能更强劲的升级版mysql-connector-java-5.0.jar,  我升级以后, 发现我的代码编译都通不过了,  原来mysql 把MysqlConnectionImpl 这个类名改成了 MysqlConnectionJDBC4Impl  , 你看看, 你整天吹嘘着要面向接口编程, 不要面向实现编程, 但是你自己设计的东西都做不到啊”

Java觉得背上开始出汗,  那个程序说的没错,  设计上出了漏洞, 赶紧弥补吧。

既然不能直接去 new 一个Connection 的实现, 肯定要通过一个新的抽象层来做, 这个中间层叫做什么?

Java 想到了电脑上的驱动程序, 很多硬件没法直接使用, 除非安装了驱动。   那我也模拟一下再做一个抽象层吧: Driver

每个数据库都需要实现Driver 接口,   通过Driver 可以获得数据库连接Connection ,  但是这个Driver 怎么才能new 出来呢?  肯定不能直接new ,    Java似乎陷入了鸡生蛋、蛋生鸡的无限循环中了。

最后, 还是Java的反射机制救了他, 不要直接new 了,  每个数据库的Driver 都用一个文本字符串来表示, 运行时动态的去装载, 例如mysql 的Driver 是这样的:

Oracle是这样的:

只要这个Driver Class不改动, 其他具体的实现像Connection,  Statement, ResultSet想怎么改就怎么改。

接下来的问题是同一个程序可能访问不同的数据库, 可能有多个不同Driver 都被动态装载进来, 如何来管理?

那就搞一个DriverManager吧,  Mysql 的Driver, Oracle的Driver 在类初始化的时候, 一定得注册到DriverManager中来, 这样DriverManager才能管理啊:

注意: 关键点是static 的代码块, 在一个类被装载后就会执行。

DriverManager 可以提供一个getConnection的方法, 用于建立数据库Connection 。

DriverManager会把这些信息传递给每个Driver , 让每个Driver去创建Connection 。

慢着!  如果DriverManager  里既有MysqlDriver, 又有OracleDriver ,  这里到底该连接哪一个数据库呢?   难道让两个Driver 都尝试一下? 那样太费劲了吧, 还得区分开,没法子只好让那些程序在数据库连接url中来指定吧:

url中指明了这是一个什么数据库, 每个Driver 都需要判断下是不是属于自己支持的类型, 是的话就开始连接, 不是的话直接放弃。

(刘欣注: 每个Driver接口的实现类都需要实现一个acceptsURL(Sting url)方法, 判断这个url是不是自己能支持的。 )

唉,真是不容易啊, Java想, 这下整个体系就完备了吧, 为了获得一个Connection , 综合起来其实就这么几行代码:

无论是任何数据库, 只要正确实现了Driver, Connection 等接口, 就可以轻松的纳入到JDBC框架下了。

Java终于可以高兴的宣布: “JDBC正式诞生了!”

转自码农翻身微信公众号文章

JDBC的诞生

码农翻身——JDBC的诞生相关推荐

  1. 码农翻身全年文章精华

    在码农翻身公众号写了一年多, 最大的体会就是:原创真心不易! 每天思考的最大问题就是: 下一篇文章写啥? 在大家的支持和鼓励下,还是坚持了下来,  回头看看走过的路,这一年过得还算充实. 很快就要过年 ...

  2. 码农翻身 各章节链接

    大话编程 我是一个线程 我是一个Java class Javascript: 一个屌丝的逆袭 Java:一个帝国的诞生 JSP:一个装配工的没落 TCP/IP 之 大明王朝的邮差 TCP/IP 之 大 ...

  3. 码农翻身全年文章精华2016

    在码农翻身公众号写了一年多, 最大的体会就是:原创真心不易! 每天思考的最大问题就是: 下一篇文章写啥? 在大家的支持和鼓励下,还是坚持了下来,  回头看看走过的路,这一年过得还算充实. 很快就要过年 ...

  4. 《码农翻身》总结整理

    最近突然想把自己读过的一些书总结一下,做个记录.<码农翻身>是我毕业之后认真读过的第一本书,从此之后一发不可收拾,上网买了一堆博客大神推荐的书,读完之后也有自己的一些总结,后面会陆续补上. ...

  5. 告别2017,码农翻身全年文章精华

    时间过得真快,转眼间2017年就结束了! 感谢大家一年来的陪伴.支持和鼓励! 这里是2017年全年码农翻身文章精华, 点击标题阅读, 欢迎转发分享. 如果觉得不过瘾的话,一定要逛逛<码农翻身20 ...

  6. 码农翻身讲网络5:从Web安全到HTTPS

    浏览器:一个家族的奋斗 浏览器家族的安全反击战 黑客三兄弟 黑客三兄弟(续) 一个故事讲完https 深入浅出HTTPS工作原理 原创: 刘欣 码农翻身 2017-12-12 我是你们每天都要使用的浏 ...

  7. 码农翻身讲计算机基础:补码,程序编译与递归

    从1加到100:一道简单的数学题挑战下你的大脑 原创: 刘欣 码农翻身 2017-01-03 2017年的第一篇, 写给刚刚踏入计算机编程领域的小白吧. 所谓编程,就是把自然语言的需求翻译成计算机语言 ...

  8. 码农翻身——Java帝国之动态代理

    已经快三更天了, Java帝国的国王还在看着IO大臣的奏章发呆,他有点想不明白, 帝国已经给臣民了提供了这么多的东西,他们为什么还不满意呢? 集合.IO.反射.网络.线程.泛型.JDBC ...... ...

  9. 码农翻身之——分布式,集群,负载均衡

    分布式:将不同的业务分布在不同的地方,这就构成了一个分布式的系统.(如下图所示) 假设由三个系统A.B.C构成的一个分布式系统(A作为主系统),那么会存在如下的问题--系统A是这个分布式系统的&quo ...

最新文章

  1. Udacity机器人软件工程师课程笔记(三)-样本搜索和找回-基于漫游者号模拟器-使用moviepy输出测试视频
  2. python使用matplotlib可视化、移除可视化图像X轴坐标轴的刻度线和标签( remove the default axis ticks and labels of x axis)
  3. 平安技术开放日质量保证技术专场第一期 [附部分 ppt]
  4. Tesseract使用日记
  5. java网络编程之Socket编程
  6. python变量标识符_简谈-Python的注释、变量类型、标识符及关键字
  7. openssl 对文本加密解密
  8. Android平台SQLite快速入门“.NET研究”实践
  9. BZOJ 10628 Luogu 2633
  10. [教程]Web自动化测试怎么做?Web网页测试全流程解析
  11. 项目管理知识体系(PMBOK)
  12. itextsharp 获取文本_使用itextsharp从签名图像中获取Layer2文本(签名描述)
  13. [1151]python连接 redis cluster集群
  14. 《计算机网络》学习总结——数据链路层(完整理解)
  15. 聚类生成anchor框的尺寸和比例
  16. 查看树莓派I2C设备是否正常
  17. windows使用scp远程传输文件的方法
  18. SQL基础知识整理—数据库相关基本概念
  19. Linux安装jdk,mysql,tomcat,redis和nginx
  20. 配置路由协议rip和ospf

热门文章

  1. 汉字怎么转换成十六进制
  2. VisualSVN Server使用手册
  3. 常用坐标系及坐标系之间的变换
  4. 在Twig模板中获取 request参数
  5. OTB数据集中的标签含义及对应的视频序列
  6. 【演示文稿制作动画】Focusky教程 | 图表美化技巧
  7. STM32F429入门(十八):DMA
  8. Scrap Shell -笔记
  9. JS 中常用判断为空的方法
  10. jass——group的使用