java JDBC数据库连接池简单使用

1. 创建 DBUtils 工具类

   

package jdbc02;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;

import org.apache.commons.dbcp.BasicDataSource;

public class DBUtils {
private static BasicDataSource ds;
static {
// 创建数据源对象
ds = new BasicDataSource();
// 读取配置文件
Properties p = new Properties();
InputStream ips = DBUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
try {
p.load(ips);
String driver = p.getProperty("driver");
String url = p.getProperty("url");
String username = p.getProperty("username");
String password = p.getProperty("password");
// 设置连接信息
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(username);
ds.setPassword(password);
ds.setInitialSize(3);// 设置初始连接数量
ds.setInitialSize(5);// 设置最大连接数量
} catch (IOException e) {
e.printStackTrace();
}
}
public static Connection getconn() throws Exception {

// 获取连接对象,注意导包别导错,异常抛出
Connection conn = ds.getConnection();
System.out.println(conn);
return conn;
}
}

2. 建 jdbc.properties 文件

  name = \u5F20\u4E09
  age =18
  driver=com.mysql.jdbc.Driver
  url=jdbc:mysql://localhost:3306/newdb3?useUnicode=true&characterEncoding=UTF-8
  username=root
  password=root

3. 创建数据库连接池 JdbcConnectionsPool

package jdbc02;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.Properties;
import java.util.logging.Logger;

import javax.sql.DataSource;

public class JdbcConnectionsPool implements DataSource {

/*
* 使用静态块代码,初始化连接池,创建连接池的中最小链接数量连接,
* 创建 linkedlist 集合,将这些连接放入集合中
*/
// 创建 linkedlist 集合
private static LinkedList<Connection> linkedlist1=new LinkedList<Connection>();
private static String driver;//
private static String url;//
private static String username;// 数据库登陆名
private static String password;// 数据库的登陆密码
private static int jdbcConnectionInitSize;// 最小连接数量
private static int max=1; // 当前最大连接数量 =max*jdbcConnectionInitSize
static{
// 通过反射机制获取访问 db.properties 文件
InputStream is=JdbcConnectionsPool.class.getResourceAsStream("/jdbc.properties");
Properties prop=new Properties();
try {
// 加载 db.properties 文件
prop.load(is);
// 获取 db.properties 文件中的数据库连接信息
driver=prop.getProperty("driver");
url=prop.getProperty("url");
username=prop.getProperty("username");
password=prop.getProperty("password");
jdbcConnectionInitSize=Integer.parseInt(prop.getProperty("jdbcConnectionInitSize"));
Class.forName("com.mysql.jdbc.Driver");
// 创建最小连接数个数据库连接对象以备使用
for(int i=0;i<jdbcConnectionInitSize;i++){
Connection conn=DriverManager.getConnection(url, username, password);
System.out.println("获取到了链接" + conn);
// 将创建好的数据库连接对象添加到 Linkedlist 集合中
linkedlist1.add(conn);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public PrintWriter getLogWriter() throws SQLException {
// TODO Auto-generated method stub
return null;
}

public void setLogWriter(PrintWriter out) throws SQLException {
// TODO Auto-generated method stub

}

public void setLoginTimeout(int seconds) throws SQLException {
// TODO Auto-generated method stub

}

public int getLoginTimeout() throws SQLException {
// TODO Auto-generated method stub
return 0;
}

public Logger getParentLogger() throws SQLFeatureNotSupportedException {
// TODO Auto-generated method stub
return null;
}

public <T> T unwrap(Class<T> iface) throws SQLException {
// TODO Auto-generated method stub
return null;
}

public boolean isWrapperFor(Class<?> iface) throws SQLException {
// TODO Auto-generated method stub
return false;
}

/*
* 实现数据库连接的获取和新创建
*/
public Connection getConnection() throws SQLException {
// 如果集合中没有数据库连接对象了,且创建的数据库连接对象没有达到最大连接数量,可以再创建一组数据库连接对象以备使用
if(linkedlist1.size()==0&&max<=5){
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i=0;i<jdbcConnectionInitSize;i++){
Connection conn=DriverManager.getConnection(url, username, password);
System.out.println("获取到了链接" + conn);
// 将创建好的数据库连接对象添加到 Linkedlist 集合中
linkedlist1.add(conn);
}
max++;
}
if(linkedlist1.size()>0){
// 从 linkedlist 集合中取出一个数据库链接对象 Connection 使用
final Connection conn1=linkedlist1.removeFirst();
System.out.println("linkedlist1 数据库连接池大小是" + linkedlist1.size());
/* 返回一个 Connection 对象,并且设置 Connection 对象方法调用的限制,
* 当调用 connection 类对象的 close() 方法时会将 Connection 对象重新收集放入 linkedlist 集合中。
*/
return (Connection) Proxy.newProxyInstance(conn1.getClass().getClassLoader(),// 这里换成 JdbcConnectionsPool.class.getClassLoader(); 也行
conn1.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(!method.getName().equalsIgnoreCase("close")){
return method.invoke(conn1, args);
}else{
linkedlist1.add(conn1);
System.out.println(conn1+"对象被释放,重新放回 linkedlist 集合中!");
System.out.println("此时 Linkedlist 集合中有"+linkedlist1.size()+"个数据库连接对象!");
return null;
}
}
});
}else{
System.out.println("连接数据库失败!");
}
return null;
}

public Connection getConnection(String username, String password) throws SQLException {

return null;
}

}

 

4 测试连接池

package jdbc02;


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

public class JdbcConnectionPoolTest {
/**
* @Field: pool
* 数据库连接池
*/
private static JdbcConnectionsPool pool = new JdbcConnectionsPool();
/**
* @Method: getConnection
* @Description: 从数据库连接池中获取数据库连接对象
* @return Connection 数据库连接对象
* @throws SQLException
*/
public static Connection getConnection() throws SQLException{
return pool.getConnection();
}
/**
* @Method: release
* @Description: 释放资源,
* 释放的资源包括 Connection 数据库连接对象,负责执行 SQL 命令的 Statement 对象,存储查询结果的 ResultSet 对象
* @param conn
* @param st
* @param rs
*/
public static void release(Connection conn,Statement st,ResultSet rs){
if(rs!=null){
try{
// 关闭存储查询结果的 ResultSet 对象
rs.close();
}catch (Exception e) {
e.printStackTrace();
}
rs = null;
}
if(st!=null){
try{
// 关闭负责执行 SQL 命令的 Statement 对象
st.close();
}catch (Exception e) {
e.printStackTrace();
}
}
if(conn!=null){
try{
// 关闭 Connection 数据库连接对象
conn.close();
}catch (Exception e) {
e.printStackTrace();
}
}
}
}