• 数据库连接池技术--C3P0、DBCP、druid


    • DBCP 是Apache提供的数据库连接池。tomcat 服务器自带dbcp数据库连接池。速度相对c3p0较快,但因自身存在BUG,Hibernate3已不再提供支持。

    • C3P0 是一个开源组织提供的一个数据库连接池,速度相对较慢,稳定性还可以。hibernate官方推荐使用

    • Druid 是阿里提供的数据库连接池,据说是集DBCP 、C3P0 、Proxool 优点于一身的数据库连接池,但是速度不确定是否有BoneCP快

    C3P0技术

      导包操作:c3p0-0.9.1.2.jar

      查看说明文档:

     实现的方式一:硬编码的形式

     1 @Test
     2     public void testGetConnection() throws Exception {
     3         // 获取数据库连接池的实例化对象
     4         ComboPooledDataSource cpds = new ComboPooledDataSource() ;
     5         
     6         // 设置连接需要的基本信息
     7         cpds.setDriverClass("com.mysql.cj.jdbc.Driver");
     8         cpds.setJdbcUrl("jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8");
     9         cpds.setUser("root");
    10         cpds.setPassword("password");
    11         // 设置与管理数据库连接池相关的属性
    12         // 设置连接池中初始连接的数量
    13         cpds.setInitialPoolSize(10);
    14         
    15         // 获取数据库连接
    16         Connection conn = cpds.getConnection() ;
    17         System.out.println(conn);
    18     }

    实现的方式二:配置文件的方式

      配置文件:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <c3p0-config>
     3     <named-config name="myc3p0">
     4             <!-- 提供用于获取连接的基本信息 -->
     5         <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
     6         <property name="jdbcUrl">jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8</property>
     7             <!-- 主机号与端口号为本机3306时,可以省略:即jdbc:mysql:///test?serverTimezone=GMT%2B8 -->
     8         <property name="user">root</property>
     9         <property name="password">password</property>
    10     
    11             <!-- 管理数据库连接池的基本信息 -->
    12             <!-- 当数据库连接池的连接不够时,c3p0 一次性向数据库服务器申请的连接数 -->
    13         <property name="acquireIncrement">5</property>
    14             <!-- c3p0数据库连接池中初始化时的连接数 -->
    15         <property name="initialPoolSize">10</property>
    16         
    17             <!-- c3p0数据库连接池中维护的最少连接数 -->
    18         <property name="minPoolSize">10</property>
    19             <!-- c3p0数据库连接池中维护的最多连接数 -->
    20         <property name="maxPoolSize">100</property>
    21         
    22             <!-- c3p0数据库连接池中最多维护的Statement的个数 -->
    23         <property name="maxStatements">50</property>
    24             <!-- 每个连接中最多可以使用的Statement的个数 -->
    25         <property name="maxStatementsPerConnection">2</property>
    26     </named-config>
    27 </c3p0-config>

    说明:

      1. 配置文件的名称要求必须为 “c3p0-config.xml”  ;

      2. 第 3 行的 <named-config name="myc3p0"> 主要用于设置该配置文件的名称 ;

      3. 提供用于获取连接的基本信息的 “name” 可以参考方式一中的方法名,注意不能出现错误。

    1 @Test
    2     public void testGetConnection2() throws Exception {
    3         // 实例化数据库连接池的对象并传入配置文件
    4         ComboPooledDataSource cpds = new ComboPooledDataSource("myc3p0");
    5         // 获取数据库连接
    6         Connection conn = cpds.getConnection() ;
    7         System.out.println("myc3p0:" + conn);
    8 }

    DBCP数据连接池技术:

      导包操作:commons-dbcp-1.4.jar、commons-pool-1.5.5.jar

      查看说明文档:

    方式一:

     1 @Test
     2     public void testGetConnection() throws Exception {
     3         // 获取DBCP数据库连接池的实例化对象
     4         BasicDataSource bds = new BasicDataSource() ;
     5         
     6         // 设置连接需要的基本信息
     7         bds.setDriverClassName("com.mysql.cj.jdbc.Driver");
     8         bds.setUrl("jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8");
     9         bds.setUsername("root");
    10         bds.setPassword("password");
    11         // 设置其他与数据库连接池管理的相关信属性
    12         bds.setInitialSize(10);
    13         
    14         // 获取数据库连接
    15         Connection conn = bds.getConnection() ;
    16         System.out.println(conn);
    17     }

    dbcp连接池常用基本配置属性:

    属性默认值说明
    initialSize 0 连接池启动时创建的初始化连接数量
    maxActive 8 连接池中可同时连接的最大的连接数
    maxIdle 8 连接池中最大的空闲的连接数,超过的空闲连接将被释放,如果设置为负数表示不限制
    minIdle 0 连接池中最小的空闲的连接数,低于这个数量会被创建新的连接。该参数越接近maxIdle,性能越好,因为连接的创建和销毁,都是需要消耗资源的;但是不能太大。
    maxWait 无限制 最大等待时间,当没有可用连接时,连接池等待连接释放的最大时间,超过该时间限制会抛出异常,如果设置-1表示无限等待
    poolPreparedStatements false 开启池的Statement是否prepared
    maxOpenPreparedStatements 无限制 开启池的prepared 后的同时最大连接数
    minEvictableIdleTimeMillis   连接池中连接,在时间段内一直空闲, 被逐出连接池的时间
    removeAbandonedTimeout 300 超过时间限制,回收没有用(废弃)的连接
    removeAbandoned false 超过removeAbandonedTimeout时间后,是否进 行没用连接(废弃)的回收

    方式二:使用配置文件:

    配置文件如下:

    1 driverClassName=com.mysql.cj.jdbc.Driver
    2 url=jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8
    3 username=root
    4 password=password
     1     @Test
     2     public void testGetConnection2() throws Exception{
     3 //        方式一:使用类的加载器
     4 //        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("dbcp.properties");
     5 //        方式二:普通的文件流(当前工程下)
     6         FileInputStream is = new FileInputStream(new File("src/dbcp.properties")) ;
     7         Properties pros = new Properties() ;
     8         pros.load(is) ;
     9         DataSource ds = BasicDataSourceFactory.createDataSource(pros) ;
    10         
    11         Connection conn = ds.getConnection() ;
    12         System.out.println(conn);
    13     }

    Druid数据库连接池技术:

      配置文件的方式:

    1 driverClassName=com.mysql.cj.jdbc.Driver
    2 url=jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8
    3 username=root
    4 password=password
    1 @Test
    2     public void testGetConnection() throws Exception {
    3         InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties") ;
    4         Properties pros = new Properties() ;
    5         pros.load(is);
    6         DataSource ds = DruidDataSourceFactory.createDataSource(pros) ;
    7         Connection conn = ds.getConnection() ;
    8         System.out.println(conn);
    9     }

    详细配置参数

    配置缺省说明
    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。
    driverClassName   根据url自动识别 这一项可配可不配,如果不配置druid会根据url自动识别dbType,然后选择相应的driverClassName(建议配置下)
    initialSize 0 初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
    maxActive 8 最大连接池数量
    maxIdle 8 已经不再使用,配置了也没效果
    minIdle   最小连接池数量
    maxWait   获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
    poolPreparedStatements false 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
    maxOpenPreparedStatements -1 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
    validationQuery   用来检测连接是否有效的sql,要求是一个查询语句。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会其作用。
    testOnBorrow true 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
    testOnReturn false 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
    testWhileIdle false 建议配置为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,是组合关系,并非替换关系

    总结:利用以上三种数据库连接池技术实现数据库的工具类"JDBCUtil“

      1 package edu.cn.ahpu4.util;
      2 
      3 import java.io.InputStream;
      4 import java.sql.Connection;
      5 import java.sql.ResultSet;
      6 import java.sql.SQLException;
      7 import java.sql.Statement;
      8 import java.util.Properties;
      9 import javax.sql.DataSource;
     10 import org.apache.commons.dbcp.BasicDataSourceFactory;
     11 import com.alibaba.druid.pool.DruidDataSourceFactory;
     12 import com.mchange.v2.c3p0.ComboPooledDataSource;
     13 
     14 /**
     15  * 
     16  * @Description 操作数据库的工具类
     17  * @author XiaoFeng Email:1431230065@qq.com
     18  * @version
     19  * @date 2020年8月20日下午4:02:59
     20  *
     21  */
     22 public class JDBCUtil {
     23 
     24     /***
     25      * 
     26      * @Description 使用C3P0技术获取数据库连接
     27      * @author XiaoFeng
     28      * @date 2020年8月20日下午4:12:17
     29      * @return 数据库连接
     30      * @throws SQLException 
     31      */
     32     // 实例化数据库连接池的对象并传入配置文件
     33     private static ComboPooledDataSource cpds = new ComboPooledDataSource("myc3p0");
     34     public static Connection getConnection1() throws SQLException {
     35         // 获取并返回数据库连接
     36         return cpds.getConnection() ;
     37     }
     38     
     39     /***
     40      * 
     41      * @Description    使用DBCP技术获取数据库连接
     42      * @author XiaoFeng  
     43      * @date 2020年8月26日上午11:16:47  
     44      * @return
     45      * @throws Exception
     46      */
     47     private static DataSource ds2 ;
     48     static {
     49         try {
     50             InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("dbcp.properties");
     51             Properties pros = new Properties() ;
     52             pros.load(is) ;
     53             // 创建一个DBCP数据库连接池
     54             ds2 = BasicDataSourceFactory.createDataSource(pros) ;
     55         } catch (Exception e) {
     56             e.printStackTrace();
     57         }
     58     }
     59     public static Connection testGetConnection2() throws Exception{
     60         Connection conn = ds2.getConnection() ;
     61         return conn ;
     62     }
     63 
     64     /***
     65      * 
     66      * @Description    使用druid技术获取数据库连接
     67      * @author XiaoFeng  
     68      * @date 2020年8月26日上午11:38:41  
     69      * @return
     70      * @throws Exception
     71      */
     72     private static DataSource ds3 ;
     73     static {
     74         try {
     75             InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties") ;
     76             Properties pros = new Properties() ;
     77             pros.load(is);
     78             ds3 = DruidDataSourceFactory.createDataSource(pros) ;
     79         } catch (Exception e) {
     80             e.printStackTrace();
     81         }
     82     }
     83     public static Connection testGetConnection3() throws SQLException{
     84         Connection conn = ds3.getConnection() ;
     85         return conn ;
     86     }
     87     
     88     /***
     89      * 
     90      * @Description    关闭资源
     91      * @author XiaoFeng  
     92      * @date 2020年8月20日下午4:15:35  
     93      * @param conn    connection资源
     94      * @param ps PreparedStatement资源
     95      */
     96     public static void closeResource(Connection conn,Statement ps) {
     97         if (ps != null) {
     98             try {
     99                 ps.close();
    100             } catch (SQLException e) {
    101                 e.printStackTrace();
    102             }
    103         }
    104         if (conn != null) {
    105             try {
    106                 conn.close();
    107             } catch (SQLException e) {
    108                 e.printStackTrace();
    109             }
    110         }
    111     }
    112     
    113     /***
    114      * 
    115      * @Description    关闭资源
    116      * @author XiaoFeng  
    117      * @date 2020年8月20日下午5:39:25  
    118      * @param conn
    119      * @param ps
    120      * @param rs ResultSet资源
    121      */
    122     public static void closeResource(Connection conn,Statement ps,ResultSet rs) {
    123         if (ps != null) {
    124             try {
    125                 ps.close();
    126             } catch (SQLException e) {
    127                 e.printStackTrace();
    128             }
    129         }
    130         if (conn != null) {
    131             try {
    132                 conn.close();
    133             } catch (SQLException e) {
    134                 e.printStackTrace();
    135             }
    136         }
    137         if(rs != null) {
    138             try {
    139                 rs.close();
    140             } catch (SQLException e) {
    141                 e.printStackTrace();
    142             }
    143         }
    144     }
    145 }
  • 相关阅读:
    Homebrew-macOS缺失的软件包管理器(简称brew)
    小程序setData工作原理理解图
    JS字符串转base64格式
    小小时钟带给我大大的思考-制作个时钟插件
    关键字屏蔽-正则
    图片(imageView)
    状态开关(ToggleButton)
    横向开关(switch)
    单选按钮(RadioButton)
    多选按钮(CheckBox)
  • 原文地址:https://www.cnblogs.com/xiaofeng338/p/13564088.html
Copyright © 2020-2023  润新知