package com.liuyong.util;
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.List;
import java.util.Properties;
import java.util.logging.Logger;
import javax.management.RuntimeErrorException;
import javax.sql.DataSource;
/**
* 数据库连接工具类
* @author DML
* @date 2018年6月22日
*
*/
public class DBConnectionPool implements DataSource {
//集合,用于存放数据库连接
private static LinkedList<Connection> dbpool = new LinkedList<Connection>();
static {
System.out.println("static在执行...");
//1.加载properties配置文件
InputStream inStream = DBConnectionPool.class.getResourceAsStream("/config.properties");
//2.实例化properties对象,用于处理properties文件
Properties prop = new Properties();
try {
//3.加载配置文件
prop.load(inStream);
//4.从properties配置文件中获得对应的参数值
String driver = prop.getProperty("CLASSNAME"); //注意:与配置文件中的名称一致
String url = prop.getProperty("URL");
String user = prop.getProperty("USERNAME");
String pwd = prop.getProperty("PASSWORD");
int initialSize = Integer.parseInt(prop.getProperty("initialSize"));//初始化创建的连接数
int maxActive = Integer.parseInt(prop.getProperty("maxActive"));//最大连接数
int maxIdle = Integer.parseInt(prop.getProperty("maxIdle"));//最大空闲连接数
int minIdle = Integer.parseInt(prop.getProperty("minIdle"));//最小空闲连接数
int maxWait = Integer.parseInt(prop.getProperty("maxWait"));//超时等待时间
//5.加载驱动
Class.forName(driver);
//6.根据 initialSize 设置的数向集合中添加connection
for (int i = 0; i < initialSize; i++) {
//7.创建连接
Connection conn = DriverManager.getConnection(url, user, pwd);
//System.out.println("已初始化了第"+ (i+1) + "个连接:" + conn);
dbpool.addLast(conn);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public PrintWriter getLogWriter() throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
// TODO Auto-generated method stub
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
// TODO Auto-generated method stub
}
@Override
public int getLoginTimeout() throws SQLException {
// TODO Auto-generated method stub
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
// TODO Auto-generated method stub
return null;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
// TODO Auto-generated method stub
return false;
}
//获得数据库连接
@Override
public Connection getConnection() throws SQLException {
// TODO Auto-generated method stub
//如果数据库连接池中的连接对象的个数大于0
if(dbpool.size()>0) {
//从dbpool集合中获取一个数据库边接
final Connection conn = dbpool.removeFirst();
//反射,三个参(当前类对象,conn对象的父接口,处理)
//该处会产生转换异常,是因为第二个参要求是它创建的代理实现了interfaces接口,由于conn.getClass().getInterfaces()获取到的接口数组是com.mysql.jdbc.Connection继承的接口,所以得到的结果是java.sql.Connection,但是这里需要使用com.mysql.jdbc.Connection;所以导致转换错误
return (Connection)Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{com.mysql.jdbc.Connection.class}, new InvocationHandler() {
//调用方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
if("close".equals(method.getName())) {
//如果调用的是Connection对象的close方法,就把conn还给数据库连接池
dbpool.addLast(conn);
return null;
}
return method.invoke(conn, args);
}
});
}else {
throw new RuntimeException("对不起,数据库繁忙,请稍后刷新");
}
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
// TODO Auto-generated method stub
return null;
}
}
package com.liuyong.util;
/**
* 数据库帮助类
*/
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DBHelper {
private static DBConnectionPool pool = new DBConnectionPool();
//获得连接
public static Connection getcon() throws SQLException{
return pool.getConnection();
}
//释放资源
public static void close(Connection conn, PreparedStatement ps, ResultSet rs) {
try {
if(conn !=null && !conn.isClosed()) {
conn.close();
}
if(ps !=null) {
ps.close();
}
if(rs !=null) {
rs.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void close(Connection conn, PreparedStatement ps) {
close(conn, ps, null);
}
}