黑马day11 动态代理模拟一个数据库连接池

数据库连接池:说白了就是在一个池子中(容器)中放了很多的数据库连接,当用户需要的时候就从中取出来一个用,用完了就放回连接池中。

优点:极大的提高了数据库的效率。

对于自定义的数据库连接池我们使用一个LinkedList做数据库连接池.这个集合的特点是增删快,查询慢。

自定义一个数据库连接池的步骤:

1.自定义一个类实现DataSource接口。

2.定义一个List<Connection> list=new LinkedList<Connection>();存放数据库连接。

3.初始化数据库连接池。就是在静态代码块static块中添加数据库的连接若干到list中(连接池)。

4.写一个方法returnPool(Connection con)还回到数据库连接池。如果数据库连接池中没有数据连接可用,就添加若干个带数据库连接池list中。

5.在getConnection()方法中动态代理重新改造Connection的close方法,因为我们不能够用完了就关闭,而是应该用完了还回数据库连接池中。这样可以循环使用。

案例:

自定义自己的数据库连接池MyPool

package com.itheima.mypools;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.logging.Logger;import javax.sql.DataSource;public class MyPool implements DataSource{//1.需要一个容器存放连接private static List<Connection> list=new LinkedList<Connection>();//初始化加载类的时候就在连接池中添加了5个连接static{try {//2.加载驱动Class.forName("com.mysql.jdbc.Driver");for(int i=0;i<5;i++){//3.获取连接Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/day11", "root", "169500");list.add(con);}}catch (Exception e) {e.printStackTrace();throw new RuntimeException();}}@Overridepublic Connection getConnection() throws SQLException {//如果连接池的数据没有了就添加3个连接到连接池中if(list.size()==0){for(int i=0;i<3;i++){Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/day11", "root", "169500");list.add(con);}}//获取连接,就是把连接池中的连接remove不是get…final Connection con = list.remove(0);//需要重写连接的close()方法,我们使用动态代理Connection proxy=(Connection) Proxy.newProxyInstance(con.getClass().getClassLoader(), con.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args)//proxy代理类对象 method被代理类的方法,,args被代理类方法的参数throws Throwable {if("close".equals(method.getName())){//要改造的方法就还回连接池returnPool(con);return null;}else{//不想改造的方法就使用被代理者对象的方法return method.invoke(con, args);}}});System.out.println("获取了一个连接,连接池中还有:"+list.size()+"个连接");return proxy;}public void returnPool(Connection con){try {if(con!=null&&!con.isClosed()){list.add(con);}} catch (SQLException e) {e.printStackTrace();}System.out.println("还回了一个连接,池里还剩余"+list.size()+"个连接");}@Overridepublic PrintWriter getLogWriter() throws SQLException {// TODO Auto-generated method stubreturn null;}@Overridepublic void setLogWriter(PrintWriter out) throws SQLException {// TODO Auto-generated method stub}@Overridepublic void setLoginTimeout(int seconds) throws SQLException {// TODO Auto-generated method stub}@Overridepublic int getLoginTimeout() throws SQLException {// TODO Auto-generated method stubreturn 0;}@Overridepublic Logger getParentLogger() throws SQLFeatureNotSupportedException {// TODO Auto-generated method stubreturn null;}@Overridepublic <T> T unwrap(Class<T> iface) throws SQLException {// TODO Auto-generated method stubreturn null;}@Overridepublic boolean isWrapperFor(Class<?> iface) throws SQLException {// TODO Auto-generated method stubreturn false;}@Overridepublic Connection getConnection(String username, String password)throws SQLException {// TODO Auto-generated method stubreturn null;}}使用这个自己定义的数据库连接池:

package com.itheima.mypools;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import cn.itheima.utils.JDBCUtils;public class JDBCDemo1 {public static void main(String[] args) {Connection con=null;PreparedStatement ps=null;ResultSet rs=null;try {//使用数据库连接池MyPool pool=new MyPool();//获取连接con=pool.getConnection();ps=con.prepareStatement("select * from account");rs=ps.executeQuery();while(rs.next()){String name=rs.getString("name");System.out.println(name);}} catch (SQLException e) {e.printStackTrace();throw new RuntimeException();}finally{//这里的close已经被更该过了if(rs!=null){try {rs.close();} catch (SQLException e) {e.printStackTrace();}finally{rs=null;}}if(ps!=null){try {ps.close();} catch (SQLException e) {e.printStackTrace();}finally{ps=null;}}if(con!=null){try {con.close();} catch (SQLException e) {e.printStackTrace();}finally{con=null;}}}}}运行结果:

福报够的人,从来就没听到过是非。

黑马day11 动态代理模拟一个数据库连接池

相关文章:

你感兴趣的文章:

标签云: