数据库连接池技术

来源:互联网 发布:单片机时钟程序汇编 编辑:程序博客网 时间:2024/06/07 06:26

连接池的基本原理:
数据库连接池的解决方案是在应用程序启动时建立足够的数据库连接,并将这些连接组成一个连接池。由应用程序动态地对池中的连接进行申请、使用和释放。对于多于连接池中连接数的并发请求,应在请求队列中排列等待,并且应用程序可根据池中连接的使用率,动态增加或减少池中的连接数。
连接池的概念是:连接池允许应用程序从连接池中获得一个连接并使用这个连接,而不需要为每一个连接请求重新建立一个连接。一旦一个新的连接被创建并且放置在连接池中,应用程序就可以重复使用这个连接而不必实施整个数据库连接创建过程。当应用程序请求一个连接时,连接池为该应用程序分配一个连接而不是重新建立一个连接;当应用程序使用完连接后,该连接被归还给连接池而不是直接释放。
连接池的工作机制
连接池是众多连接对象的“缓冲存储池”,连接池提供一种管理机制来控制连接池内部连接对象的个数,提供应用程序使用的获取、释放连接接口。连接池主要由3部分组成:连接池的建立、连接池中连接使用与释放。下面就着重讨论这3部分及连接池的配置问题
建立连接池
首先要建立一个静态的连接池,在系统初始化时就分配好池中的连接,并且不能够随意关闭。使用Java中的容器类可以很好地构建连接池,如:Vector,Stack等。在系统初始化时,根据
配置创建连接并放置在连接池中,以后所使用的连接都是从该连接池中获取。这样就可以避免由于频繁的连接和断开所造成的开销。通过使用连接池将大大提高程序效率,同时,可以通过
其自身的管理机制来监视数据库连接的数量,使用情况等。
连接池内连接的使用与释放
建立好连接池后,还需要提供一套相应的分配、释放等策略来保证数据库的有效复用。当客户请求数据库连接时,首先看连接池中是否有匹配的空闲连接。如果有,则把该连接分配给客户。此时该连接就在多个客户间复用。当客户释放数据库连接时,可以根据该连接是否被复用进行不同的处理。如果连接没有使用者,就放入连接池中,而不是被关闭。
配置连接池
对于数据库连接,一般的配置策略是根据具体的应用需求,给出一个初始的连接池中连接的数目,以及一个连接池可以扩张到的最大连接数目。当连接数目不够用时,连接池将逐个添加数据库连接,直到最大连接数。此后的连接请求被加入请求队列,即如果请求了更多的连接,那么调用者被挂起,直到有一个连接放回连接池。
[url=http://burt.javaeye.com/blog/71705][color=#108ac6]配置tomcat 6.0.10连接池[/color][/url]
(位于:$CATALINA_HOME/conf/server.xml)
在中添加下列代码:

Context path="" docBase=""
          debug="0" reloadable="true" crossContext="true">
           Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
           maxAtive="100" maxIdle="30" maxWait="10000"
           username="javauser" password="javadude" driverClassName="com.mysql.jdbc.Driver"
           url="jdbc:mysql://localhost:3306/javatest?autoReconnect=true" />
          /Context>
修改web应用的目录WEB-INF的web.xml文件。
在中添加下列代码:
resource-ref>
        description>DB Connection/description>
        res-ref-name>jdbc/TestDB/res-ref-name>
        res-type>javax.sql.DataSource/res-type>
        res-auth>Container/res-auth>
/resource-ref>
进行连接:
package cn.burt.connpool;
  
import java.sql.*;
import javax.naming.*;
import javax.sql.*;
  
public class Conn {
       public static synchronized Connection get() throws Exception {
           Context ctx = new InitialContext();
           Context envctx = (Context) ctx.lookup("java:comp/env");
           DataSource ds = (DataSource) envctx.lookup("jdbc/TestDB");
           return ds.getConnection();
       }
}
在jsp中调用这个类:
%@ page language="java" import="java.util.*,cn.burt.connpool.*" pageEncoding="gb2312"%>
%@ page import="java.sql.*,javax.sql.*" %>
  
%
  
Connection conn=null;
Statement st=null;
ResultSet rs=null;
  
try{
      
      conn=get();
      st=conn.createStatement();
      rs=st.executeQuery("select * from testdata");
      
      while(rs.next()){
      System.out.println(rs.getString("foo"));
      }
      
      st.close();
      rs.close();
      conn.close();
      
}catch(Exception e){
      e.printStackTrace();
}
  
%>

上述配置数据源的方式使用了JNDI,那么什么是JNDI呢?
参见:
[url=http://avaj.javaeye.com/blog/151736]http://avaj.javaeye.com/blog/151736[/url]

Hibernate实现数据库的连接不同方式:
1. 程序内部启动 c3p0 连接池。
   配置方式如下:连接池的支持(注:需要c3p0的类库支持)
property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
        property name="hibernate.connection.url" value="jdbc:postgresql://xxxxx/xxxx" />
        property name="hibernate.connection.username" value="xxxxx" />
        property name="hibernate.connection.password" value="xxxx" />
        property name="hibernate.c3p0.min_size"
                    value="5"/>
        property name="hibernate.c3p0.max_size"
                    value="20"/>
        property name="hibernate.c3p0.timeout"
                    value="300"/>
        property name="hibernate.c3p0.max_statements"
                    value="50"/>
        property name="hibernate.c3p0.idle_test_period"
                    value="3000"/>
注: Hibernate根据 hibernate.c3p0.max_size 这个配置来识别是支持c3p0连接池
2. 引用外部连接池    (通过JNDI查找 DataSource资料)
   需要配置方式如下:
property name="hibernate.connection.datasource" value="java:comp/env/jdbc/qualitydb"/>
3. 通过 org.hibernate.connection.ProxoolConnectionProvider 创建
    由
       hibernate.proxool.xml
       hibernate.proxool.properties
       hibernate.proxool.existing_pool 三个配置一起来确定
4.  DriverManager 创建直接连接方式
property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
       property name="hibernate.connection.url" value="jdbc:postgresql://xxxxx/xxxx" />
       property name="hibernate.connection.username" value="xxxxx" />
       property name="hibernate.connection.password" value="xxxx" />
注: Hibernate根据 hibernate.connection.url这个来识别,由于在识别时,c3p0的优先级会高于DriverManger所以,与c3p0的配置不会冲突


有几种开源的数据库连接池:
一种是dbcp,一种是c3p0,还有一种是proxool

spring中怎样配置数据库连接池(采用dbcp):

bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  property name="driverClassName">
  value>${jdbc.driverClassName}/value>
  /property>
  property name="url">
  value>${jdbc.url}/value>
  /property>
  property name="username">
  value>${jdbc.username}/value>
  /property>
  property name="password">
  value>${jdbc.password}/value>
  /property>
  property name="maxActive">
  value>${jdbc.maxActive}/value>
  /property>
  property name="initialSize">
  value>${jdbc.initialSize}/value>
  /property>
  property name="maxWait">
  value>${jdbc.maxWait}/value>
  /property>
  property name="minIdle">
  value>${jdbc.minIdle}/value>
  /property>
  /bean>