连接, 连接, 总是连接!

生活中肯定有比数据库连接更有趣的事情。

1

数据库连接

又到了数据库连接的时间!

那些码农把数据库参数送过来,  Oracle , Db2,  Sybase, SQL Server这些JDBC Driver 懒洋洋起来去干活赚钱。

小东也是其中之一,  每天的工作就是连接Mysql 数据库, 发出SQL查询, 获取结果集。

工作稳定, 收入不菲, 只是日复一日,年复一年, 枯燥的工作实在是太令人厌烦了。

有时候小东会和其他JDBC Driver 聊天, 谈起有些不着调的码农, 创建一个Connection,  发出一个查询, 处理完ResultSet后 , 立刻就把Connection给关掉了。

“他们简直不知道我们建立一个数据连接有多么辛苦, 先通过Socket 建立TCP连接, 然后还要有应用层的握手协议, 唉, 不知道要干多少脏活累活, 这帮码农用完就关, 真是浪费啊。 ”

“还有更可气的, 有些家伙使用了PreparedStatement , 我通知数据库做了预编译, 制定了查询计划, 为此我还花费了不菲的小费。   但是只执行了一次查询, Connection就关掉了, PreparedStatement 也就不可用了, 现在数据库都懒的给我做预编译了 !”

“你们这都是好的, 有些极品根本就不关闭Connection,  最后让这个Connection 进入了不可控状态。 ”

“我们啊, 都把宝贵的生命都献给了数据库连接事业...... ”

抱怨归抱怨, 大部分人都安于现状,逆来顺受了。

2

向Tomcat取经

但是不安分的小东决心改变, 他四处拜访取经,  但是一无所获。

这一天在Tomcat村遇到了Tomcat 村长,  看到了村长处理Http请求的方式, 突然间看到了曙光。

村长说: 我们本来是一个线程处理一个Http请求  ,  一个Http请求来到我们这里以后,  我并不会新建一个线程来处理,  而是从一个小黑屋叫来一个线程直接干活, 干完活以后再回到小黑屋待着。

小东问: 小黑屋是什么?

(码农翻身注: 参见文章《我是一个线程》)

村长说: “学名是线程池, 为了充分利用资源, 我在启动时就建立了一批线程, 放到线程池里, 需要线程时直接去取就可以了。   ”

“那要是线程池里的线程都被派出去了怎么办 ? ”

"要么新创建线程, 要么新来的Http请求就要等待了。  实际上,线程也不是无限可用的资源, 也得复用。"

小东心想, 我们JDBC也可以这么搞啊, 把数据库连接给缓存下来, 随用随取, 一来正好可以控制码农们无限制的连接数据库; 二来可以减少数据库连接时间;  第三还可以复用Connection上的PreparedStatement, 不用老是找数据库预编译了。

3

数据库连接池

建立数据库连接池不是那么一帆风顺的, 小东的第一次尝试是创建了一个ConnectionPool这个接口:

里边有两个重要的方法, getConnection(), 用于从池中取出一个让用户使用;

releaseConnection() 把数据库连接放回池中去。

小东想, 只要我写一个ConnectionPool的实现类, 里边可以维护一个管理数据库连接的数据结构就行了, 码农们用起来也很方便, 他们肯定会喜欢的。

可是事与愿违, 几乎没有人用这样的接口。

小东经过多方打探才明白, 码农们要么是用DriverManager来获得Connection, 要么是使用DataSource来得到Connection;关闭的时候,只需要调用Connection.close() 就可以了。

这样的代码已经有很多了, 而小东的新方案相当于新的接口, 需要改代码才能用,  话说回来, 谁愿意没事改代码玩?  尤其是正在运行的系统。

再做一次改进吧, 小东 去找Java 这个设计高手求教。

Java 说:“虽然ConnectionPool概念不错, 但是具体的实现最好隐藏起来, 对码农来说,还是通过DataSource 来获取Connection,   至于这个Connection 是新建的还是从连接池中来的, 码农不应该关心, 所以应该加一个代理Proxy,把物理的Connection给封装起来,  然后把这个Proxy返回给码农。”

“那这个Proxy是不是得和您定义的接口Connection 接口保持一致?   要不然码农还得面对新东西。”

“是的, 这个Proxy 应该也实现JDBC的Connection 接口, 像这样: ”

(点击看大图)

小东说: ”奥, 我明白了, 当码农从DataSource中获得Connection的时候, 我返回的其实是一个ConnectionProxy ,   其中封装了一个从ConnectionPool来的Connection ,  然后把各种调用转发到这个实际的physicalConn的方法去,  关键点在close,  并不会真的关闭Connection, 而是放回到ConnectionPool “

“哈哈, 看来你已经get了,  这就是面向接口编程的好处啊, 你给码农返回了一个ConnectionProxy, 但是码农们一无所知, 仍然以为是在使用Connection , 这是一次成功的‘欺骗’啊”

“但是你定义的Connection 接口中的方法实在是太多了, 足足有50多个, 我这个Proxy类实际上只关注那么几个, 例如close方法, 其他的都是转发而已,这么多无聊的转发代码是在是太烦人了”

Java说: “还有一种办法,可以用动态代理啊”

小东问:“什么是动态代理?”

"刚才我们提供的那个Proxy可以称为静态代理,   我的动态代理不用你写一个类去实现Connection, 完全可以在运行期来做, 还是先来看代码吧"

(点击看大图)

“代码有点难懂,   你看,这里没有声明一个实际的类来实现Connection 接口 , 而是用动态代理在运行时创建了一个类Proxy.newProxyInstance(....) ,    重点部分就是InvocationHandler,  在他的invoke方法中, 我们判断下被调用的方法是不是close, 如果是, 就把Connection 放回连接池, 如果不是,就调用实际Connection的方法。”  Java 解释了一通。

小东惊叹到:“代码虽然难懂, 但是精简了好多,我对Java 反射不太熟, 回头我再仔细研究下。”

(码农翻身注: 不熟悉Java动态代理的也可以研究下, 这是一项重要的技术)

经过一番折腾, 数据库连接池终于隐藏起来了, 码农们可以使用原有的方式去获取Connection, 只是不知道背后其实发生了巨变。

当然也不可能让码农完全意识不到连接池, 毕竟他们还得去设置一些参数, 小东定义了一些:

数据库连接池获得了巨大的成功, 几乎成了每一个Java Web项目的标配,  不一样的JDBC驱动小东也获得了极高的荣誉, 后面等着他的还会有哪些挑战呢?

(完)

码农翻身相关历史文章推荐:



Java EE

我是一个线程

我是一个Java class

Java:一个帝国的诞生

JDBC诞生记

JSP:一个装配工的没落

Javascript: 一个屌丝的逆袭

Spring本质系列(1) -- 依赖注入

Spring本质系列(2) -- AOP

Http 历险记(上)

Http 历险记(下)—Struts的秘密

三层架构和MVC那点事儿

Java帝国之 Java Bean(上)

Java帝国之 Java Bean(下)

计算机网络

我是一个路由器

我是一个网卡

TCP/IP之大明邮差

TCP/IP之大明内阁

TCP/IP之蓟辽督师

张大胖的socket

IE为什么把Chrome和火狐打伤了?

对浏览器村的第二次采访

节约标兵IE的自述

EMail诞生记

EMail诞生记(下)

数据库

小李的数据库之旅(上)

小李的数据库之旅(下)

张大胖学数据库

数据库村的旺财和小王

你看到的只是冰山一角, 更多精彩文章,尽在“码农翻身” 微信公众号, 回复消息"m"或"目录" 查看更多文章

有心得想和大家分享? 欢迎投稿 ! 我的联系方式:微信:liuxinlehan  QQ: 3340792577

公众号:码农翻身

“码农翻身”公众号由工作15年的前IBM架构师创建,分享编程和职场的经验教训。

一个不安分的JDBC驱动相关推荐

  1. 【oracle】oracle jdbc驱动与c3p0的一个兼容问题

    环境 oracle 12c 12.1.0.1 oracle jdbc7 12.1.0.1 c3p0 0.9.1.1 tomcat 7.0.55 jdk 1.7 问题 java.lang.Runtime ...

  2. jdbc驱动_JDBC概述和CRUD

    第八章 JDBC的简介 8.1 简介 JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问 ...

  3. 解决maven官方库中没有oracle jdbc驱动问题 编辑

    2019独角兽企业重金招聘Python工程师标准>>> 刚研究maven不久,遇到一个比较头疼的问题,在工程里怎么下都下载不了oracle的jdbc驱动. 刚还以为是网络问题,重新下 ...

  4. Ubuntu下eclipse部署mysql jdbc驱动

    1.mysql jdbc驱动包下载地址:http://dev.mysql.com/downloads/connector/j/ 版本:mysql-connector-java-5.1.17.zip 2 ...

  5. jsp mysql驱动程序_JSP通过JDBC驱动MySQL数据库方法

    JSP通过JDBC驱动MySQL数据库方法 发布时间:2020-03-26 15:42 百度谷歌一翻后,发现jsp要连mysql数据库的话,有这样的一种方法:使用jsp通过JDBC驱动链接MySQL数 ...

  6. jdbc驱动jar_Javagt; 连接数据库时,JDBC和Mybatis的区别

    搭建好了Java的Springboot架构后,如果需要连接数据库,我们应该怎么处理呢? 举个例子,我们在做线上监控时,需要从数据库中将接口运行的结果拿出来,处理好数据后显示给前端.怎么从数据库中将数据 ...

  7. db2 jdbc驱动参数_JDBC详细整理(一)

    一.什么是JDBC JDBC(Java DataBase Connectivity)就是Java数据库连接,说白了就是用Java语言来操作数据库.原来我们操作数据库是在控制台使用SQL语句来操作数据库 ...

  8. jdbc版本低MySQL版本高_Mysql JDBC驱动版本与Mysql版本的对应问题解决

    好长时间不用Mysql了, 昨天朋友有一个小项目在我的机器上跑的一点问题都没有, 到他的机器上却是报服务器内部错误(500), 用QQ上远程协助(太慢 好长时间不用Mysql了, 昨天朋友有一个小项目 ...

  9. java通过JDBC驱动连接操作hive实例

    Hive提供了jdbc驱动,使得我们可以用java代码来连接Hive并进行一些类关系型数据库的sql语句查询等操作.首先,我们必须将Hive的服务,也就是HiveServe打开.在Hive 0.11. ...

最新文章

  1. 错误3 error C3859: 超过了 PCH 的虚拟内存范围;请使用“-Zm120”
  2. 数据呈现 | 20大数据可视化工具测评
  3. github使用教程及小问题
  4. java安全技术-Base64编码与解码
  5. java哪个软件编程好学吗_java好学吗?java是不是最难学的语言?
  6. @SpringBootTest注解进行单元测试无法运行
  7. JS向后台传递json数组对象
  8. 拦截器---SpringMVC(权限拦截)
  9. 远程执行漏洞修复方案_请马上修复!SaltStack远程命令执行漏洞
  10. 图结构练习——判断给定图是否存在合法拓扑序列
  11. 最短路(HDU-2544)
  12. mysql5.4升级5.6_如何在CentOS上升级php5.4至5.6?
  13. mysql_connect和mysql_pconnect区别
  14. numpy 索引多个_Numpy基础三,学习Python编程必备
  15. STM32F103单片机RTC实时时钟的使用
  16. JavaThread学习
  17. 【转】golang 结构体和方法
  18. html5中心旋转动画效果图,HTML5 Canvas旋转动画的2个代码例子(一个旋转的太极图效果)...
  19. python ttk_tkinter进阶版——ttk
  20. html中颜色打字机效果,基于Css3和JQuery实现打字机效果

热门文章

  1. 图片上传 axios
  2. 戴尔科技集团为您提供寻觅已久的存储可见性!
  3. 与某流氓网站的血泪交战史
  4. 好记性不如烂笔头——C++篇
  5. (二)FirePower-FTD初始化设置并加入到FMC管理
  6. SpringBoot导出pdf文件学习
  7. 世界上五个最不务正业的科学家!看完三观都碎了…
  8. 人生启示录效应篇之破窗效应:及时矫正和补救正在发生的问题
  9. Adblock Plus使用教程
  10. 为什么成立计算机维修社团,张家口煤矿机械制造高级技工学校学生计算机维修社团成立...