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();
        		}
        	}
        }
    }
  • 相关阅读:
    podium服务器端的微前端开发框架
    几个java proxy servlet 工具
    Presto Infrastructure at Lyft
    cube.js 通过presto-gateway 进行连接
    presto-gateway nodejs client
    presto-gateway 试用以及docker 镜像制作
    presto-gateway lyft 团队开源的prestodb 的负载均衡、代理、网关工具
    Singer 修改tap-s3-csv 支持minio 连接
    plotly-dash 简单使用(一)
    smashing 三方widgets 使用
  • 原文地址:https://www.cnblogs.com/yangang2013/p/5407745.html
Copyright © 2011-2022 走看看