zoukankan      html  css  js  c++  java
  • jdbc-数据库连接池

    对于一个简单的数据库应用,由于对于数据库的访问不是很频繁,这时可以简单地在需要访问数据库时,就新创建一个连接,用完后就关闭它,这样做也不会带来什么明显的性能上的开销。但是对于一个复杂的数据库应用,情况就完全不同了,频繁的建立、关闭连接,会极大的减低系统的性能,因为对于连接的使用成了系统性能的瓶颈。
    数据库连接池的基本原理是在内部对象池中维护一定数量的数据库连接,并对外暴露数据库连接获取和返回方法。如:外部使用者可通过getConnection方法获取连接,使用完毕后再通过releaseConnection 方法将连接返回,注意此时连接并没有关闭,而是由连接池管理器回收,并为下一次使用做好准备。这样带来的好处如下:

    1、资源重用

    数据库连接得到重用,避免了频繁创建、释放连接引起的大量性能开销。在减少系统消耗的基础上,另一方面也增进了系统运行环境的平稳性(减少内存碎片以及数据库临时进程/线程的数量)。

    2、更快的系统响应速度

    数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而缩减了系统整体响应时间。

    3、统一的连接管理,避免数据库连接泄漏

    较为完备的数据库连接池实现中,可根据预先的连接占用超时设定,强制收回被占用连接。从而避免了常规数据库连接操作中可能出现的资源泄漏。

    自定义连接池

      1 public class MyPool {
      2 
      3     // 初始化连接数目
      4     private static int init_count = 3;
      5     // 最大连接数
      6     private static int max_count = 6;
      7     // 记录当前使用连接数
      8     private static int current_count = 0;
      9     // 连接池
     10     private static LinkedList<Connection> pool = new LinkedList<>();
     11     
     12     static {
     13         // 初始化连接
     14         for (int i=0; i<init_count; i++){
     15             // 记录当前连接数目
     16             current_count++;
     17             // 创建原始的连接对象
     18             Connection con = createConnection();
     19             // 把连接加入连接池
     20             pool.addLast(con);
     21         }
     22     }
     23 
     24     private static Connection createConnection(){
     25         try {
     26             Class.forName("com.mysql.jdbc.Driver");
     27             // 原始的目标对象
     28             final Connection con = DriverManager.getConnection("jdbc:mysql:///ysdrzp", "root", "root");
     29 
     30             // 对连接对象创建代理对象
     31             Connection proxy = (Connection) Proxy.newProxyInstance(
     32                     con.getClass().getClassLoader(),
     33                     new Class[]{Connection.class},
     34                     new InvocationHandler() {
     35                         @Override
     36                         public Object invoke(Object proxy, Method method, Object[] args)
     37                                 throws Throwable {
     38                             // 方法返回值
     39                             Object result = null;
     40                             // 当前执行的方法的方法名
     41                             String methodName = method.getName();
     42                             if ("close".equals(methodName)) {
     43                                 System.out.println("begin:当前执行close方法开始!");
     44                                 pool.addLast(con);
     45                                 System.out.println("end: 当前连接已经放入连接池了!");
     46                             } else {
     47                                 // 调用目标对象方法
     48                                 result = method.invoke(con, args);
     49                             }
     50                             return result;
     51                         }
     52                     }
     53             );
     54             return proxy;
     55         } catch (Exception e) {
     56             throw new RuntimeException(e);
     57         }
     58     }
     59 
     60     public Connection getConnection(){
     61 
     62         if (pool.size() > 0){
     63             return pool.removeFirst();
     64         }
     65         
     66         if (current_count < max_count) {
     67             // 记录当前使用的连接数
     68             current_count++;
     69             // 创建连接
     70             return createConnection();
     71         }
     72 
     73         throw new RuntimeException("当前连接已经达到最大连接数目");
     74     }
     75 
     78     public void realeaseConnection(Connection con) {
     79         
     80         if (pool.size() < init_count){
     81             pool.addLast(con);
     82         } else {
     83             try {
     84                 current_count--;
     85                 con.close();
     86             } catch (SQLException e) {
     87                 throw new RuntimeException(e);
     88             }
     89         }
     90     }
     91 
     92     public static void main(String[] args) throws SQLException {
     93         MyPool pool = new MyPool();
     94         System.out.println("当前连接: " + pool.current_count);
     95         pool.getConnection();
     96         pool.getConnection();
     97         Connection con4 = pool.getConnection();
     98         Connection con3 = pool.getConnection();
     99         Connection con2 = pool.getConnection();
    100         Connection con1 = pool.getConnection();
    101         // 释放连接, 连接放回连接池
    102         // 动态代理实现重写close()方法
    103         con1.close();
    104         pool.getConnection();
    105         System.out.println("连接池:" + pool.pool.size());
    106         System.out.println("当前连接: " + pool.current_count);
    107     }
    108 
    109 }

     DBCP

     

    url=jdbc:mysql:///ysdrzp
    driverClassName=com.mysql.jdbc.Driver
    username=root
    password=root
    initialSize=3
    maxActive=6
    maxIdle=3000
    public class DBCP {
    
        @Test
        public void testDbcp() throws Exception {
            // DBCP连接池核心类
            BasicDataSource dataSouce = new BasicDataSource();
            dataSouce.setUrl("jdbc:mysql:///ysdrzp");
            dataSouce.setDriverClassName("com.mysql.jdbc.Driver");
            dataSouce.setUsername("root");
            dataSouce.setPassword("root");
            dataSouce.setInitialSize(3);
            dataSouce.setMaxActive(6);
            dataSouce.setMaxIdle(3000);
    
            Connection con = dataSouce.getConnection();
            con.prepareStatement("delete from admin where id=3").executeUpdate();
            con.close();
        }
    
        @Test
        public void testProp() throws Exception {
            Properties prop = new Properties();
            InputStream inStream = DBCP.class.getResourceAsStream("/db.properties");
            prop.load(inStream);
            DataSource dataSouce = BasicDataSourceFactory.createDataSource(prop);
    
            Connection con = dataSouce.getConnection();
            con.prepareStatement("delete from admin where id=4").executeUpdate();
            con.close();
        }
    }

    C3P0

     1 <c3p0-config>
     2 
     3     <default-config>
     4         <property name="jdbcUrl">jdbc:mysql://localhost:3306/ysdrzp</property>
     5         <property name="driverClass">com.mysql.jdbc.Driver</property>
     6         <property name="user">root</property>
     7         <property name="password">root</property>
     8         <property name="initialPoolSize">3</property>
     9         <property name="maxPoolSize">6</property>
    10         <property name="maxIdleTime">1000</property>
    11     </default-config>
    12 
    13     <named-config name="dataSource">
    14         <property name="jdbcUrl">jdbc:mysql://localhost:3306/ysdrzp</property>
    15         <property name="driverClass">com.mysql.jdbc.Driver</property>
    16         <property name="user">root</property>
    17         <property name="password">root</property>
    18         <property name="initialPoolSize">3</property>
    19         <property name="maxPoolSize">6</property>
    20         <property name="maxIdleTime">1000</property>
    21     </named-config>
    22 
    23 </c3p0-config>
     1 public class C3P0 {
     2 
     3     @Test
     4     public void testCode() throws Exception {
     5         // 创建连接池核心工具类
     6         ComboPooledDataSource dataSource = new ComboPooledDataSource();
     7         // 设置连接参数:url、驱动、用户密码、初始连接数、最大连接数
     8         dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/ysdrzp");
     9         dataSource.setDriverClass("com.mysql.jdbc.Driver");
    10         dataSource.setUser("root");
    11         dataSource.setPassword("root");
    12         dataSource.setInitialPoolSize(3);
    13         dataSource.setMaxPoolSize(6);
    14         dataSource.setMaxIdleTime(1000);
    15 
    16         Connection con = dataSource.getConnection();
    17         con.prepareStatement("delete from admin where id=7").executeUpdate();
    18         con.close();
    19     }
    20 
    21     @Test
    22     public void testXML() throws Exception {
    23         // 自动加载src下c3p0的配置文件【c3p0-config.xml】
    24         //ComboPooledDataSource dataSource = new ComboPooledDataSource();
    25         ComboPooledDataSource dataSource = new ComboPooledDataSource("dataSource");
    26         PreparedStatement pstmt = null;
    27 
    28         Connection con = dataSource.getConnection();
    29         for (int i=1; i<11;i++){
    30             String sql = "insert into user(name,password) values(?,?)";
    31             pstmt = con.prepareStatement(sql);
    32             pstmt.setString(1, "Rose" + i);
    33             pstmt.setInt(2, 1);
    34             pstmt.executeUpdate();
    35         }
    36         pstmt.close();
    37         con.close();
    38     }
    39 }
  • 相关阅读:
    Educational Codeforces Round 83 --- F. AND Segments
    Educational Codeforces Round 83 --- G. Autocompletion
    SEERC 2019 A.Max or Min
    2019-2020 ICPC Southwestern European Regional Programming Contest(Gym 102501)
    Educational Codeforces Round 78 --- F. Cards
    今天我学习了一门全新的语言
    codeforces 1323D 题解(数学)
    Educational Codeforces Round 80 (Div. 2) 题解 1288A 1288B 1288C 1288D 1288E
    Educational Codeforces Round 81 (Div. 2) 题解 1295A 1295B 1295C 1295D 1295E 1295F
    Codeforces Round #617 (Div. 3) 题解 1296C 1296D 1296E 1296F
  • 原文地址:https://www.cnblogs.com/ysdrzp/p/9955046.html
Copyright © 2011-2022 走看看