• 连接池(怎样使用动态代理模式写一个简单的连接池)


    连接池原理:通过一次性从数据库中取出多个Connection连接放入到一个集合中,当用户需要用到Connection连接时可以从集合中取出来,而不用频繁从数据库中获取连接对象,

    大大提高了数据库的性能,使用代理模式可以监看到当用户调用close关闭连接的方法时,将当前连接放入到集合中,从而达到复用的效果!

    1.数据库连接工具类:

    package mybatis.tools;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    /**
     * 用于获取数据库连接对象
     * @author lance
     *
     */
    public class DBUtils {
    
        private static String driver = "com.mysql.jdbc.Driver";
    
        private static String url = "jdbc:mysql://127.0.0.1:3306/mydb?useSSL=true&useUnicode=true&characterEncoding=utf-8";
    
        private static String user = "root";
    
        private static String password = "root";
    
    
        /*在静态代码块中加载驱动,
        静态代码块在加载class文件的会执行,且只执行一次*/
        static {
            try {
                Class.forName(driver);
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    
        /**提供获取Connection对象的方法*/
        public static Connection getConnection() {
            //通过驱动管理器获取一个连接对象
            Connection conn = null;
            try {
                conn = DriverManager.getConnection(url, user, password);
            } catch(SQLException e) {
                e.printStackTrace();
            }
            return conn;
        }
    
    }

    2.定义连接池工具类:

    package mybatis.tools;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.sql.Connection;
    import java.util.LinkedList;
    
    /**
     * 描述:
     * 连接池
     *
     * @author lance
     * @create 2018-10-16 9:42
     */
    public class ConnectionProxy {
        /**
         * 连接池集合
         * 用到LinkedList集合是因为这是一个链表结构,我们可以很方便从头部取出连接,
         * 从底部放入连接(LinkedList的优点)
         */
        private static LinkedList<Connection> pool = new LinkedList<>();
    
        /**
         * 初始化连接池的大小
         * @param initSize
         */
        public ConnectionProxy(int initSize){
            for (int i = 0; i < initSize; i++) {
                //获取连接
                Connection conn = DBUtils.getConnection();
                //对连接进行代理(先代理好连接再放入到集合中是因为不用在集合中
                // 再一个个取出来再进行代理,效率快)
                conn = createProxy(conn);
                //放入到集合中
                pool.add(conn);
            }
        }
    
        /**
         * 从连接池中拿出连接
         * @return
         */
        public Connection getConnection(){
            if(pool.size() > 0){
                return  pool.removeFirst();
            }
            //如果集合中没有连接则抛出异常
            throw new RuntimeException("连接池没有可用连接!");
        }
    
        /**
         * 对Connection进行代理
         * @param conn
         * @return
         */
        private Connection createProxy(Connection conn) {
            return (Connection) Proxy.newProxyInstance(
                    // 类加载器
                conn.getClass().getClassLoader(),
                    // 目标对象实现的接口
                    new Class[]{Connection.class},
                    // 当调用con对象方法的时候, 自动触发事务处理器
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            // 判断当执行了close方法的时候,把连接放入连接池
                            if ("close".equals(method.getName())) {
                                pool.addLast((Connection)proxy);
                                return null;
                            }
                            Object returnValue = method.invoke(conn,args);
                            return returnValue;
                        }
                    });
        }
    
        /**
         * 查看连接池的大小
         * @return
         */
        public int size(){
            return pool.size();
        }
    
        public static void main(String[] args) throws Exception{
            ConnectionProxy connectionProxy = new ConnectionProxy(10);
            System.out.println(connectionProxy.size());
            Connection connection = connectionProxy.getConnection();
            System.out.println(connectionProxy.size());
            connection.close();
            System.out.println(connectionProxy.size());
        }
    }

    效果图

  • 相关阅读:
    原生js实现 table表格列宽拖拽
    vue.js 利用SocketCluster实现动态添加数据及排序
    angular-websocket.js 使用
    判断当前页面是否是激活状态。
    remove ---会报错discard不会报错
    .pop ----remove 删除
    add添加
    #将相同值输出,取一个值
    集合
    __delattr__\__delitem__
  • 原文地址:https://www.cnblogs.com/gepuginy/p/9800413.html
Copyright © 2020-2023  润新知