最好写一个配置文件保存数据库的链接参数,方便后期更改路径等参数,我用的是properties文件。
JdbcPool类:
写一个连接池,首先,需要实现DataSource 接口;
因为会涉及到很多的添加删除操作,所以用LinkedList来保存一个个的Connection接口,并设为静态;
获取配置文件时因为只需要读取一次,也将获取代码放入静态代码块中;
实现getConnection时,发现close方法只能进行删除操作,在一个链接池中,只进行删除操作,LinkedList集合内的对象很快就变为空,所以要增强close方法,当发现实现的方法不足以实现我所需功能,有三种办法解决:
1. 写一个子类,覆盖需要增强的方法;
2. 写一个Connection的包装类,增强close方法,包装类的设计模式:1)写一个类,实现被增强对象相同的接口;
2)定义一个变量指向被增强对象;
3)定义个构造函数接收被增强对象;
4)覆盖想增强对象方法;
5)对于不想增强的方法,直接调用被增强对象的方法;
3. 用动态代理,返回一个代理对象,拦截close方法的调用,对close进行增强,以下的完整代码用的是动态代理方法。
JdbcUtils类:
链接数据库方法:
直接可以new出jdbcPool类。
释放数据苦方法:
见以下完整代码。
JdbcPool类:
package cn.itcast.demo;
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.CallableStatement;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Savepoint;
import java.sql.Statement;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.sql.DataSource;
public class JdbcPool implements DataSource {
private static LinkedList<Connection> list = new LinkedList<Connection>();
static{
try{
InputStream in = JdbcPool.class.getClassLoader().getResourceAsStream("db.properties");
Properties prop = new Properties();
prop.load(in);
String driver = prop.getProperty("driver");
String url = prop.getProperty("url");
String username = prop.getProperty("username");
String password = prop.getProperty("password");
Class.forName(driver);
for(int i=0;i<10;i++){
Connection conn = DriverManager.getConnection(url, username, password);
System.out.println("获取到了链接" + conn);
list.add(conn);
}
}catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public Connection getConnection() throws SQLException {
//proxyConnection.commit() proxyConnection.rollback
if(list.size()>0){
final Connection conn = list.removeFirst(); //myconnection.commit
return (Connection) Proxy.newProxyInstance(JdbcPool.class.getClassLoader(), conn.getClass().getInterfaces(), new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if(!method.getName().equals("close")){
return method.invoke(conn, args);
}else{
return list.add(conn);
}
}
});
}else{
throw new RuntimeException("对不起,数据库忙");
}
}
public Connection getConnection(String username, String password)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
public PrintWriter getLogWriter() throws SQLException {
// TODO Auto-generated method stub
return null;
}
public int getLoginTimeout() throws SQLException {
// TODO Auto-generated method stub
return 0;
}
public void setLogWriter(PrintWriter arg0) throws SQLException {
// TODO Auto-generated method stub
}
public void setLoginTimeout(int arg0) throws SQLException {
// TODO Auto-generated method stub
}
}
JdbcUtils类:
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class JdbcUtils {
private static JdbcPool pool = null;
public static Connection getConnection() throws SQLException{
return pool.getConnection();
}
public static void release(Connection conn,Statement st,ResultSet rs){
if(rs!=null){
try{
rs.close();
}catch (Exception e) {
e.printStackTrace();
}
rs = null;
}
if(st!=null){
try{
st.close();
}catch (Exception e) {
e.printStackTrace();
}
}
if(conn!=null){
try{
conn.close();
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
properties配置文件:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/JDBCTEST
username=root
password=root