数据库——开源数据库连接池DBCP和C3P0

数据库——数据库连接池

数据库连接是一种关键的、有限的、昂贵的资源

对数据库连接的管理能显著影响到整个应用程序(特别是多用户的网页应用程序)的伸缩性和健壮性,影响到程序的性能指标。

数据库连接—>执行完毕—>释放 这个过程很浪费系统资源

因此需要数据库连接池负责分配、管理和释放数据库连接(数据库连接池的功能)

编写连接池只用实现一个接口 DateSource

影响数据库连接池的因素:

  • 最小连接数:
    • 是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费。
    • 最小连接数 决定了数据库连接池在初始化时 创建的数据库连接数
    • 大于最小连接数的数据库连接在使用完不会马上被释放,它将被放到连接池中等待重复使用或是空闲超时后被释放。
  • 最大连接数:
    • 是连接池能申请的最大连接数,如果数据库连接请求超过此数,后面的数据库连接请求将被加入到等待队列中,等待过程中我们会设置一个等待时间,超过等待时间的数据库连接将会断开连接

开源数据库连接池

  • DBCP

  • C3P0

  • Druid(阿里巴巴)

使用了数据库连接池后,我们在项目开发中就不需要编写连接数据库的代码了

DBCP数据库连接池

DBCP需要导入的jar包

commons-dbcp.jar下载地址

commons-pool.jar 下载地址

jar包导入方法

编写DBCP工具类

package com.peng.cheng.lesson05.utils;

import com.peng.cheng.lesson02.utils.JdbcUtils;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

// DBPC数据库连接池工具类
public class JdbcUtils_DBCP {
    
    

    private static DataSource dataSource=null;

    static {
    
    //获取配置文件资源
        try {
    
     //          返回一个输入流                 获得类加载器+       获得具体的资源        资源名就是配置文件名,配置文件最好提出来单独放放
            InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
            Properties properties = new Properties();
            properties.load(inputStream);//加载文件

            //创建数据源   工厂模式,用来创建对象
            dataSource = BasicDataSourceFactory.createDataSource(properties);


        } catch (Exception  e) {
    
    
            e.printStackTrace();
        }
    }

    // 获取连接方法
    public static Connection getConnection() throws SQLException {
    
    
        return dataSource.getConnection();//从数据源中获取连接,DataSource数据源里面自带连接
    }

    //释放资源
    public static void release(Connection conn, Statement st, ResultSet rs) {
    
    
        if (rs != null) {
    
    
            try {
    
    
                rs.close();
            } catch (SQLException e) {
    
    
                e.printStackTrace();
            }
        }

        if (st != null) {
    
    
            try {
    
    
                st.close();
            } catch (SQLException e) {
    
    
                e.printStackTrace();
            }
        }
        if (conn != null) {
    
    
            try {
    
    
                conn.close();
            } catch (SQLException e) {
    
    
                e.printStackTrace();
            }
        }
    }
}

配置文件(文件名:dbcpconfig.properties)

#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=19990802

#<!-- 初始化连接 -->
initialSize=10

#最大连接数量
maxActive=50

#<!-- 最大空闲连接 -->
maxIdle=20

#<!-- 最小空闲连接 -->
minIdle=5

#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60-->
maxWait=60000


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

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

#driver default 指定由连接池所创建的连接的(read-commit)状态。
#如果没有设置该值,则“setReadonly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
defaultReadOnly=

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

DBCP的用法测试(一般在并发情况下使用数据源DateSource)

package com.peng.cheng.lesson05;

import com.peng.cheng.lesson05.utils.JdbcUtils_DBCP;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;

//测试DBCP数据库连接池
//测试插入语句
public class TestDBCP {
    
    
    public static void main(String[] args) {
    
    
        Connection conn = null;
        PreparedStatement pst = null;

        try {
    
    
            conn = JdbcUtils_DBCP.getConnection();
            //                                                                         使用?号占位符代替参数
            String sql = " INSERT INTO users (`id`,`NAME`,`PASSWORD`,`email`,`birthday`) VALUES(?,?,?,?,?) ";

            pst = conn.prepareStatement(sql);//传一个预编译的sql,先写SQL语句,然后不执行

            //手动给参数赋值
            pst.setInt(1, 6);
            pst.setString(2, "神明");
            pst.setInt(3, 123456);
            pst.setString(4, "[email protected]");
            pst.setDate(5, new java.sql.Date(new Date().getTime()));

            //执行,直接调用执行的方法
            int i = pst.executeUpdate();
            if (i > 0) {
    
    
                System.out.println("插入成功");
            }

        } catch (SQLException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
           JdbcUtils_DBCP.release(conn, pst, null);
        }
    }
}

C3P0数据库连接池

C3P0需要导入的jar包

提取链接 提取码:r9p2

编写C3P0工具类

package com.peng.cheng.lesson05.utils;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.peng.cheng.lesson02.utils.JdbcUtils;
import org.apache.commons.dbcp.BasicDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

//开源数据源连接池C3P0工具类
public class JdbcUtils_C3P0 {
    
    
    private static ComboPooledDataSource dataSource=null;

    static {
    
    //获取配置文件资源
        try {
    
    

             /*方式二;代码方式实现,不推荐使用
             dataSource = new ComboPooledDataSource();

             dataSource.setDriverClass("driver");
             dataSource.setUser("root");
             dataSource.setPassword("19990802");
             dataSource.setJdbcUrl("url");

             dataSource.setMaxPoolSize();设置最大连接池
             dataSource.setMinPoolSize();设置最小连接池
*/

            //创建数据源   方式一:以配置文件的方式
             dataSource = new ComboPooledDataSource("mysql");//不加参数使用默认的数据源,加参数则使用以参数为名的数据源
            
        } catch (Exception  e) {
    
    
            e.printStackTrace();
        }
    }

    //2.获取连接方法
    public static Connection getConnection() throws SQLException {
    
    
        return dataSource.getConnection();//从数据源中获取连接,DataSource数据源里面自带连接,DataSource接口里只有getConnection()一个获取连接方法
    }

    //释放资源
    public static void release(Connection conn, Statement st, ResultSet rs) {
    
    
        if (rs != null) {
    
    
            try {
    
    
                rs.close();
            } catch (SQLException e) {
    
    
                e.printStackTrace();
            }
        }

        if (st != null) {
    
    
            try {
    
    
                st.close();
            } catch (SQLException e) {
    
    
                e.printStackTrace();
            }
        }
        if (conn != null) {
    
    
            try {
    
    
                conn.close();
            } catch (SQLException e) {
    
    
                e.printStackTrace();
            }
        }
    }
}

配置文件(文件名:c3p0-config.xml)

<?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/jdbcstudy?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false</property>
        <property name="user">root</property>
        <property name="password">19990802</property>

        <property name="initialPoolSize">10</property>
        <property name="maxIdleTime">30</property>
        <property name="maxPoolSize">20</property>
        <property name="minPoolSize">5</property>
        <property name="maxStatements">200</property>
    </default-config>

    <named-config name="mysql">
        <property name="acquireIncrement">50</property>
        <property name="initialPoolSize">100</property>
        <property name="minPoolSize">50</property>
        <property name="maxPoolSize">1000</property><!-- intergalactoApp adopts a different approach to configuring statement caching -->
        <property name="maxStatements">0</property>
        <property name="maxStatementsPerConnection">5</property>
    </named-config>

    <named-config name="oracle">
        <property name="acquireIncrement">50</property>
        <property name="initialPoolSize">100</property>
        <property name="minPoolSize">50</property>
        <property name="maxPoolSize">1000</property><!-- intergalactoApp adopts a different approach to configuring statement caching -->
        <property name="maxStatements">0</property>
        <property name="maxStatementsPerConnection">5</property>
    </named-config>
</c3p0-config>

C3P0的用法测试

package com.peng.cheng.lesson05;

import com.peng.cheng.lesson05.utils.JdbcUtils_C3P0;
import com.peng.cheng.lesson05.utils.JdbcUtils_DBCP;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;

//测试C3P0数据源连接池
public class TestC3P0 {
    
    
    public static void main(String[] args) {
    
    
        Connection conn = null;
        PreparedStatement pst = null;

        try {
    
    
            conn = JdbcUtils_C3P0.getConnection();
            String sql = " INSERT INTO users (`id`,`NAME`,`PASSWORD`,`email`,`birthday`) VALUES(?,?,?,?,?) ";

            pst = conn.prepareStatement(sql);//传一个预编译的sql,先写SQL语句,然后不执行

            //手动给参数赋值
            pst.setInt(1, 8);
            pst.setString(2, "风起");
            pst.setInt(3, 123456);
            pst.setString(4, "[email protected]");
            pst.setDate(5, new java.sql.Date(new Date().getTime()));


            int i = pst.executeUpdate();
            if (i > 0) {
    
    
                System.out.println("插入成功");
            }

        } catch (SQLException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            JdbcUtils_C3P0.release(conn, pst, null);
        }

    }
}

总结:无论使用什么数据源,本质是一样的,因为DateSource接口不会变,所以接口里的方法(getConnection();)就不会变

c3p0与dbcp的区别

dbcp没有自动回收空闲连接的功能

c3p0有自动回收空闲连接功能

猜你喜欢

转载自blog.csdn.net/wpc2018/article/details/109266820