数据库连接池--DBCP&&C3P0

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/MyBabyChao/article/details/82353701

全文结构:

  1. 为什么需要数据库连接池?
  2. 什么是数据库连接池?
  3. 使用DBCP获取连接
  4. 使用C3P0获取连接

1.为什么需要数据库连接池?

数据库连接是一种关键的、有限的、昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出。对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标。数据库连接池正是针对这个问题提出来的。

我们每次需要查询查询数据库时,都需要创建对数据库的连接对象,查询完成后,我们需要释放连接。可每次创建、释放连接所需要消耗的资源是比较大的。但是如果使用单例的Connection,又无法提高性能,这个时候问题的就出现了,一方面我们希望减少频繁创建Connection来减少资源的消耗,从而提高性能,另一方面,又希望能够在并发量比较大的时候,能够有多个Connection并发操作,从而提高性能。解决这个问题的一个比较好的做法就是使用池化技术。

参考数据库连接池之DBCP

2.数据库连接池

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个。


3.DBCP

DBCP(DataBase ConnectionPool)数据库连接池,是java数据库连接池的一种,由Apache开发,通过数据库连接池,可以让程序自动管理数据库连接的释放和断开。

使用DBCP获取连接

准备工作

1.导入DBCP依赖的jar包。

  • commons-dbcp-1.4.jar
  • commons-pool-1.5.6.jar

2.Java连接MySQL需要的驱动包

  • mysql-connector-java-5.1.7-bin.jar

3.存放DBCP的所有配置参数的properties文件,放在src目录下。参考官方提供的参数信息配置

dbcpconfig.properties文件内容:

# 连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
username=root
password=root

# 初始化连接 
initialSize=10

# 最大连接数量
maxActive=50

# 最大空闲连接 
maxIdle=20

# 最小空闲连接
minIdle=5

# 超时等待时间以毫秒为单位 60000毫秒/1000等于60秒
maxWait=60000


# JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;] 
# 注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=gbk

# 指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true

# driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
# 可用值为下列之一:NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED

代码:

package com.mbc.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.junit.Test;

import com.mbc.util.JDBCUtil;

public class TestDBCP {

    @Test
    //连接方式1
    public void testDBCP1(){
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            //1.创建数据源对象
            BasicDataSource source = new BasicDataSource();

            //读取配置文件
            InputStream in = TestDBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
            Properties properties = new Properties();
            properties.load(in);

            //2.设置驱动名称,数据库的url,用户名,密码
            source.setDriverClassName(properties.getProperty("driverClassName"));
            source.setUrl(properties.getProperty("url"));
            source.setUsername(properties.getProperty("username"));
            source.setPassword(properties.getProperty("password"));

            //3.从数据源中获取连接
            conn = source.getConnection();

            //执行简单的查询操作
            String sql = "SELECT * FROM user";
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            while(rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                System.out.println("id:" + id + " name:" + name);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtil.release(conn, ps);
        }       
    }

    @Test
    //连接方式2,上面的连接方式需要设置数据源的各个参数,太麻烦了,
    //我们可以创建BasicDataSource的工厂类来简化代码
    public void testDBCP2(){
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            //1.创建数据源工厂对象
            BasicDataSourceFactory factory = new BasicDataSourceFactory();
            //读取配置文件
            InputStream in = TestDBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
            Properties properties = new Properties();
            properties.load(in);

            //2.读取配置文件来创建数据源对象
            DataSource source = factory.createDataSource(properties);

            //3.从数据源中获取连接
            conn = source.getConnection();

            //3.从数据源中获取连接
            conn = source.getConnection();

            //执行简单的查询操作
            String sql = "SELECT * FROM user";
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            while(rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                System.out.println("id:" + id + " name:" + name);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭资源
            //关闭连接,实际上是把连接放回到连接池中
            JDBCUtil.release(conn, ps, rs);
        }       
    }
}

JDBCUtil中的代码

package com.mbc.util;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCUtil {
    public static void release(Connection conn , Statement st , ResultSet rs){
        closeRs(rs);
        closeSt(st);
        closeConn(conn);
    }

    public static void release(Connection conn , Statement st){
        closeSt(st);
        closeConn(conn);
    }

    private static void closeRs(ResultSet rs){
        try {
            if(rs != null){
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            rs = null;
        }
    }

    private static void closeSt(Statement st){
        try {
            if(st != null){
                st.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            st = null;
        }
    }

    private static void closeConn(Connection conn){
        try {
            if(conn != null){
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            conn = null;
        }
    }
}

4.使用C3P0获取连接

C3P0

C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。 –百度百科

准备工作
1.导入C3P0依赖的jar包

  • c3p0-0.9.1.2.jar

2.Java连接MySQL需要的驱动包

  • mysql-connector-java-5.1.7-bin.jar

3.存放C3P0的所有配置参数的c3p0-config.xml(名称不能变)文件,放在src目录下。c3p0的配置文件支持properties,也支持xml方式。不过开发中,一般使用xml方式来配置。参数配置参考:数据库连接池C3P0学习

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <!-- default-config 默认的配置,  -->
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost/test</property>
        <property name="user">root</property>
        <property name="password">root</property>
        <!-- 连接池初始化时创建的连接数  -->
        <property name="initialPoolSize">10</property>
        <!-- 连接的最大空闲时间  -->
        <property name="maxIdleTime">30</property>
        <!-- 连接池保持的最大连接数  -->
        <property name="maxPoolSize">100</property>
        <!-- 连接池保持的最小连接数  -->
        <property name="minPoolSize">10</property>
        <!-- 连接池为数据源缓存的PreparedStatement的总数 -->
        <property name="maxStatements">200</property>
    </default-config>
<c3p0-config>

代码实现

package com.mbc.test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import org.junit.Test;

import com.mbc.util.JDBCUtil;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class TestC3p0 {

    @Test
    //连接方式1,不读取文件
    public void testDemo1() {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            //1.创建ComboPooledDataSource对象
            ComboPooledDataSource source = new ComboPooledDataSource();

            //2.设置参数
            source.setDriverClass("com.mysql.jdbc.Driver");
            source.setJdbcUrl("jdbc:mysql://localhost:3306/test");
            source.setUser("root");
            source.setPassword("root");

            //3.获取连接
            conn = source.getConnection();

            //4.执行简单的查询操作
            String sql = "SELECT * FROM user";
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            while(rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                System.out.println("id:" + id + " name:" + name);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            JDBCUtil.release(conn, ps, rs);
        }
    }

    @Test
    //连接方式2,读取配置文件的c3p0-config.xml
    public void testDemo2() {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            //1.创建ComboPooledDataSource对象
            ComboPooledDataSource source = new ComboPooledDataSource();

            //2.获取连接
            conn = source.getConnection();

            //3.执行简单的查询操作
            String sql = "SELECT * FROM user";
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            while(rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                System.out.println("id:" + id + " name:" + name);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            JDBCUtil.release(conn, ps, rs);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/MyBabyChao/article/details/82353701