java中建立java数据库连接池池,有哪几个步骤

  接下来,在我们的应用中,只要简单地使用ConnectionSource.getConnection()就可以取得连接池中的连接,享受数据库连接带给我们的好处了。当我们使用完取得的数据库连接后,只要简单地使用connection.close()就可把此连接返回到连接池中,至于为什么不是直接关闭此连接,而是返回给连接池,这是因为dbcp使用委派模型来实现Connection接口了。

  在使用Properties来创建BasicDataSource时,有很多参数可以设置,比较重要的还有:

  testOnBorrow、testOnReturn、testWhileIdle,他们的意思是当是取得连接、返回连接或连接空闲时是否进行有效性验证(即是否还和数据库连通的),默认都为false。所以当数据库连接因为某种原因断掉后,再从连接池中取得的连接,实际上可能是无效的连接了,所以,为了确保取得的连接是有效的, 可以把把这些属性设为true。当进行校验时,需要另一个参数:validationQuery,对oracle来说,可以是:SELECT COUNT(*) FROM DUAL,实际上就是个简单的语句,验证时,就是把这个SQL语句在数据库上跑一下而已,如果连接正常的,当然就有结果返回了。

时间,就会启动一个线程,校验连接池中闲置时间超过minEvictableIdleTimeMillis的连接对象。

一.数据库连接池的概念

数据库连接池可以理解为是存放多个数据库连接的集合。

  作用;解决建立数据库连接耗费很多资源和时间问题,提高性能

* DBCP连接池实现类:

* 连接池的创建步骤 :

* 1:创建一个空的连接池

* 2:给这个连接池设置四大信息--->连接池会自动的向池子中存放连接 (默认一般是10个)

* 3:封装一个方法,对外提供一个连接池中连接

//创建一个空的连接池

* 方法会自动的去bin目录中找配置文件夹

* 该方法会做两件事情:

* 2: 创建一个有连接的连接池

* 创建一个静态方法 ,可以让外界获取连接对象

//这里这个close不是关流释放资源,而是重写方法,将连接放回连接池

④使用编写的工具类(简单demo)

C3P0开源免费的连接池!目前使用它的开源项目有:Spring、Hibernate等。使用第三方工具需要导入jar包,c3p0使用时还需要添加配置文件 c3p0-config.xml

    ①:导入jar包

    ②:编写配置文件

        文件类型:xml

③编写连接池使用工具类

* 1:创建一个空的连接池

* 2: 设置四大信息--->连接池会自动的存放连接

* 1:该对象在创建的时候会自动的检测是否有c3p0-config.xml

* 你需要手动的设置四大信息

* 1:该对象在创建的时候会自动的解析xml文件

* 3: 创建连接池,并向连接池中存放连接池

//封装一个方法,让别人能够获取连接池中的连接

conn.close();// 连接池已经重写类该方法,该方法是将连接重新放回到连接池

数据库连接池在编写应用服务是经常需要用到的模块,太过频繁的连接数据库对服务性能来讲是一个瓶颈,使用缓冲池技术可以来消除这个瓶颈。我们可以在 互联网上找到很多关于数据库连接池的源程序,但是都发现这样一个共同的问题:这些连接池的实现方法都不同程度地增加了与使用者之间的耦合度。很多的连接池 都要求用户通过其规定的方法获取数据库的连接,这一点我们可以理解,毕竟目前所有的应用服务器取数据库连接的方式都是这种方式实现的。但是另外一个共同的 问题是,它们同时不允许使用者显式的调用Connection.close()方法,而需要用其规定的一个方法来关闭连接。这种做法有两个缺点:

第一:改变了用户使用习惯,增加了用户的使用难度。

首先我们来看看一个正常的数据库操作过程:

使用者在用完数据库连接后通常是直接调用连接的方法close来释放数据库资源,如果用我们前面提到的连接池的实现方法,那语句 conn.close()将被某些特定的语句所替代。

第二:使连接池无法对之中的所有连接进行独占控制。由于连接池不允许用户直接调用连接的close方法,一旦使用者在使用的过程中由于 习惯问题直接关闭了数据库连接,那么连接池将无法正常维护所有连接的状态,考虑连接池和应用由不同开发人员实现时这种问题更容易出现。

综合上面提到的两个问题,我们来讨论一下如何解决这两个要命的问题。

首先我们先设身处地的考虑一下用户是想怎么样来使用这个数据库连接池的。用户可以通过特定的方法来获取数据库的连接,同时这个连接的类 型应该是标准的java.sql.Connection。用户在获取到这个数据库连接后可以对这个连接进行任意的操作,包括关闭连接等。

通过对用户使用的描述,怎样可以接管Connection.close方法就成了我们这篇文章的主题。

为了接管数据库连接的close方法,我们应该有一种类似于钩子的机制。例如在Windows编程中我们可以利用Hook API来实现对某个Windows API的接管。在JAVA中同样也有这样一个机制。JAVA提供了一个Proxy类和一个InvocationHandler,这两个类都在 java.lang.reflect包中。我们先来看看SUN公司提供的文档是怎么描述这两个类的。

SUN的API文档中关于Proxy的描述很多,这里就不罗列出来。通过文档对接口InvocationHandler的描述我们可以 看到当调用一个Proxy实例的方法时会触发Invocationhanlder的invoke方法。从JAVA的文档中我们也同时了解到这种动态代理机 制只能接管接口的方法,而对一般的类无效,考虑到java.sql.Connection本身也是一个接口由此就找到了解决如何接管close方法的出 路。

首先,我们先定义一个数据库连接池参数的类,定义了数据库的JDBC驱动程序类名,连接的URL以及用户名口令等等一些信息,该类是用 于初始化连接池的参数,具体定义如下:

其次是连接池的工厂类ConnectionFactory,通过该类来将一个连接池对象与一个名称对应起来,使用者通过该名称就可以获 取指定的连接池对象,具体代码如下:

* 连接池类厂,该类常用来保存多个数据源名称合数据库连接池对应的哈希 //该哈希表用来保存数据源名和连接池对象的关系表 * 从连接池工厂中获取指定名称对应的连接池对象 * 将指定的名字和数据库连接配置绑定在一起并初始化数据库连接池 * 重新绑定数据库连接池 * 删除一个数据库连接池对象

ConnectionFactory主要提供了用户将将连接池绑定到一个具体的名称上以及取消绑定的操作。使用者只需要关心这两个类即 可使用数据库连接池的功能。下面我们给出一段如何使用连接池的代码:

//以上代码是用来登记一个连接池对象,该操作可以在程序初始化只做一次即可 //以下开始就是使用者真正需要写的代码

从使用者的示例代码就可以看出,我们已经解决了常规连接池产生的两个问题。但是我们最最关心的是如何解决接管close方法的办法。接 管工作主要在ConnectionFactory中的两句代码:

DataSourceImpl是一个实现了接口javax.sql.DataSource的类,该类维护着一个连接池的对象。由于该类 是一个受保护的类,因此它暴露给使用者的方法只有接口DataSource中定义的方法,其他的所有方法对使用者来说都是不可视的。我们先来关心用户可访 问的一个方法getConnection

//首先从连接池中找出空闲的对象 //判断是否超过最大连接数,如果超过最大连接数 //则等待一定时间查看是否有空闲连接,否则抛出异常告诉用户无可用连接 else{//没有超过连接数,重新获取一个数据库的连接 //代理将要返回的连接对象 * 从连接池中取一个空闲的连接 * 否则的话等待nTimeout毫秒看是否还有空闲连接,如果没有抛出异常 //等待nTimeout毫秒以便看是否有空闲连接

DataSourceImpl类中实现getConnection方法的跟正常的数据库连接池的逻辑是一致的,首先判断是否有空闲的连 接,如果没有的话判断连接数是否已经超过最大连接数等等的一些逻辑。但是有一点不同的是通过DriverManager得到的数据库连接并不是及时返回 的,而是通过一个叫_Connection的类中介一下,然后调用_Connection.getConnection返回的。如果我们没有通过一个中介 也就是JAVA中的Proxy来接管要返回的接口对象,那么我们就没有办法截住Connection.close方法。

终于到了核心所在,我们先来看看_Connection是如何实现的,然后再介绍是客户端调用Connection.close方法时 走的是怎样一个流程,为什么并没有真正的关闭连接。

* 数据连接的自封装,屏蔽了close方法 //用户最后一次访问该连接方法的时间 //返回数据库连接conn的接管类,以便截住close方法 * 该方法真正的关闭了数据库的连接 //由于类属性conn是没有被接管的连接,因此一旦调用close方法后就直接关闭连接 //判断是否调用了close的方法,如果调用close方法则把连接置为无用状态 //设置最后一次访问时间,以便及时清除超时的连接

一旦使用者调用所得到连接的close方法,由于用户的连接对象是经过接管后的对象,因此JAVA虚拟机会首先调用 _Connection.invoke方法,在该方法中首先判断是否为close方法,如果不是则将代码转给真正的没有被接管的连接对象conn。否则的 话只是简单的将该连接的状态设置为可用。到此您可能就明白了整个接管的过程,但是同时也有一个疑问:这样的话是不是这些已建立的连接就始终没有办法真正关 闭?答案是可以的。我们来看看ConnectionFactory.unbind方法,该方法首先找到名字对应的连接池对象,然后关闭该连接池中的所有连 接并删除掉连接池。在DataSourceImpl类中定义了一个close方法用来关闭所有的连接,详细代码如下:

* 关闭该连接池中的所有数据库连接

该方法一一调用连接池中每个对象的close方法,这个close方法对应的是_Connection中对close的实现,在 _Connection定义中关闭数据库连接的时候是直接调用没有经过接管的对象的关闭方法,因此该close方法真正的释放了数据库资源。

我要回帖

更多关于 java数据库连接池 的文章

 

随机推荐