java数据库连接池

别来无恙 提交于 2019-12-04 11:14:50

        web项目都会使用数据库,而数据库访问会影响系统性能(I/O操作)。建立数据库连接是一个非常耗时耗资源的操作,通过配置连接池可以在系统启动时就分配并维护一定数量的连接,保持最低数量的连接数,通过设定连接池最大连接数来防止系统无尽的与数据库连接。这样在每次数据请求方需要连接时,直接从连接池获取,使用完毕之后再放回去,这样就可以尽可能减少不必要的数据库连接消耗,缓解数据库的访问压力,减轻对系统性能的影响。

        java常用的数据库连接池主要有 DBCP 和 C3P0;

一、DBCP

DBCP(DataBase connection pool),数据库连接池。是 apache 上的一个 Java 连接池项目,也是Tomcat 在 7.0 以前的版本使用的连接池组件。

使用DBCP应该导入commons-dbcp-x.x.jar、commons-pool-x.x.jar、commons-logging-x.x.jar

commons-dbcp最新版本是Apache Commons DBCP 2.1.1 for JDBC 4.1 (Java 7.0+)

Apache Commons Pool 2.4.2 (Java 6.0+)

Apache Commons Logging 1.2

测试实例

TestDBCP.java

package cn.iborder.utils;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
import org.junit.Test;

public class TestDBCP {
	
	//硬编码方式实现连接池
	@Test
	public void test1() {
		Connection con = null;
		PreparedStatement pstat = null;
		ResultSet rs = null;
		
		BasicDataSource dataSource = new BasicDataSource();
		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		dataSource.setUrl("jdbc:mysql://localhost/test");
		dataSource.setUsername("root");
		dataSource.setPassword("root");
		dataSource.setInitialSize(3);
		//dataSource.setMaxActive(6); //DBCP2.0以上版本已经移除此方法,由 setMaxTotal()代替
		dataSource.setMaxTotal(6);	//最大连接数
		dataSource.setMaxIdle(5); 	//最大空闲连接数.
		dataSource.setMinIdle(4);
		
		try {
			con = dataSource.getConnection();
			pstat = con.prepareStatement("select * from admin");
			rs = pstat.executeQuery();
			while (rs.next()) {
				System.out.println(rs.getInt(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3));
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				if(rs != null){
					rs.close();
					rs=null;
				}
				if(pstat != null){
					pstat.close();
					pstat=null;
				}
				if (con != null && !con.isClosed()) {
					con.close();
					con=null;
				}
			} catch (Exception e2) {
				// TODO: handle exception
			}
		}
	}
	
	//配置文件方式实现连接池
	@Test
	public void test2() {
		Connection con = null;
		PreparedStatement pstat = null;
		ResultSet rs = null;
		try {
			Properties prop = new Properties();
			BufferedInputStream in = (BufferedInputStream) this.getClass().getResourceAsStream("/db.properties");
			//FileInputStream in = (FileInputStream) TestDBCP.class.getResourceAsStream("/db.properties");//抛异常
			prop.load(in);
			DataSource dataSource = BasicDataSourceFactory.createDataSource(prop);
			con = dataSource.getConnection();
			pstat = con.prepareStatement("select * from admin");
			rs = pstat.executeQuery();
			while (rs.next()) {
				System.out.println(rs.getInt(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3));
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				if(rs != null){
					rs.close();
					rs=null;
				}
				if(pstat != null){
					pstat.close();
					pstat=null;
				}
				if (con != null && !con.isClosed()) {
					con.close();
					con=null;
				}
			} catch (Exception e2) {
				// TODO: handle exception
			}
		}
	}

}

db.properties

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost/test
username=root
password=root
InitialSize=3
MaxTotal=6
MaxIdle=5
MinIdle=4

二、C3P0

C3P0是一个开放源代码的JDBC连接池,最常用的连接池技术,Spring/Hibernate框架默认支持C3P0

使用C3P0 应该导入c3p0.xxxx.jar和mchange-commons-java-x.x.x.jar

C3P0最新版本是C3P0 0.9.5.2
核心类:CombopooledDataSource
测试实例

TestC3P0.java

package cn.iborder.utils;

import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.junit.Test;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class TestC3P0 {

	//硬编码方式实现连接池
	@Test
	public void test1(){
		Connection con = null;
		PreparedStatement pstat = null;
		ResultSet rs = null;
		
		try {
			ComboPooledDataSource dataSource = new ComboPooledDataSource();
			dataSource.setDriverClass("com.mysql.jdbc.Driver");
			dataSource.setJdbcUrl("jdbc:mysql://localhost/test");
			dataSource.setUser("root");
			dataSource.setPassword("root");
			dataSource.setInitialPoolSize(3);
			dataSource.setMaxPoolSize(6);
			dataSource.setMaxIdleTime(1000);
			
			con = dataSource.getConnection();
			pstat = con.prepareStatement("select * from admin");
			rs = pstat.executeQuery();
			while (rs.next()) {
				System.out.println(rs.getInt(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3));
			}
		} catch (PropertyVetoException e) {
			// TODO: handle exception
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  finally {
			try {
				if(rs != null){
					rs.close();
					rs=null;
				}
				if(pstat != null){
					pstat.close();
					pstat=null;
				}
				if (con != null && !con.isClosed()) {
					con.close();
					con=null;
				}
			} catch (Exception e2) {
				// TODO: handle exception
			}
		}
	}
	
	//配置文件方式实现连接池
	@Test
	public void test2() {
		Connection con = null;
		PreparedStatement pstat = null;
		ResultSet rs = null;
		try {
			//读取默认数据库
			//ComboPooledDataSource dataSource = new ComboPooledDataSource();
			
			//读取指定name的数据库
			ComboPooledDataSource dataSource = new ComboPooledDataSource("otherDB");
			
			con = dataSource.getConnection();
			pstat = con.prepareStatement("select * from admin");
			rs = pstat.executeQuery();
			while (rs.next()) {
				System.out.println(rs.getInt(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3));
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  finally {
			try {
				if(rs != null){
					rs.close();
					rs=null;
				}
				if(pstat != null){
					pstat.close();
					pstat=null;
				}
				if (con != null && !con.isClosed()) {
					con.close();
					con=null;
				}
			} catch (Exception e2) {
				// TODO: handle exception
			}
		}
	}
}

c3p0-config.xml

<c3p0-config>
	<!-- 默认数据库 -->
	<default-config>
		<property name="jdbcUrl">jdbc:mysql://localhost:3306/test</property>
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="user">root</property>
		<property name="password">root</property>
		<property name="initialPoolSize">3</property>
		<property name="maxPoolSize">6</property>
		<property name="maxIdleTime">1000</property>

		<user-overrides user="swaldman">
			<!-- 
			<property name="unreturnedConnectionTimeout">5</property>
			<property name="debugUnreturnedConnectionStackTraces">true</property> 
			-->
			<!-- <property name="preferredTestQuery">select poop from doop</property> -->
			<!-- intentionally broken -->
		</user-overrides>

	</default-config>

	<!-- 配置其他是数据库 -->
	<named-config name="otherDB">
		<property name="jdbcUrl">jdbc:mysql://localhost:3306/test</property>
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="user">root</property>
		<property name="password">root</property>
		<property name="initialPoolSize">3</property>
		<property name="maxPoolSize">6</property>
		<property name="maxIdleTime">1000</property>
	</named-config>

</c3p0-config>

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!