zoukankan      html  css  js  c++  java
  • JDBC基础学习(六)—数据库连接池

    一、数据库连接池介绍

    1.数据库连接池的缘由

         对于一个简单的数据库应用,由于对于数据库的访问不是很频繁。这时可以简单地在需要访问数据库时,就新创建一个连接,用完后就关闭它,这样做也不会带来什么明显的性能上的开销。但是对于一个复杂的数据库应用,情况就完全不同了。频繁的建立、关闭连接,会极大的减低系统的性能,因为对于连接的使用成了系统性能的瓶颈。

         连接复用。通过建立一个数据库连接池以及一套连接使用管理策略,使得一个数据库连接可以得到高效、安全的复用,避免了数据库连接频繁建立、关闭的开销。

         对于共享资源,有一个很著名的设计模式:资源池。该模式正是为了解决资源频繁分配、释放所造成的问题的。把该模式应用到数据库连接管理领域,就是建立一个数据库连接池,提供一套高效的连接分配、使用策略,最终目标是实现连接的高效、安全的复用。

    2.数据库连接池的原理

         连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。而连接的建立、断开都由连接池自身来管理。同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数以及每个连接的最大使用次数、最大空闲时间等等。也可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。

         image

    3.数据库连接池的优点

    (1)资源重用

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

    (2)更快的系统响应速度

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

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

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

    二、C3P0连接池

         JDBC 的数据库连接池使用 javax.sql.DataSource 来表示,DataSource 只是一个接口,该接口通常由服务器(Weblogic, WebSphere, Tomcat)提供实现,也有一些开源组织提供实现:
         (1)DBCP 数据库连接池
         (2)C3P0 数据库连接池

         现在由于用的最多的是C3P0连接池,下面几介绍它的配置了。

    c3p0-config.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <c3p0-config>
    
    	<!-- 指定连接数据源的基本属性 -->
    	<named-config name="c3p0test">
    		<property name="driverClass">com.mysql.jdbc.Driver</property>
    		<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc</property>
    		<property name="user">root</property>
    		<property name="password">123456</property>
    		<!-- 若数据库连接数不足时,一次向服务器申请的连接数 -->
    		<property name="acquireIncrement">5</property>
    		<!-- 初始化数据库连接池时连接的数量 -->
    		<property name="initialPoolSize">10</property>
    		<!-- 数据库连接池中最小的连接数 -->
    		<property name="minPoolSize">5</property>
    		<!-- 数据库连接池中最大的连接数 -->
    		<property name="maxPoolSize">20</property>
    		<!-- 数据库连接池可以维护的Statement的个数 -->
    		<property name="maxStatements">20</property>
    		<!-- 每个连接同时可以使用的Statement对象的个数 -->
    		<property name="maxStatementsPerConnection">5</property>
    	</named-config>
    
    </c3p0-config>

    JDBCTools.java

    public class JdbcTools{
    	
    	private static ComboPooledDataSource dataSource;
         
        private JdbcTools(){
             
        }
         
        static{
            try{
                //注册驱动
                Class.forName("com.mysql.jdbc.Driver");
            }catch(ClassNotFoundException e){
                throw new ExceptionInInitializerError(e);
            }
        }
        
        
        /*
         * 初始化数据库连接池
         */
        static{
        	dataSource = new ComboPooledDataSource("c3p0test");
        }
        
         
        /*
         * 获取连接
         */
        public static Connection getConnection() throws SQLException{
        	return dataSource.getConnection();
        }
         
        /*
         * 释放资源
         */
        public static void releaseResource(Connection con,Statement st,ResultSet rs){
            try{
                if(rs != null){
                    rs.close();
                }
            }catch(SQLException e){
                e.printStackTrace();
            }finally{
                try{
                    if(st != null){
                        try{
                            st.close();
                        }catch(SQLException e){
                            e.printStackTrace();
                        }
                    }
                }finally{
                    if(con != null){
                        try{
                            //数据库连接才Connection对象进行关闭,并不是真的关闭。
                        	//而是归还到了数据库连接词中
                        	con.close();
                        }catch(SQLException e){
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        
        /*
         * 通用的增删改方法
         * 执行SQL语句,使用PreparedStatemnt
         * @param sql 带占位符的sql语句
         * @param args 填写SQL占位符的可变参数
         */
        public static void update(String sql,Object...args){
        	Connection con = null;
        	PreparedStatement ps = null;
        	ResultSet rs = null;
        	
        	try{
        		con = JdbcTools.getConnection();
        		ps = con.prepareStatement(sql);
        		
        		for(int i = 0;i < args.length;i++){
    				ps.setObject(i + 1,args[i]);
    			}
        		
        		ps.execute();
        		
        	}catch (Exception e) {
        		e.printStackTrace();
    		}
        	finally{
        		JdbcTools.releaseResource(con,ps,rs);
        	}
        }
        
        public static void update(Connection con,String sql,Object...args){
        	PreparedStatement ps = null;
        	ResultSet rs = null;
        	
        	try{
        		ps = con.prepareStatement(sql);
        		
        		for(int i = 0;i < args.length;i++){
        			ps.setObject(i + 1,args[i]);
        		}
        		
        		ps.execute();
        		
        	}catch (Exception e) {
        		e.printStackTrace();
        	}
        	finally{
        		JdbcTools.releaseResource(null,ps,rs);
        	}
        }
        
        /*
         * 开启事务
         */
        public static void beginTx(Connection con){
        	if(con != null){
        		try{
    				con.setAutoCommit(false);
    			}catch(SQLException e){
    				e.printStackTrace();
    			}
        	}
        }
        
        /*
         * 提交事务
         */
        public static void commitTx(Connection con){
        	if(con != null){
        		try{
        			con.commit();
        		}catch(SQLException e){
        			e.printStackTrace();
        		}
        	}
        }
        
        /*
         * 回滚事务
         */
        public static void rollBackTx(Connection con){
        	if(con != null){
        		try{
        			con.rollback();
        		}catch(SQLException e){
        			e.printStackTrace();
        		}
        	}
        }
    }
  • 相关阅读:
    bzoj 4012: [HNOI2015]开店
    POJ 1054 The Troublesome Frog
    POJ 3171 Cleaning Shifts
    POJ 3411 Paid Roads
    POJ 3045 Cow Acrobats
    POJ 1742 Coins
    POJ 3181 Dollar Dayz
    POJ 3040 Allowance
    POJ 3666 Making the Grade
    洛谷 P3657 [USACO17FEB]Why Did the Cow Cross the Road II P
  • 原文地址:https://www.cnblogs.com/yangang2013/p/5407745.html
Copyright © 2011-2022 走看看