一、自定义一个数据库连接池
package cn.itcast.jdbc.datasource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
/**
* 自定义数据库连接池
*/
public class MyDataSource {
//实际开发中,这些应该写在配置文件中
private static String url = "jdbc:mysql:///jdbc";
private static String user = "root";
private static String password = "root";
private static int initCount = 5;//初始连接数
private static int maxCount = 10;//最大连接数
private int currentCount = 0; //当前连接数
//需要经常进行添加或者删除操作,因此使用LinkedList效率更高
private LinkedList<Connection> connectionPools = new LinkedList<Connection>();
/**
* 构造函数,负责初始化创建数据库连接
*/
public MyDataSource() {
try {
for(int i = 0; i < initCount; i ++) {
this.connectionPools.addLast(this.createConnection());
this.currentCount ++;
}
} catch (SQLException e) {
//抛出初始化错误异常
throw new ExceptionInInitializerError(e);
}
}
/**
* 获取连接
* @return
* @throws SQLException
*/
public Connection getConnection() throws SQLException {
synchronized (connectionPools) {
if(this.connectionPools.size() > 0) {
return this.connectionPools.removeFirst();
}
if(this.currentCount < maxCount) {
this.currentCount ++;
return this.createConnection();
}
throw new SQLException("已经没有连接");
}
}
/**
* 释放连接
* @param conn
*/
public void free(Connection conn) {
this.connectionPools.addLast(conn);
}
/**
* 创建真实的数据库连接
* @return
* @throws SQLException
*/
private Connection createConnection() throws SQLException {
return DriverManager.getConnection(url, user, password);
}
}
二、修改JdbcUtils.java中的部分代码
package cn.itcast.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import cn.itcast.jdbc.datasource.MyDataSource;
/**
* Jdbc工具类
*/
public final class JdbcUtils {
//省略localhost:3306
private static String url = "jdbc:mysql:///jdbc";
private static String url2
= "jdbc:mysql:///jdbc?user=root&password=root&"
+ "useUnicode=true&generateSimpleParameterMetadata=true";
private static String username = "root";
private static String password = "root";
private static MyDataSource myDataSource = null;
/**
* 构造器私用,防止直接创建对象,
* 当然通过反射可以创建
*/
private JdbcUtils(){
}
//保证只是注册一次驱动
static{
try {
Class.forName("com.mysql.jdbc.Driver");
//初始化该对象一定要在注册驱动之后
myDataSource = new MyDataSource();
} catch (ClassNotFoundException e) {
throw new ExceptionInInitializerError(e);
}
}
/**
* 获取连接
* @return
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
//return DriverManager.getConnection(url2);
//return DriverManager.getConnection(url, username, password);
//从数据源中获取数据,也就是从数据库连接池中获取数据
return myDataSource.getConnection();
}
/**
* 释放资源
*/
public static void free(ResultSet rs, Statement st, Connection conn) {
//规范的关系连接的方式
try{
if(rs != null) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
try{
if(st != null) {
st.close();
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
if(conn != null) {
//conn.close();
//将连接放入数据库连接池中
myDataSource.free(conn);
}
}
}
}
}
三、编写测试类进行测试
package cn.itcast.jdbc.datasource;
import java.sql.Connection;
import java.sql.SQLException;
import org.junit.Test;
import cn.itcast.jdbc.JdbcUtils;
/**
* 用于测试数据类
*/
public class TestDataSource {
/**
* 测试在使用数据库连接池的情况下创建数据库连接
* @throws SQLException
*/
@Test
public void testCreateConn() throws SQLException {
for(int i = 0; i < 10; i ++) {
Connection conn = JdbcUtils.getConnection();
System.out.println(conn);
JdbcUtils.free(null, null, conn);
}
}
}
控制台打印结果(有重复的对象):
com.mysql.jdbc.JDBC4Connection@7d6f77cc
com.mysql.jdbc.JDBC4Connection@5aaa6d82
com.mysql.jdbc.JDBC4Connection@73a28541
com.mysql.jdbc.JDBC4Connection@6f75e721
com.mysql.jdbc.JDBC4Connection@69222c14
com.mysql.jdbc.JDBC4Connection@7d6f77cc
com.mysql.jdbc.JDBC4Connection@5aaa6d82
com.mysql.jdbc.JDBC4Connection@73a28541
com.mysql.jdbc.JDBC4Connection@6f75e721
com.mysql.jdbc.JDBC4Connection@69222c14