【学习笔记】数据库连接池

数据库连接池

数据库的连接,执行到释放,过程十分浪费系统资源

所以出现了一种技术叫做:池化技术

池化技术:准备一些预先的资源,过来就连接预先准备好的资源

最小连接数:根据业务来调整,常用连接数在100个左右,最小连接数为100即可

最大连接数:业务最高承载上限

超过了最大连接数就需要排队等待,等别人用完,才能再去使用

等待超时:如果一个业务等待的时间超过某个时间,就不让他等待了,自动结束

 

编写连接池,只需要实现一个接口:DataSource

 

目前比较知名的实现类:开源数据源实现

  • DBCP

  • C3P0

  • Druid 阿里巴巴

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

 

DBCP

需要导入的jar包:

commons-dbcp-1.4.jar 、commons-pool-1.6.jar

 

  • 新建配置文件 dbcp.properties

    driverClassName=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true
    username=root
    password=123456
    ​
    #<!-- 初始化连接 -->
    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-only)状态。
    #如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
    defaultReadOnly=
    ​
    #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
    #可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
    defaultTransactionIsolation=READ_UNCOMMITTED

 

  • 编写dbcp工具类

    package com.lesson05.utils;
    ​
    import org.apache.commons.dbcp.BasicDataSourceFactory;
    ​
    import javax.sql.DataSource;
    import java.io.InputStream;
    import java.sql.*;
    import java.util.Properties;
    ​
    public class JdbcUtils_DBCP {
        private static DataSource dataSource = null;
    ​
       static{
           try{
               //读取配置文件
               InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcp.properties");
               Properties properties = new Properties();
               properties.load(in);
               //创建数据源  使用工厂模式
               dataSource = BasicDataSourceFactory.createDataSource(properties);
    ​
           } catch (Exception e) {
               e.printStackTrace();
           }
       }
       //获取连接
        public static Connection getConnection() throws SQLException {
            return dataSource.getConnection();   //从数据源中获取连接
        }
    ​
        //关闭连接
        public static void release(Connection conn, Statement st, ResultSet rs) throws SQLException {
           if (rs != null){
               rs.close();
           }
           if (st != null){
               st.close();
           }
           if (rs != null){
               rs.close();
           }
        }
    }

与之前的区别就是,不用自己创建连接,直接从数据源中获取连接

使用工厂模式创建数据源,从配置文件中获得数据库的信息

 

  • 测试

    package com.lesson05;
    ​
    import com.lesson02.utils.JdbcUtils;
    import com.lesson05.utils.JdbcUtils_DBCP;
    ​
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import java.util.Date;
    ​
    public class TestDbcp {
        public static void main(String[] args) throws SQLException {
            Connection connection = JdbcUtils_DBCP.getConnection();
            //使用 ? 占位符 代替参数
            String sql = "insert into users(`id`,`NAME`,`PASSWORD`,`email`,`birthday`)values (?,?,?,?,?)";
            //先预编译sql
            PreparedStatement ps = connection.prepareStatement(sql);
            //手动给参数赋值
            ps.setInt(1,5);  //第一个参数是表示第几个占位符即第几个? 第二个参数是具体的值
            ps.setString(2,"xiaohong");
            ps.setString(3,"123561");
            ps.setString(4,"123456@123.com");
            ps.setDate(5,new java.sql.Date(new Date().getTime()));
    ​
            int i = ps.executeUpdate();
            if (i>0){
                System.out.println("插入成功");
            }
            JdbcUtils_DBCP.release(connection,ps,null);
        }
    }

     

 

 

C3P0

需要导入的jar包:

c3p0-0.9.5.5.jar、mchange-commons-java-0.2.19.jar

 

  • 配置文件 c3p0config.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <c3p0-config>
        <!--
        c3p0的缺省(默认)配置
        如果在代码中ComboPooledDataSource ds=new ComboPooledDataSource();这样写就表示使用的是c3p0的缺省(默认)
        -->
        <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&amp;serverTimezone=UTC</property>
            <property name="user">root</property>
            <property name="password">123456</property>
            <property name="acquiredIncrement">5</property>
            <property name="initialPoolSize">10</property>
            <property name="minPoolSize">5</property>
            <property name="maxPoolSize">20</property>
        </default-config>
    ​
        <!--
        c3p0的命名配置
        如果在代码中ComboPooledDataSource ds=new ComboPooledDataSource("MySQL");这样写就表示使用的是name是MySQL
        -->
        <name-config name="MySQL">
            <property name="driverClass">com.mysql.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=UTC</property>
            <property name="user">root</property>
            <property name="password">123456</property>
            <property name="acquiredIncrement">5</property>
            <property name="initialPoolSize">10</property>
            <property name="minPoolSize">5</property>
            <property name="maxPoolSize">20</property>
        </name-config>
    </c3p0-config>

    它里面的有两个方法,一个有参数,一个没有参数,调用时,带参数就执行上面的那个,不带参数就执行下面那个。

     

  • c3p0工具类

    package com.lesson05.utils;
    ​
    import com.mchange.v2.c3p0.ComboPooledDataSource;
    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 JdbcUtils_C3P0 {
        private static DataSource dataSource = null;
    ​
       static{
           try{
               //第一种写法读取配置文件
              dataSource = new ComboPooledDataSource("MySQL");
    ​
              //第二种写法 代码版配置
    //           dataSource = new ComboPooledDataSource();
    //           dataSource.setDriverClass();
    //           dataSource.setUser();
    ​
    ​
           } catch (Exception e) {
               e.printStackTrace();
           }
       }
       //获取连接
        public static Connection getConnection() throws SQLException {
            return dataSource.getConnection();   //从数据源中获取连接
        }
    ​
        //关闭连接
        public static void release(Connection conn, Statement st, ResultSet rs) throws SQLException {
           if (rs != null){
               rs.close();
           }
           if (st != null){
               st.close();
           }
           if (rs != null){
               rs.close();
           }
        }
    }

 

测试与上面相同,只是把工具类的名字改一下就好。

 

无论用什么数据源,本质还是一样的,DataSource接口不变,方法就不会变

posted @ 2022-10-06 17:22  GrowthRoad  阅读(41)  评论(0编辑  收藏  举报