连接池与JDBC连接池进阶使用

连接池与JDBC连接池进阶使用

阿里巴巴Druid连接池

  • Druid是阿里巴巴开源连接池组件,是最好的连接池组件之一
  • Druid对数据库连接进行有效管理与重用,最大化程序执行效率
  • 连接池负责创建管理连接,程序只负责取用与归还
  • 结合了C3P0、DBCP、Proxool等DB池的优点
  • 加入了日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针对监控而生的DB连接池

Druid连接池配置与使用

配置:

  1. 导入druid的jar包

  2. 在src下创建对应的配置文件,配置连接参数

    • 详细配置
    配置缺省说明
    name配置这个属性的意义在于,如果存在多个数据源,监控的时候可以通过名字来区分开来。 如果没有配置,将会生成一个名字,格式是:”DataSource-” + System.identityHashCode(this)
    url*连接数据库的url,不同数据库不一样。例如:mysql : jdbc:mysql://10.20.153.104:3306/druid2 oracle : jdbc:oracle:thin:@10.20.149.85:1521:ocnauto
    username*连接数据库的用户名
    password*连接数据库的密码。如果你不希望密码直接写在配置文件中,可以使用ConfigFilter。详细看这里:https://github.com/alibaba/druid/wiki/使用ConfigFilter
    driverClassName*根据url自动识别 这一项可配可不配,如果不配置druid会根据url自动识别dbType,然后选择相应的driverClassName(建议配置下)
    initialSize0初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
    maxActive8最大连接池数量
    maxIdle8已经不再使用,配置了也没效果
    minIdle最小连接池数量
    maxWait获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
    poolPreparedStatementsfalse是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
    maxOpenPreparedStatements-1要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
    validationQuery用来检测连接是否有效的sql,要求是一个查询语句。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会其作用。
    testOnBorrowtrue申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
    testOnReturnfalse归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
    testWhileIdlefalse建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
    timeBetweenEvictionRunsMillis有两个含义: 1)Destroy线程会检测连接的间隔时间2)testWhileIdle的判断依据,详细看testWhileIdle属性的说明
    numTestsPerEvictionRun不再使用,一个DruidDataSource只支持一个EvictionRun
    minEvictableIdleTimeMillis
    connectionInitSqls物理连接初始化的时候执行的sql
    exceptionSorter根据dbType自动识别 当数据库抛出一些不可恢复的异常时,抛弃连接
    filters属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有: 监控统计用的filter:stat日志用的filter:log4j防御sql注入的filter:wall
    proxyFilters类型是List,如果同时配置了filters和proxyFilters,是组合关系,并非替换关系

使用:

  1. 加载配置文件
  2. 获取DateSource数据源对象
  3. 获取数据库连接

代码案例:

  1. druid-config.properties

    #配置必要信息
    driverClassName=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql://localhost:3306/imooc?useSSL=false&useUnicode=true&charsetEncoding=utf-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
    username=root
    password=root
    
    #初始化数据库连接配置
    initialSize=10
    maxActive=20
    
  2. DruidSample.java

    package com.imooc.jdbc.sample;
    
    import com.alibaba.druid.pool.DruidDataSourceFactory;
    import com.imooc.jdbc.goodapp.common.DBUtils;
    import com.mysql.cj.DataStoreMetadata;
    
    import javax.sql.DataSource;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.net.URLDecoder;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.util.Properties;
    
    /**
     * Druid连接池配置与使用
     * @author CubeMonkey
     * @create 2020-10-12 16:58
     */
    public class DruidSample {
        public static void main(String[] args) {
            //1.加载属性文件
            Properties properties = new Properties();
            String propertiesFile = DruidSample.class.getResource("/druid-config.properties").getPath();
            //空格->%20 \c:\java code\druid-config.properties
            //c:\java%20code\druid-config.properties
            try {
                propertiesFile = new URLDecoder().decode(propertiesFile, "utf-8");
                properties.load(new FileInputStream(propertiesFile));
            } catch (Exception e) {
                e.printStackTrace();
            }
            Connection conn = null;
            PreparedStatement pstmt = null;
            ResultSet rs = null;
            try {
                //2.获取DataSource数据源对象
                DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
                //3.创建数据库连接
                conn = dataSource.getConnection();
                pstmt = conn.prepareStatement("select * from employee limit 0, 10");
                rs = pstmt.executeQuery();
                while(rs.next()){
                    int eno = rs.getInt("eno");
                    String ename = rs.getString("ename");
                    float salary = rs.getFloat("salary");
                    String dname = rs.getString("dname");
                    System.out.println(dname + "-" + eno + "-" + ename + "-" +salary);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                DBUtils.closeConnection(rs, pstmt, conn);
            }
    
        }
    }
    
    

Tip

  1. 用getResource().realPath(), 可以动态的获取文件的真实路径
  2. 获取的文件路径格式为URL编码,需要用Decoder类的decoder(fileName, ‘utf-8’)方法处理中文字符的编码问题(如:’ '->%20),以此类推,有关URL编码的地址,为防止中文乱码,都要用Decoder类的decoder(fileName, ‘utf-8’)方法处理。
  3. 在一般情况下,配置initalSize和maxActive时,值都是一样的,让应用程序在一开始就创建好所有的连接,避免在使用时再创建连接

C3P0连接池使用:

配置:

  1. 导入mchange通用包->mchange-commons-java的jar包和c3p0的jar包
  2. 创建c3p0-config.xml文件,配置数据库连接的信息和数据库连接池的信息

使用:

  1. 加载配置文件
  2. 获取DateSource数据源对象
  3. 获取数据库连接

代码案例:

c3p0-config.xml
<?xml version="1.0" encoding="utf-8"?>
<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/imooc?useSSL=false&amp;useUnicode=true&amp;charsetEncoding=utf-8&amp;serverTimezone=Asia/Shanghai&amp;allowPublicKeyRetrieval=true</property>
        <property name="user">root</property>
        <property name="password">root</property>
        <!--连接池初始连接数量-->
        <property name="initialPoolSize">10</property>
        <!--最大连接数-->
        <property name="maxPoolSize">20</property>
    </default-config>
</c3p0-config>
C3P0Sample.java
package com.imooc.jdbc.sample;

import com.imooc.jdbc.goodapp.common.DBUtils;
import com.mchange.v2.c3p0.ComboPooledDataSource;

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

/**
 * @author CubeMonkey
 * @create 2020-10-13 10:54
 */
public class C3P0Sample {
    public static void main(String[] args) {
        //1.加载配置文件
        //2.创建DataSource数据源
        DataSource dataSource = new ComboPooledDataSource();
        //3.得到数据库连接
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = dataSource.getConnection();
            pstmt = conn.prepareStatement("select * from employee");
            rs = pstmt.executeQuery();
            while (rs.next()){
                int eno = rs.getInt("eno");
                String ename = rs.getString("ename");
                float salary = rs.getFloat("salary");
                String dname = rs.getString("dname");
                System.out.println(dname + "-" + eno + "-" + ename + "-" +salary);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            DBUtils.closeConnection(rs, pstmt, conn);
        }

    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rex·Lin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值