欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JDBC——连接池概念、DBCP、c3p0、Druid及其工具类

程序员文章站 2022-05-24 12:30:30
...

目录

JDBC连接池

数据库连接池的概念

跳转到目录
其实就是一个容器(集合),存放数据库连接的容器。当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。
为什么存在数据库连接池: 因为与数据库建立连接底层是向操作系统申请的资源,由于每次申请连接资源后,我们就把资源给释放了. 下次需要操作数据库又需要去申请,这个操作是比较耗时的,所以就出现了数据库连接池的技术。
优点:节约资源、用户访问高效

数据库连接池的实现

跳转到目录

  • 实现接口
    DataSource javax.sql包下的接口
    方法
    getConnection()获取连接
    Connection.close()归还连接

    一般我们不去实现DataSource,又提供数据库的厂商来实现。

DBCP连接池

跳转到目录
使用步骤:
1. 导入jar包(两个) commons-dbcp-1.4.jarcommons-pool-1.5.6.jar
JDBC——连接池概念、DBCP、c3p0、Druid及其工具类

DBCP工具类

跳转到目录

package com.sunny.utils;

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;

public class DBCPUtil {
    private static Properties p = new Properties();
    private static DataSource ds;

    static {
        try {
            // 从classpath的根路径下去寻找dbcp.properties文件
            InputStream inputStream = Thread.currentThread().
                    getContextClassLoader().getResourceAsStream("dbcp.properties");
            p.load(inputStream);
            ds = BasicDataSourceFactory.createDataSource(p);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取连接的方法
     *
     * @return
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

    /**
     * 获取连接池的方法
     *
     * @return
     */
    public static DataSource getDataSource() {
        return ds;
    }

    /**
     * 释放资源
     *
     * @param stmt
     * @param conn
     */
    public static void close(Statement stmt, Connection conn) {
        close(null, stmt, conn);
    }

    /**
     * 释放资源
     *
     * @param rs
     * @param stmt
     * @param conn
     */
    public static void close(ResultSet rs, Statement stmt, Connection conn) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (stmt != null) {
            try {
                stmt.close();   // 归还连接
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (conn != null) {
            try {
                conn.close();   // 归还连接
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

  • DBCPTest
package com.sunny.datasource.DBCP;

import com.sunny.utils.DBCPUtil;
import org.junit.Test;

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

public class DBCPTest1 {

    // 查询zy数据库中emp表中员工的姓名和工资
    @Test
    public void testQueryEmp() throws SQLException {
        String sql = "SELECT * FROM emp";
        Connection conn = DBCPUtil.getConnection();
        PreparedStatement ps = conn.prepareStatement(sql);
        ResultSet rs = ps.executeQuery();
        while (rs.next()){
            long id = rs.getLong("id");
            String ename = rs.getString("ename");
            double salary = rs.getDouble("salary");
            System.out.println(id+"\t"+ename+"\t"+salary);
        }
        DBCPUtil.close(rs, ps, conn);
    }
}

c3p0连接池

跳转到目录
使用步骤:
1. 导入jar包(两个) c3p0-0.9.5.2.jarmchange-commons-java-0.2.12.jar
2. 定义配置文件 c3p0.properties 或者 c3p0-config.xml直接放在src目录下
3. 创建数据库连接池对象 ComboPooledDataSource
4. 获取连接 getConnection

/*
    c3p0演示
 */
public class C3P0Demo1 {
    public static void main(String[] args) throws SQLException {
        //1. 创建数据库连接池对象,可以使用默认配置,也可以使用指定配置
        //DataSource ds = new ComboPooledDataSource();
        DataSource ds = new ComboPooledDataSource("otherc3p0");
        //2. 获取连接对象
        Connection conn = ds.getConnection();
        //3. 打印
        System.out.println(conn);
    }
}

c3p0-config.xml 使用此名字会自动加载该配置文件

<c3p0-config>
  <!-- 使用默认的配置读取连接池对象 -->
  <default-config>
  	<!--  连接参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/db</property>
    <property name="user">root</property>
    <property name="password">1111</property>
    
    <!-- 连接池参数 -->
    <!-- 初始化申请的连接池对象 -->
    <property name="initialPoolSize">5</property>
    <!-- 最大的连接数量 -->
    <property name="maxPoolSize">10</property>
    <!-- 超时时间 -->
    <property name="checkoutTimeout">3000</property>
  </default-config>

  <!-- 使用otherc3p0的配置 -->
  <named-config name="otherc3p0"> 
    <!--  连接参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/db</property>
    <property name="user">root</property>
    <property name="password">1111</property>
    
    <!-- 连接池参数 -->
    <property name="initialPoolSize">5</property>
    <property name="maxPoolSize">8</property>
    <property name="checkoutTimeout">1000</property>
  </named-config>
</c3p0-config>

除了这种XML的配置文件外,还有.properties文件.

C3P0连接池工具类

import com.mchange.v2.c3p0.ComboPooledDataSource;

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

public class C3P0Util {

    // 创建C3P0连接池对象,内部村粗了多个Connection对象
    // 创建对象时,会自动读取src根目录下的配置文件
    private static ComboPooledDataSource cpds = new ComboPooledDataSource();

    // 私有化构造器
    private  C3P0Util(){

    }

    // 定义静态方法,获取Connection对象
    public static Connection getConnection() throws Exception{
        return cpds.getConnection();
    }

    /**
     * 获取连接池的方法
     * @return
     */
    public static DataSource getDataSource(){
        return cpds;
    }

    public static void close(Statement stmt, Connection conn){
        close(null, stmt, conn);
    }

    /**
     * 释放资源
     * @param rs
     * @param stmt
     * @param conn
     */
    public static void close(ResultSet rs, Statement stmt, Connection conn){
        if (rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (stmt != null){
            try {
                stmt.close();   // 归还连接
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (conn != null){
            try {
                conn.close();   // 归还连接
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

Druid

跳转到目录

使用步骤:
1. 导入jar包 druid-1.0.9.jar
2. 定义配置文件是properties文件,可以叫任意名称,可以放在任意目录下
3. 加载配置文件properties
4. 获取数据库连接池对象,通过工厂类来获取DruidDataSourceFactory
5. 获取连接 getConnection

/*
    druid演示
 */
public class DruidDemo {
    public static void main(String[] args) throws Exception {
        //1. 导入jar包
        //2. 定义配置文件
        //3. 加载配置文件
        Properties pro = new Properties();
        InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
        pro.load(is);
        //4. 获取连接池对象
        DataSource ds = DruidDataSourceFactory.createDataSource(pro);
        //5. 获取连接
        Connection conn = ds.getConnection();
        System.out.println(conn);
    }
}

Druid连接池工具类

跳转到目录

/**
 * Druid连接池工具类
 */
public class JDBCUtils {

    //1. 定义成员变量DataSource
    private static DataSource ds;

    static{
        try {
            //1. 加载配置文件
            Properties pro = new Properties();
            pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
            //2. 获取连接池DataSource对象
            ds = DruidDataSourceFactory.createDataSource(pro);

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


    /**
     * 获取连接的方法
     * @return
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException{
        return ds.getConnection();
    }

    /**
     * 获取连接池的方法
     * @return
     */
    public static DataSource getDataSource(){
        return ds;
    }

    /**
     * 释放资源
     * @param stmt
     * @param conn
     */
    public static void close(Statement stmt, Connection conn){
        close(null, stmt, conn);
    }

    /**
     * 释放资源
     * @param rs
     * @param stmt
     * @param conn
     */
    public static void close(ResultSet rs, Statement stmt, Connection conn){
        if (rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (stmt != null){
            try {
                stmt.close();   // 归还连接
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (conn != null){
            try {
                conn.close();   // 归还连接
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

使用Druid工具类完成对关系表添加一条记录操作:

/**
 * 使用新工具类, 做一个添加的操作
 */
public class DruidDemo2 {

    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        // 给account表添加一条记录
        try {
            //1. 获取连接
            conn = JDBCUtils.getConnection();
            //2. 定义sql
            String sql = "INSERT INTO account values(null, ?, ?)";
            //3. 获取pstmt对象
            pstmt = conn.prepareStatement(sql);
            //4. 给?赋值
            pstmt.setString(1, "朝阳");
            pstmt.setDouble(2, 3000);
            //5. 执行sql语句
            int count = pstmt.executeUpdate();
            System.out.println(count);

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 释放资源
            JDBCUtils.close(pstmt, conn);
        }
    }
}