JDBC基础学习(六)—数据库连接池

一、数据库连接池介绍

1.数据库连接池的缘由

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

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

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

 

2.数据库连接池的原理

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

    

 

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();
    		}
    	}
    }
}
时间: 2024-11-08 18:04:16

JDBC基础学习(六)—数据库连接池的相关文章

JDBC基础学习(一) 第一个JDBC示例代码

创建JDBC应用程序: 我们以<MYSQL权威指南>中mylibray的authors表为例 下面是构建JDBC应用程序的六个步骤: 导入数据包 . 需要包括含有需要进行数据库编程的JDBC类的包.大多数情况下,使用 import java.sql.*  就可以了 注册JDBC驱动程序. 需要初始化驱动程序,可以与数据库打开一个通信通道 打开连接. 需要使用DriverManager.getConnection() 方法创建一个Connection对象,它代表与数据库的物理连接 执行查询 . 

JDBC基础学习

1.概念:java数据库连接技术 2.JDBC:是一个规范,提供接口(面向接口编程) 3.JDBC API:提供程序员调用的接口和类,集成在java.sql 和javax.sql包中.如:DriverManager类(管理不同的JDBC驱动).Connerction接口.Statement接口.ResultSet接口 4.JDBC API主要功能:与数据库建立连接.执行SQL语句.处理结果 5.三大接口: <1>Connerction接口:负责连接数据库并担任传输数据的任务 <2>

JDBC基础学习(一)&mdash;JDBC的增删改查

一.数据的持久化     持久化(persistence): 把数据保存到可掉电式存储设备中以供之后使用.大多数情况下,数据持久化意味着将内存中的数据保存到硬盘上加以固化,而持久化的实现过程大多通过各种关系数据库来完成.      持久化的主要应用是将内存中的数据存储在关系型数据库中,当然也可以存储在磁盘文件.XML数据文件中.        二.JDBC简介 1.JDBC概述      JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统.通用的SQL

JDBC基础学习(四)&mdash;数据库事务

一.事务基本认识 1.事务的概述      为了保证数据库中数据的一致性,数据的操作应当是离散的成组的逻辑单元.当它全部完成时,数据的一致性可以保持,而当这个单元中的一部分操作失败,整个事务应当全部视为错误,所有从起始点以后的操作应全部回退到开始状态.      事务的操作: 先定义开始一个事务,然后对数据做修改操作,这时如果提交(commit),这些数据就永久的保存下来,如果回退(rollback),数据库管理系统就放弃所有的修改而回到开始事务的状态.   2.事务的属性 (1)原子性(Atm

scala言语基础学习六

trait的学习 1.将trait作为接口来使用 trait中可以实现一些方法,子类只要extends 了trait就可以直接使用父trait里面的方法 普通继承的话父类和子类之间的field是通过引用访问,而trait之间的继承scala编译器会直接用同一个field trait的抽象filed 继承者必须实现 为实例混入trait trait调用链 在trait中覆盖抽象方法 此时不能调用因为是抽象方法 混合使用trait的具体方法和抽象方法

Java基础学习之数据库连接

数据库的操作mysql增删查改 mysql> show databases;数据库的展示 mysql> use java12使用数据库 mysql> drop table person;删除表格 Query OK, 0 rows affected (0.01 sec) mysql> create table person(age int(4),name varchar(20),telNum varchar(14));Query OK, 0 rows affected (0.01 s

JDBC基础学习(三)&mdash;处理BLOB类型数据

一.BLOB类型介绍      在MySQL中,BLOB是一个二进制的大型对象,可以存储大量数据的容器,它能容纳不同大小的数据.      在MySQL中有四种BLOB类型.          实际使用中根据需要存入的数据大小定义不同的BLOB类型.需要注意的是,如果存储的文件过大,数据库的性能会下降.   二.Java数据类型与MySQL类型对照表      对于blob,一般用于对图片的数据库存储,原理是把图片打成二进制,然后进行的一种存储方式,在java中对应byte[]数组.      

Struts2基础学习(六)&mdash;文件的上传和下载

一.文件的上传 1.单个文件上传      Struts2使用拦截器完成了文件的上传,而且底层使用的也是FileUpload开源组件. 客户端注意事项: (1)method="post" (2)enctype="multipart/form-data" (3)<intput type="file" name="photo">   在Action编写文件上传时,需要定义三个属性. (1)文件类型File,属性名与表单

JavaScript基础学习(六)&mdash;函数

一.函数的定义 1.function语句形式 //1.function语句式 function test1(){ alert("I am test1"); } test1(); 2.函数直接量形式 //2.函数直接量形式 var test2 = function(){ alert("I am test2"); } test2(); 3.通过Function构造函数形式 Function构造函数可以接收任意数量的参数,但最后一个参数始终都被看成函数体.我们不推荐使用,