zoukankan      html  css  js  c++  java
  • DBCP数据库连接池初探

    1、 概述

    数据库连接是很“宝贵的”,如果每次获取Connection都去创建数据库连接,使用之后就断开,再次使用又重新创建,程序效率是很低的。因为Socket连接的建立很消耗资源。

    所以需要数据库连接池,数据库连接池也被称为数据源即DataSourceJAVA中为了使用者更加规范的编写数据源类,定义了java.sql.DataSource接口,如果我们要编写自己的连接池,就要实现这个接口。

    程序通过连接池预先同数据库建立一些连接,放在内存中,需要数据库连接时直接到连接池中取一个就行,用完后再放回去。

    该接口声明了两个获取数据库连接的方法

    1 public interface DataSource  extends CommonDataSource, Wrapper {
    2 
    3     Connection getConnection() throws SQLException;
    4 
    5     Connection getConnection(String username, String password) throws SQLException;
    6 }

    2、DBCP 数据源概述

    DBCP(DataBase Connection Pool)Apache开发,可以让程序自动管理数据库连接的释放和断开。

    需要使用的jar包:commons-dbcp-1.4.jar、commons-pool-1.5.4.jar、commons-logging-1.0.4.jar、commons-collections-3.1.jar

    重要的配置参数:

    driverClassName 数据库驱动
    url 数据库连接url
    username 数据库连接用户名
    password 数据库连接密码
    initialSize 初始连接数量
    maxActive 最大活跃连接数量
    maxIdle 最大空闲连接数量
    minIdle 最小空闲连接数量
    maxWaitMillis 在抛出异常之前等待的最大毫秒数(当没有可用的连接时),默认-1无限期地等待
    validationQuery 验证连接时使用的SQL
    testOnCreate 连接创建时验证
    testOnBorrow 连接获取时验证
    testOnReturn 连接归还时验证
    testWhileIdle 是否验证空闲连接,默认false不验证。 如果一个对象无法验证,将从池中删除
    timeBetweenEvictionRunsMillis 运行空闲对象删除线程的时间间隔,单位为毫秒,默认为-1即不执行任务
    numTestsPerEvictionRun 空闲对象删除线程每次运行时检查的对象数量(如果有的话),默认3个
    minEvictableIdleTimeMillis 在空闲对象删除线程可以删除连接之前,连接可以在池中空闲的最少时间(如果有的话),默认1000 * 60 * 30
    maxConnLifetimeMillis 连接的最长寿命(以毫秒为单位)。超过此时间后,连接将在下一次激活、钝化或验证测试时失败。0或更小意味着连接具有无限寿命
    removeAbandonedTimeout Timeout in seconds before an abandoned connection can be removed

    3、 设计思路

    1)    在jdbc.properties文件配置数据源实现类类型,以及该数据源的属性信息;

    2)    在DBUtil工具类中解析配置文件,获取到使用的数据源类型,并通过反射实例化;

    3)    使用beanutils框架给实例化的数据源对象注入属性,需要使用到commons-beanutils-1.9.3.jar框架;

    4)    修改getConnection方法从数据源获取连接

    之所以这样做,是为了程序代码和具体数据源实现类的解耦,当不再使用DBCP改用C3P0时,我们可以通过修改jdbc.properties配置文件而不再需要修改程序代码。

    4、 配置 jdbc.properties

    ##### DBCP Configuration #####
    
    dataSourceClassName=org.apache.commons.dbcp.BasicDataSource
    
    driverClassName=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false
    
    username=system
    password=123456
    
    initialSize=1
    maxActive=10
    maxIdle=5
    minIdle=2
    
    maxWaitMillis=-1
    validationQuery=select 1
    testWhileIdle=true
    timeBetweenEvictionRunsMillis=60000
    numTestsPerEvictionRun=3
    minEvictableIdleTimeMillis=60000
    softMinEvictableIdleTimeMillis=60000
    maxConnLifetimeMillis=300000
    removeAbandonedTimeout=300

    5、DBUtil 工具类

     1 public class DBUtil {
     2 
     3     /**
     4      * 数据源对象
     5      */
     6     private static DataSource ds;
     7 
     8     private static Properties prop = new Properties();
     9 
    10     static {
    11         try {
    12             // 读取加载jdbc配置文件
    13             prop.load(DBUtil.class.getClassLoader().getResourceAsStream(
    14                     "jdbc.properties"));
    15 
    16             // 获取数据源实现类类型
    17             String dataSourceClassName = prop
    18                     .getProperty("dataSourceClassName");
    19 
    20             // 实例化数据源实现类
    21             Class<?> clazz = Class.forName(dataSourceClassName);
    22             ds = (DataSource) clazz.newInstance();
    23 
    24             prop.remove("dataSourceClassName");
    25 
    26             // 为数据源注入属性
    27             Map<String, Object> p = new HashMap<String, Object>();
    28             for (Object key : prop.keySet()) {
    29                 p.put(key.toString(), prop.get(key));
    30             }
    31             BeanUtils.populate(ds, p);
    32 
    33         } catch (IOException e) {
    34             throw new RuntimeException("加载JDBC配置失败", e);
    35         } catch (ClassNotFoundException e) {
    36             throw new RuntimeException("数据源实现类未找到", e);
    37         } catch (InstantiationException e) {
    38             throw new RuntimeException("创建数据源实现类对象失败", e);
    39         } catch (IllegalAccessException e) {
    40             throw new RuntimeException("创建数据源实现类对象失败", e);
    41         } catch (InvocationTargetException e) {
    42             throw new RuntimeException("数据源属性注入时失败", e);
    43         }
    44     }
    45 
    46     /**
    47      * 从数据源中获取一个数据库连接
    48      * 
    49      * @return 数据库连接
    50      * @throws SQLException
    51      */
    52     public static Connection getConnection() throws SQLException {
    53         return ds.getConnection();
    54     }
    55 }
  • 相关阅读:
    轻松处理高于平常10倍的视频需求,还能节省60%的IT成本,蓝墨做对了什么?
    支付宝研究员王益的建议:“学好语文,才能写好代码”
    Flutter+FaaS一体化任务编排的思考与设计
    开放下载!《大促背后的前端核心业务实践》
    揭秘!信息检索技术高端玩法
    秒懂云通信:如何用阿里云语音通知服务(小白指南)
    卡顿人生,如何拯救?
    阿里云荣获可信云容器安全能力先进级认证, ACK/ACR为企业级安全护航
    飞天大数据产品价值解读— SaaS模式云数据仓库MaxCompute
    阿里产品专家:高情商的技术人,如何做沟通?
  • 原文地址:https://www.cnblogs.com/xugf/p/9258373.html
Copyright © 2011-2022 走看看