您的位置:首页 > 其它

数据源的编写(开发中不写)、使用动态代理覆写Connection的close方法

2014-03-13 23:39 369 查看
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.SQLException;
import java.util.LinkedList;

import javax.sql.DataSource;

import com.itheima.util.JdbcUtil;
//标准的数据库连接池。按照字面意思,一般叫做数据源(都是带池的,为了提高效率)
public class MyDataSource implements DataSource {

private static LinkedList<Connection> pool = new LinkedList<Connection>();
static{
try {
//池进行初始化:10个连接
for(int i=0;i<10;i++){
pool.add(JdbcUtil.getConnection());
}
} catch (Exception e) {
throw new ExceptionInInitializerError("数据库连接池初始化失败");
}
}
//返回它的包装类,会拦截connection中的所有方法
@Override
public synchronized Connection getConnection() throws SQLException {
if(pool.size()>0){
final Connection conn = pool.removeFirst();//原来的数据的connection实现。被包装类
Connection proxyconn = (Connection)Proxy.newProxyInstance(conn.getClass().getClassLoader(),
conn.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println(method.getName());
if("close".equals(method.getName())){
return pool.add(conn);
}else{
return method.invoke(conn, args);
}
}
});
return proxyconn;
}else
throw new RuntimeException("服务器忙");
}

@Override
public PrintWriter getLogWriter() throws SQLException {
return null;
}

@Override
public void setLogWriter(PrintWriter out) throws SQLException {

}

@Override
public void setLoginTimeout(int seconds) throws SQLException {

}

@Override
public int getLoginTimeout() throws SQLException {
return 0;
}

@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}

@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}

@Override
public Connection getConnection(String username, String password)
throws SQLException {
return null;
}

}


package com.jxnu.util;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
//通用的工具类:与具体数据库没有关系
public class JdbcUtil {

private static String driverClass;
private static String url;
private static String username;
private static String password;

static{
try {
//加载配置文件
InputStream in = JdbcUtil.class.getClassLoader().getResourceAsStream("dbcfg.properties");
Properties props = new Properties();
props.load(in);

driverClass = props.getProperty("driverClass");
url = props.getProperty("url");
username = props.getProperty("username");
password = props.getProperty("password");

Class.forName(driverClass);

} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}

//获取数据库的连接
public static Connection getConnection() throws Exception{
Connection conn = DriverManager.getConnection(url, username, password);
return conn;
}
//释放占用的资源
public static void release(ResultSet rs,Statement stmt,Connection conn){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}


测试:

package com.jxnu.pool04;

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

import org.junit.Test;

public class Dao1Impl {
MyDataSource ds = new MyDataSource();
@Test
public void add(){
Connection conn  = null;
Statement stmt = null;
try{
conn = ds.getConnection();
stmt = conn.createStatement();
//com.mysql.jdbc.Connection     :MySQL
//com.oracle.jdbc.Connection    :Oracle
//...
System.out.println(conn.getClass().getName());
}catch(Exception e){
e.printStackTrace();
}finally{
if(conn!=null){
try {
conn.close();//把连接给关了。不应该关,放回池中,怎么放回池中呢?连接池重点所在
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: