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

来源:互联网 发布:mac系统玩不了魔兽 编辑:程序博客网 时间:2024/05/23 07:23
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中的所有方法@Overridepublic 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;}elsethrow new RuntimeException("服务器忙");}@Overridepublic PrintWriter getLogWriter() throws SQLException {return null;}@Overridepublic void setLogWriter(PrintWriter out) throws SQLException {}@Overridepublic void setLoginTimeout(int seconds) throws SQLException {}@Overridepublic int getLoginTimeout() throws SQLException {return 0;}@Overridepublic <T> T unwrap(Class<T> iface) throws SQLException {return null;}@Overridepublic boolean isWrapperFor(Class<?> iface) throws SQLException {return false;}@Overridepublic 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();@Testpublic 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();}}}}}


0 0