在JDK1.0刚开始发布时,并没有跟着发布一个连接数据库的API,那么那时的开发人员,如果想要连接到数据库的话,该怎么做呢?那时的通常做法是使用另一个数据库驱动管理器——ODBC。
ODBC(Open Database Connectivity,开放数据库互连)提供了一种标准的API(应用程序编程接口)方法来访问数据库管理系统(DBMS)。这些API利用SQL来完成其大部分任务。ODBC本身也提供了对SQL语言的支持,用户可以直接将SQL语句送给ODBC。ODBC的设计者们努力使它具有最大的独立性和开放性:与具体的编程语言无关,与具体的数据库系统无关,与具体的操作系统无关。(https://zh.wikipedia.org/wiki/ODBC)
在此再之前,如果要开发数据库应用程序,则必须要使用数据库厂商随数据库产品一同发布的一些工具集来访问数据库,或者在程序中使用嵌入式SQL来访问数据库,缺乏一个统一的编程接口。
ODBC的结构包括四个主要部分:应用程序接口、驱动器管理器、数据库驱动器和数据源。
应用程序接口:屏蔽不同的ODBC数据库驱动器之间函数调用的差别,为用户提供统一的SQL编程接口。
驱动器管理器:为应用程序装载数据库驱动器。
数据库驱动器:实现ODBC的函数调用,提供对特定数据源的SQL请求。如果需要,数据库驱动器将修改应用程序的请求,使得请求符合相关的DBMS所支持的文法。
数据源:由用户想要存取的数据以及与它相关的操作系统、DBMS和用于访问DBMS的网络平台组成。
当应用系统发出调用与数据源进行连接时,数据库驱动器能管理通信协议。当建立起与数据源的连接时,数据库驱动器便能处理应用系统向DBMS发出的请求,对分析或发自数据源的设计进行必要的翻译,并将结果返回给应用系统。
虽然使用ODBC的确是让Java开发人员也可以在应用中连接上数据库了,但由于ODBC毕竟并非是为Java而准备的,ODBC自身是使用C语言开发,标准接口也是对于C语言而言。因此那时的Java开发人员如果需要使用ODBC则不得不在Java程序中添加C语言的ODBC函数调用,使得许多Java自身的特性无法充分发挥,比如平台无关性、面向对象特性等。
因此在众多开发人员的强烈需求下,JDBC 1.0 随JDK1.1发布了。
JDBC 1.0 随JDK1.1一起发布,JDBC操作相关的接口和类位于java.sql包中。包含了DriverManager类,Driver接口,Connection接口,Statement接口,ResultSet接口,SQLException 类等。
JDBC 2.0 API被划分为两部分:核心API和扩展API。
核心API(java.sql包)
概括的来说,JDBC核心API的新特性在两个方面做了工作。一个是支持一些新的功能,另一个就是支持新的SQL的数据类型。
1、 在支持新功能方面:包括结果集可以向后滚动,批量的更新数据。另外,还提供了UNICODE字符集的字符流操作。
2、 在支持SQL的数据类型方面:新增加的BLOB, CLOB,和数组接口能够是应用程序操作大块的数据类型。
扩展API(javax.sql包)
1、DataSource接口:和Java名字目录服务(JNDI)一起工作的数据源接口。
2、 Connection pooling(连接池):可以重复使用连接,而不是对每个请求都使用一个新的连接。
如果DataSource对象实现与一个支持连接池的中间层的服务器一起工作,DataSource对象就会自动的返回连接池中的连接,这个连接也是可以重复利用的。
3、 Distrubute Transaction(分布式的事务):在一个事务中涉及到了多个数据库服务器。
4、 Rowsets:扩展了ResultSet接口,在ResultSet的基础上,可以对其进行滚动和更新,使其与数据库的耦合减小了。
总结
JDBC2.0标准扩展API通过见DataSource注册到JNDI名字服务上,将JDBC技术扩展为一个全新的概念。使应用程序的代码更加精巧,易于控制。新的API支持了连接池,支持分布式的事务。最后,还使java应用程序可以在网络上传播结果集,是不可以滚动的ResultSet变成了可以滚动的RowSet。
Year | JDBC Version | JSR Specification | JDK Implementation |
---|---|---|---|
2014 | JDBC 4.2 | JSR 221 | Java SE 8 |
2011 | JDBC 4.1 | JSR 221 | Java SE 7 |
2006 | JDBC 4.0 | JSR 221 | Java SE 6 |
2001 | JDBC 3.0 | JSR 54 | JDK 1.4 |
1999 | JDBC 2.0 | JDK 1.2? | |
1997 | JDBC 1.2 | JDK 1.1? |
http://www.herongyang.com/JDBC/Overview-JDBC-Version.html
DriverManager
数据源
使用JNDI配置并获取DataSource:JNDI学习总结(一)——JNDI数据源的配置
Proxool or C3P0,在MAVEN上找到的最早的版本都是2005年十一月发布的。但这两者现在基本都已不再更新。(c3p0偶尔还有一些小的更新,proxool在2006年后已经彻底不更新了)
c3p0在很长一段时间内,它一直是Java领域内数据库连接池的代名词,当年盛极一时的Hibernate都将其作为内置的数据库连接池。c3p0功能简单易用,稳定性好这是它的优点,但性能上的缺点却让它彻底被打入冷宫。c3p0的性能很差,差到即便是和同时代的产品相比,它也是垫底的(见图一)。同时代的BoneCP更是直接以干掉它为自己的口号(官网号称比c3p0快25倍),更不要说和后来的druid和HikariCP相比了。
c3p0最致命的问题就是架构设计过于复杂,让重构变成了一项不可能完成的任务。随着国内互联网大潮的涌起,性能有硬伤的c3p0彻底的退出了历史舞台。
proxool最初在设计上另辟蹊径,以JDBC驱动的身份为用户提供连接池服务,这使得将proxool移植到现有代码中别的十分容易,而且proxool还开创性的提供了连接池监控功能,让它迅速的获得了不少用户的青睐。
但产品作者兴趣的缺失,让这款本来很有潜力的产品早早夭折。在github的项目首页,作者写到:“我从2006年之后就再没碰过这个项目了,我甚至练Java都不用了…”,也许,proxool本来就是这位天才coder的练手之作,java本身也不是他的主力语言,但不论哪种原因,proxool都已经和c3p0一样,鲜有人问津了。
This project is no longer actively maintained. I haven’t used Proxool myself since 2006 and no longer even use Java. If the project has any chance of survival at all it would need to find a new maintainer. If anyone can recommend a good alternative I would be happy to mention it here. Alternatively, if anyone wants to contribute to this project then please create a pull request.
关于使用c3p0获取数据源:
JNDI学习总结(二)——Tomcat下使用C3P0配置JNDI数据源
Hibernate整合C3P0实现连接池
区分一个数据库连接池是属于第一代产品还是第二代产品的一个最重要特征就是看它在架构和设计时采用的线程模型,因为这直接影响的并发环境下存取数据库连接的性能。一般来讲采用单线程同步的架构设计的都属于第一代连接池,而采用多线程异步架构的则属于第二代。
大话数据库连接池
数据库连性池性能测试(hikariCP,druid,tomcat-jdbc,dbcp,c3p0)
Druid连接池介绍
druid wiki
druid 的filter设计原理
参考资料:
1、ODBC
2、JDBC进化史–从JDBC1.0到JDBC4.2
3、Why do we use a DataSource instead of a DriverManager?
4、Java中用动态代理实现标准的DataSource数据源连接池
5、数据库连接池性能比对
6、大话数据库连接池
7、druid wiki
8、druid 的filter设计原理