首页 > 代码库 > 数据库连接池

数据库连接池

手动编写连接池需实现java.sql.DataSource接口。DataSource接口中定义了两个重载的getConnection方法:(JDK API)

  Connection getConnection()

  Connection getConnection(String username, String password)

实现DataSource接口,并实现连接池功能的步骤:

  1. 在DataSource构造函数中批量创建与数据库的连接,并把创建的连接加入LinkedList对象中。

  2. 实现getConnection方法,让getConnection方法每次调用时,从LinkedList中取一个Connection返回给用户。

  3. 当用户使用完Connection,调用Connection.close()方法时,Collection对象应保证将自己返回到LinkedList中,而不要把conn还给数据库。

    4. Collection保证将自己返回到LinkedList中是此处编程的难点。

  所以为了让连接用完返回给LinkedList集合,而不是返还给数据库,必须要增强connection的close方法

     //增强 close方法,conn.close()
  在实际开发,发现对象的方法满足不了开发需求时,有三种方式对其进行增强
  1.写一个connecton子类,覆盖close方法,增强close方法
  2.用包装设计模式
  3.用动态代理 aop 面向切面编程

这里不可以用子类的方法来做,因为connection里面封装了很多其他信息,程序中还会用到connection的其他信息,所以如果用子类的方法基本不可能,等同于要重新写jdbc的驱动了。

 

包装设计模式增强close方法步骤:

   1.定义一个类,实现与被增强相同的接口
   2.在类中定义一个变量,记住被增强对象
   3.定义一个构造函数,接收被增强对象
   4.覆盖想增强的方法
   5.对于不想增强的方法,直接调用目标对象(被增强对象)的方法

 

class MyConnection implements Connection{        private Connection conn;        public MyConnection(Connection conn){            this.conn = conn;        }        public void close(){            list.add(this.conn);        }        public void clearWarnings() throws SQLException {            this.conn.clearWarnings();                    }

.......

 

最好的解决办法是动态代理。采用拦截技术。AOP,面向切面编程

 

开源数据库连接池:数据库连接池也叫数据源

现在很多WEB服务器(Weblogic, WebSphere, Tomcat)都提供了DataSoruce的实现,即连接池的实现。

通常我们把DataSource的实现,按其英文含义称之为数据源,数据源中都包含了数据库连接池的实现。


也有一些开源组织提供了数据源的独立实现:
  DBCP 数据库连接池
  C3P0 数据库连接池

实际应用时不需要编写连接数据库代码,直接从数据源获得数据库的连接。程序员编程时也应尽量使用这些数据源的实现,以提升程序的数据库访问性能。

TOMCAT内置的连接池就是DBCP,tomcat是Apache的,dbcp也是apache的。

 

 

DBCP数据源:

DBCP 是 Apache 软件基金组织下的开源连接池实现,使用DBCP数据源,应用程序应在系统中增加如下两个 jar 文件:

  Commons-dbcp.jar:连接池的实现

  Commons-pool.jar:连接池实现的依赖库

Tomcat 的连接池正是采用该连接池来实现的。该数据库连接池既可以与应用服务器整合使用,也可由应用程序独立使用。

 

dbcpconfig.properties封装了DBCP数据源的一些配置信息,包括数据库连接,连接数等。
一般放在src文件夹下
public class JdbcUtils_DBCP {        private static DataSource ds = null;    static{        try{            InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");            Properties prop = new Properties();            prop.load(in);                        BasicDataSourceFactory factory = new BasicDataSourceFactory();            ds = factory.createDataSource(prop);        }catch (Exception e) {            throw new ExceptionInInitializerError(e);        }    }    public static Connection getConnection() throws SQLException{        return ds.getConnection();//从连接池中拿连接,这个连接肯定也是增强过的,因为该连接用完还要还给连接池。    }            public static void release(Connection conn,Statement st,ResultSet rs){                if(rs!=null){            try{                rs.close();   //throw new             }catch (Exception e) {                e.printStackTrace();            }            rs = null;        }        if(st!=null){            try{                st.close();            }catch (Exception e) {                e.printStackTrace();            }            st = null;        }        if(conn!=null){            try{                conn.close();            }catch (Exception e) {                e.printStackTrace();            }        }                    }}    

在开发中可以通过上面的连接池来获取连接,释放连接。

 

 

C3P0数据源:Spring内置的连接池就是C3P0

导入C3P0的两个jar包

  c3p0.....jar

  mchang-commons.jar

c3p0-config.xml 连接池的配置文件,一般放在src目录下,详情查看c3p0的文档

 

<?xml version="1.0" encoding="UTF-8"?><c3p0-config>    <default-config>        <property name="driverClass">com.mysql.jdbc.Driver</property>        <property name="jdbcUrl">jdbc:mysql://localhost:3306/day16</property>        <property name="user">root</property>        <property name="password">root</property>                <property name="acquireIncrement">5</property>        <property name="initialPoolSize">10</property>        <property name="minPoolSize">5</property>        <property name="maxPoolSize">20</property>                    </default-config>    <named-config name="flx">        <property name="driverClass">com.mysql.jdbc.Driver</property>        <property name="jdbcUrl">jdbc:mysql://localhost:3306/day16</property>        <property name="user">root</property>        <property name="password">root</property>        <property name="acquireIncrement">5</property>        <property name="initialPoolSize">10</property>        <property name="minPoolSize">5</property>        <property name="maxPoolSize">20</property>    </named-config></c3p0-config>

 

public class JdbcUtils_C3P0 {        private static ComboPooledDataSource ds = null;    static{        try{            ds = new ComboPooledDataSource();        }catch (Exception e) {            throw new ExceptionInInitializerError(e);        }    }    public static Connection getConnection() throws SQLException{        return ds.getConnection();    }            public static void release(Connection conn,Statement st,ResultSet rs){                if(rs!=null){            try{                rs.close();   //throw new             }catch (Exception e) {                e.printStackTrace();            }            rs = null;        }        if(st!=null){            try{                st.close();            }catch (Exception e) {                e.printStackTrace();            }            st = null;        }        if(conn!=null){            try{                conn.close();            }catch (Exception e) {                e.printStackTrace();            }        }                    }}    

 

 

配置TOMCAT数据库连接池:

使用tomcat的时候,可以不必要加入第三方连接池,tomcat内置了一个连接池, 如果希望tomcat

为你的应用程序创建连接池,需要对tomcat做配置。

<Context>  <Resource name="jdbc/datasource" auth="Container"            type="javax.sql.DataSource" username="root" password="root"            driverClassName="com.mysql.jdbc.Driver"            url="jdbc:mysql://localhost:3306/jdbc"            maxActive="8" maxIdle="4"/></Context>

只要对tomcat做了上面的配置,tomcat启动的时候就会为你的应用程序创建连接池,并且tomcat会把创建的连接池以JNDI的形式绑定到一个uri上面去,

name="jdbc/datasource",只要用的时候使用这个名称在JNDI中检索就可以啦。

以上配置可以在tomcat-config里的server.xml里

也可以在WebRoot-META-INF文件夹下新建一个context.xml里配置

可以参考tomcat的主页里的JNDI-COnfigration

 

在程序中就可以使用JNDI的方式去向连接池要连接了。

 

Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
dataSource = (DataSource)envCtx.lookup("jdbc/datasource");

特别提醒:此种配置下,驱动jar文件需放置在tomcat的lib下

 

JNDI(Java Naming and Directory Interface),Java命名和目录接口,它对应于J2SE中的javax.naming包,

这套API的主要作用在于:它可以把Java对象放在一个容器中(JNDI容器),并为容器中的java对象取一个名称,以后程序想获得Java对象,只需通过名称检索即可。

其核心API为Context,它代表JNDI容器,其lookup方法为检索容器中对应名称的对象。

 

public class JdbcUtils_Tomcat {    private static DataSource ds;    static {        try {            Context initCtx = new InitialContext();            Context envCtx = (Context) initCtx.lookup("java:comp/env");            ds = (DataSource) envCtx.lookup("jdbc/EmployeeDB");        } catch (Exception e) {            throw new RuntimeException(e);        }    }    public static Connection getConnection() throws SQLException{        return ds.getConnection();    }}

在程序中就可以使用上面的工具类来向tomcat内置的数据源要连接。

 

数据库连接池