宁波IT培训
美国上市IT培训机构

0574-87236644

JDBC是什么?你真的理解吗?

  • 时间:2018-06-11 19:42
  • 发布:转载
  • 来源:网络

JDBC是什么?Java数据库连接(Java Database Connectivity,简称JDBC),是Java语言中用来规范客户端应用程序(比如Web应用程序等如何访问关系型数据库的应用程序接口),提供了诸如查询和更新数据库中数据的方法。

JDBC驱动程序一共有四种类型:

类型1-JDBC-ODBC桥

类型2-本地API驱动

类型3-网络协议驱动

类型4-本地协议驱动

我们常用的是类型4-本地协议驱动,这种类型的驱动使用socket链接,直接在客户端和数据库之间进行通信。

优点是1-访问速度快 2-最直接,最纯粹的JAVA实现。

缺点是1-需要每个数据库厂商提供自己的JDBC驱动。2-需要针对不同的数据库使用不同的驱动程序。

JDBC的API在jdk的java.sql包中,扩展的内容在javax.sql包中。主要包括(斜体代表接口,需驱动程序提供者来具体实现):

DriverManager:负责加载各种不同驱动程序(Driver),并根据不同的请求,向调用者返回相应的数据库连接(Connection)。

Driver:驱动程序,会将自身加载到DriverManager中去,并处理相应的请求并返回相应的数据库连接(Connection)。

Connection:数据库连接,负责进行与数据库间的通讯,SQL执行以及事务处理都是在某个特定Connection环境中进行的。可以产生用以执行SQL的Statement。

Statement:用以执行SQL查询和更新(针对静态SQL语句和单次执行)。

PreparedStatement:用以执行包含动态参数的SQL查询和更新(在服务器端编译,允许重复执行以提高效率)。

CallableStatement:用以调用数据库中的存储过程。

SQLException:代表在数据库连接的创建和关闭和SQL语句的执行过程中发生了例外情况(即错误)。

3DBCP数据库连接池和JDBC之间的关系

数据库连接池负责创建(通过JDBC API)、管理、销毁数据库的连接。应用程序可以从数据库连接池中重复使用一个现有的连接,而不是重新创建一个。连接池,common-pool中的GenericObjectPool它负责缓存和管理连接;连接,这是是指PoolableConnection;连接池和连接一对多的关系。池化技术是通过commons-pool来实现的,每个连接是一个对象,换言之,是对象池的使用与管理。DBCP连接池是基于commons-pool这种对象池来实现的。

二、commons-pool的理解

Apache commons-pool是一种对象池技术,我们使用的很多涉及池的场景一般都是基于该组件来实现的,DBCP数据库连接池也是基于commons-pool来实现的,因此我们先来了解下这种对象池技术。下图是对象池的对象生命周期流程图。

讲真,你真的懂JDBC吗?
三、DBCP核心类图及序列图
讲真,你真的懂JDBC吗?
讲真,你真的懂JDBC吗?
讲真,你真的懂JDBC吗?
讲真,你真的懂JDBC吗?
讲真,你真的懂JDBC吗?
讲真,你真的懂JDBC吗?
创建数据源createDataSource
讲真,你真的懂JDBC吗?
创建连接getConnection
讲真,你真的懂JDBC吗?
创建statement prepareStatement
讲真,你真的懂JDBC吗?
四、DBCP配置及使用

DBCP是Apache下的一个开源数据库连接池,我们在使用时需要两个JAR文件,分别是commons-dbcp.jar(连接池的实现)和commons-pool.jar(连接池实现的依赖库),不过我们在使用的时候只需要引入下面mvaen坐标,commons-pool是在commons-dbcp里面隐含引用了。

注意一点,就是从1.x升级到2.x的时候,由于DBCP的包路径已经变了,需要升级者修改局部代码。

<dependency>

<groupId>commons-dbcp</groupId>

<artifactId>commons-dbcp</artifactId>

<version>2.2</version>

</dependency>

DBCP可以在应用程序中独立的使用,也可以与web应用服务器整合使用。

1Tomcat中使用

比如Tomcat的连接池就是采用该连接池来实现的。如下:

讲真,你真的懂JDBC吗?

2应用程序中独立使用

讲真,你真的懂JDBC吗?

更多配置请参照

五、连接超时机制

对网络资源访问时,超时设置是必须的。没有超时的保护,一旦依赖资源发生故障或者网络故障,就会引起线程堆积,甚至发生雪崩。

1超时层级

讲真,你真的懂JDBC吗?

从这张图中我们也能够看出DBCP并不参与数据库超时的处理,它只负责管理连接。根据上图我们可以看到超时有一个依赖层级,上层超时依赖下层超时。依次为:事务超时->Statement超时->JDBC Driver socket超时->操作系统超时。

事务超时

事务是应用层级的概念,我们知道事务是有一组SQL执行单元组成的。那么事务超时的时间阈值,实际是Statement超时N个需要执行的Statement数量。比如一个事务里面有3条Statement,每条Statement的执行时间是50MS,其它业务上的逻辑执行时间+框架执行时间未100ms,那么最终事务的超时时间为:350+100=250ms。

statement超时

用来限制SQL语句的执行时间,通过setQueryTimeout(int timeout)来设置,不过现在大都是ibatis了,可以通过 SqlMapConfig.xml 中的 setting 属性defaultStatementTimeout 来设置全局的 statement 超时缺省值,还可以在每个sql.xml文件中,根据业务实际需要来设置<select timeout="10"/> <insert timeout="10"/> <update timeout="10"/>

Socket超时

这是底层的一种超时,因为我们使用的JDBC驱动类型是TYPE4,它是基于socket来通信的。MySQL的JDBC驱动中的connectTimeout 和 socketTimeout 的默认值是 0 ,这意味着不会发生超时。所以我们必须在DBCP配置中设置这两个值。

connectTimeout为建立连接的超时时间,socketTimeout为JDBC客户端和数据库服务器之间数据交互的时间。注意这里配置的socketTimeout的值必须要大于Statement的超时时间值。否则Statement超时就没有意义,也不能生效。

操作系统的socket超时

linux操作系统也会设置socket超时,比如我们这边的服务器一般配置的是20分钟,因为公司的Linux服务器的KeepAlive检查周期为20分钟。这样即使上面的socketTimeout值为0永不超时,也还是要收到Linux服务器的超时限制,也就是由于网络原因引起的数据库网络连接问题也不会超过20分钟。

2MySQL处理超时的机制及原理

讲真,你真的懂JDBC吗?

上图是一MySQL在执行一个命令的过程中的步骤以及发生超时现象后的处理机制:

通过Connection的createStatement()方法去创建一个Statement,以便后续进行读写操作

执行第1步创建的Statement的executeQuery()方法

将查询请求命令发送到MySQL数据库服务器

创建一个超时线程(从5.1版本以后,在创建每个连接的时候,会随之创建一个处理超时的线程timeout-execution)

把当前的statement对象注册到超时线程timeout-execution中

发生了超时(阈值是你在Statement执行前候配置的setQueryTimeout(int timeout),如果是mybatis则是在配置文件里面配置的值defaultStatementTimeout="15",单位s)

超时线程会重新创建一个新的Connection,这个Connection的属性配置都跟先前的一样

用新创建的这个Connection去发送取消查询请求

六、各种数据库连接池性能对比

测试环境,OS: OS X 10.8.2 CPU:intel i7 2GHz 4 core JVM:java version "1.7.0_05"

测试执行申请归还连接1,000,000(一百万)次总耗时性能对比,Java7 的基准测试结果如下:

讲真,你真的懂JDBC吗?

Druid是性能最好的数据库连接池,DBCP性能属于中上,我们在以后的业务场景中可以根据实际需要做选择。这个是Druid的官方测试,不过可以利用测试代码自己进行验证一遍,测试代码如下:

https://github.com/alibaba/druid/blob/master/src/test/java/com/alibaba/druid/benckmark/pool/Case1.java

七、总结

本文梳理了数据库连接相关的概念,JNDI、JDBC、连接池,DBCP的核心类和时序图,另外还梳理了commons的池化组件,最后描述了JDBC连接过程中的超时机制,包括超时依赖和超时的机制原理,超时的知识点对与我们非常重要,超时是一种防护措施,当依赖DB性能变慢或者网络故障的情况下,可以快速失败,以便保护应用程序不会导致线程堆积而发生雪崩这类致命事故。

预约申请免费试听课

怕钱不够?就业挣钱后再付学费!    怕学不会?从入学起,达内定制课程!     担心就业?达内多家实践企业供你挑选!

上一篇:干货:Spring AOP的实现机制
下一篇:干货分享:MySQL分区和分表

2020年Java程序员就业难吗?

Java工程师是干什么的?

Java工程师前途在哪里?

Java学到什么程度可以就业?

选择城市和中心
江西省

贵州省

广西省

海南省