java数据库连接池(DBCP,C3P0)


灵感来源于:https://blog.csdn.net/lfdfhl/article/details/99658807

数据库连接池简介

出现的原因

用java通过Connection连接数据库时,会消耗时间与IO资源(会消耗IO资源是因为数据库的数据是在硬盘中的,创建连接的话会将Connection对象加载到内存中,使用到IO流)。而在面临大量数据并发访问的时候,就会频繁的连接数据库,很影响效率。

作用

于是数据库连接池应运而生。
官方介绍的是:数据库连接池(Connection pooling)是程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的连接进行申请,使用,释放。
(1) 程序初始化时创建连接池(集中创建多个数据库连接)
(2) 使用时向连接池申请可用连接
(3) 使用完毕,将连接返还给连接池(返还给池子,而不是关闭连接)
(4) 程序退出时,断开所有连接,并释放资源
连接池节省了大量的数据库连接打开和关闭的动作

数据库

在这里插入图片描述

DBCP

1.创建dbcpconfig.properties配置文件

#<!-- 连接设置 -->
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb
username=root
password=root

#<!-- 初始化连接 -->
initialSize=10

#<!-- 最大连接数量 -->
maxActive=50

#<!-- 最大空闲连接 -->
maxIdle=20

#<!-- 最小空闲连接 -->
minIdle=5

#<!-- 超时等待时间(单位毫秒) -->
maxWait=50000

#<!-- 编码方式 -->
connectionProperties=useUnicode=true;characterEncoding=utf8

##<!-- 指定由连接池所创建的连接自动提交 -->
defaultAutoCommit=true

#<!-- 指定由连接池所创建的连接的事务级别 -->
defaultTransactionIsolation=REPEATABLE_READ

2.创建DBCPUtil工具类(提高代码的复用性,专门封装了创建数据库连接与释放资源这两部分)

package com.etime01;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSourceFactory;

public class DBCPUtil {
    
    
	private static DataSource dataSource = null;
	// 设置静态代码块的目的是为了让数据库连接只进行一次
	// 静态代码块会在类被加载的时候第一个被执行,且只执行一次
	// 创建数据库连接池
	static {
    
    
		// new一个Properties对象
		Properties properties = new Properties();
		try {
    
    
			// 创建类加载器
			ClassLoader classLoader = DBCPUtil.class.getClassLoader();
			// 加载配置文件
			//Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class com.etime01.DB
			//切记dbcpconfig.properties要放在src的根目录下
			properties.load(classLoader.getResourceAsStream("dbcpconfig.properties"));
			// 创建数据源工厂
			dataSource = BasicDataSourceFactory.createDataSource(properties);
		} catch (Exception e) {
    
    
			// 抛出一个异常对象
			throw new ExceptionInInitializerError("DBCP初始化错误,请检查配置文件");
		}
	}

	// 创建连接
	public static Connection getConnection() {
    
    
		try {
    
    
			// 获取Connection对象
			return dataSource.getConnection();
		} catch (SQLException e) {
    
    
			// 抛出异常
			throw new RuntimeException("数据库连接错误");
		}
	}

	// 释放资源
	public static void release(Connection connection, Statement statement, ResultSet resultSet) {
    
    
		if (connection != null) {
    
    
			try {
    
    
				connection.close();
			} catch (SQLException e) {
    
    
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		connection = null;

		if (statement != null) {
    
    
			try {
    
    
				statement.close();
			} catch (SQLException e) {
    
    
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		statement = null;

		if (resultSet != null) {
    
    
			try {
    
    
				resultSet.close();
			} catch (SQLException e) {
    
    
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		resultSet = null;
	}

}

3.创建javaBean类(这个因人而异,看个人的数据库里的数据而定)

package com.etime01;

public class Student {
    
    

	private int studentID;
	private String studentName;

	public Student() {
    
    
		super();
		// TODO Auto-generated constructor stub
	}

	public Student(int studentID, String studentName) {
    
    
		super();
		this.studentID = studentID;
		this.studentName = studentName;
	}

	@Override
	public String toString() {
    
    
		return "Student [studentID=" + studentID + ", studentName=" + studentName + "]";
	}

	public int getStudentID() {
    
    
		return studentID;
	}

	public void setStudentID(int studentID) {
    
    
		this.studentID = studentID;
	}

	public String getStudentName() {
    
    
		return studentName;
	}

	public void setStudentName(String studentName) {
    
    
		this.studentName = studentName;
	}

}

4.创建测试类

package com.etime01;

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

public class TestDBCP {
    
    

	public static void main(String[] args) {
    
    
		// new一个本类对象出来调用本类方法
		TestDBCP demo = new TestDBCP();
		demo.testDBCP();
	}

	private void testDBCP() {
    
    
		Connection connection = null;
		PreparedStatement statement = null;
		ResultSet resultSet = null;
		try {
    
    
			// 通过DBCPUtil创建连接
			connection = DBCPUtil.getConnection();
			String sql = "select studentid,studentname from student";
			statement = connection.prepareStatement(sql);
			resultSet = statement.executeQuery();
			while (resultSet.next()) {
    
    
				int id = resultSet.getInt("studentid");
				String name = resultSet.getString("studentname");
				Student student = new Student(id, name);
				System.out.println(student);
			}
		} catch (SQLException e) {
    
    
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
    
    
			DBCPUtil.release(connection, statement, resultSet);
		}
	}

}

C3P0

1.创建c3p0-config.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
  <default-config>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb</property>
    <property name="user">root</property>
    <property name="password">root</property>
    <property name="initialPoolSize">15</property>
    <property name="maxIdleTime">40</property>
    <property name="maxPoolSize">150</property>
    <property name="minPoolSize">20</property>
  </default-config>
</c3p0-config>

2.创建C3P0Util工具类

package com.etime02;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0Util {
    
    
	// 创建数据库连接池
	private static DataSource dataSource = new ComboPooledDataSource();

	// 创建连接
	public static Connection getConnection() {
    
    
		try {
    
    
			return dataSource.getConnection();
		} catch (SQLException e) {
    
    
			throw new RuntimeException("获取数据库连接失败");
		}
	}

	// 释放连接
	public static void release(Connection connection, Statement statement, ResultSet resultSet) {
    
    
		if (connection != null) {
    
    
			try {
    
    
				connection.close();
			} catch (SQLException e) {
    
    
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		connection = null;

		if (statement != null) {
    
    
			try {
    
    
				statement.close();
			} catch (SQLException e) {
    
    
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		statement = null;

		if (resultSet != null) {
    
    
			try {
    
    
				resultSet.close();
			} catch (SQLException e) {
    
    
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		resultSet = null;
	}

}

3.创建javaBean类(和DBCP一模一样)

package com.etime02;

public class Student {
    
    

	private int studentID;
	private String studentName;

	public Student() {
    
    
		super();
		// TODO Auto-generated constructor stub
	}

	public Student(int studentID, String studentName) {
    
    
		super();
		this.studentID = studentID;
		this.studentName = studentName;
	}

	@Override
	public String toString() {
    
    
		return "Student [studentID=" + studentID + ", studentName=" + studentName + "]";
	}

	public int getStudentID() {
    
    
		return studentID;
	}

	public void setStudentID(int studentID) {
    
    
		this.studentID = studentID;
	}

	public String getStudentName() {
    
    
		return studentName;
	}

	public void setStudentName(String studentName) {
    
    
		this.studentName = studentName;
	}

}

4.创建测试类(和DBCP一模一样)

package com.etime02;

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

public class TestC3P0 {
    
    

	public static void main(String[] args) {
    
    
		TestC3P0 demo = new TestC3P0();
		demo.testC3P0();
	}

	public void testC3P0() {
    
    
		Connection connection = null;
		PreparedStatement statement = null;
		ResultSet resultSet = null;
		try {
    
    
			connection = C3P0Util.getConnection();
			String sql = "select studentid,studentname from student";
			statement = connection.prepareStatement(sql);
			resultSet = statement.executeQuery();
			while (resultSet.next()) {
    
    
				int id = resultSet.getInt("studentid");
				String name = resultSet.getString("studentname");
				Student student = new Student(id, name);
				System.out.println(student);
			}
		} catch (SQLException e) {
    
    
			e.printStackTrace();
		} finally {
    
    
			C3P0Util.release(connection, statement, resultSet);
		}
	}
}

dbcp与c3p0的区别

1.dbcp没有自动的去回收空闲连接的功能 c3p0有自动回收空闲连接功能
2.两者主要是对数据连接的处理方式不同!C3P0提供最大空闲时间,DBCP提供最大连接数。
3.前者当连接超过最大空闲连接时间时,当前连接就会被断掉。DBCP当连接数超过最大连接数时,所有连接都会被断开

猜你喜欢

转载自blog.csdn.net/qq_49249150/article/details/108038263
今日推荐