zoukankan      html  css  js  c++  java
  • 装饰者模式-自定义连接池

    装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例

    为什么要有连接池

    数据库的连接对象创建工作,比较消耗性能。

    如何创建简单的连接池

    在内存中开辟一块空间(集合),一开先往池子里面放置 多个连接对象。 后面需要连接的话,直接从池子里面取。不要去自己创建连接了。 使用完毕, 要记得归还连接。确保连接对象能循环利用。

    代码实现自定义连接池

    import java.io.PrintWriter;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.sql.SQLFeatureNotSupportedException;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.logging.Logger;
    
    import javax.sql.DataSource;
    
    /**
     * 这是一个数据库连接池
     * 一开始先往池子里面放10个连接
     * 
     *     1. 开始创建10个连接。
     * 
     *     2. 来的程序通过getConnection获取连接
     * 
     *     3. 用完之后,使用addBack 归还连接。
     * 
     *     4. 扩容。 
     * 
     * 
     * 问题: 
     * 
     *         1. sun公司针对数据库连接池定义的一套规范。 
     *     
     *     1. 需要额外记住 addBack方法
     * 
     *     2. 单例。
     * 
     *     3. 无法面向接口编程。 
     * 
     *         UserDao dao = new UserDaoImpl();
     *         dao.insert();
     * 
     * 
     *         DataSource dataSource = new MyDataSource();
     * 
     *         因为接口里面没有定义addBack方法。 
     * 
     *     4. 怎么解决?  
     *         
     */
    public class MyDataSource implements DataSource {
        
        List <Connection> list = new ArrayList<Connection>();
        
        public  MyDataSource() {
            for (int i = 0; i < 10; i++) {
                Connection conn = JDBCUtil.getConn();
                list.add(conn);
            }
        }
        
        
    //    该连接池对外公布的获取连接的方法
        @Override
        public Connection getConnection() throws SQLException {
            //来拿连接的时候,先看看,池子里面还有没有。
            if(list.size() == 0 ){
                for (int i = 0; i < 5; i++) {
                    Connection conn = JDBCUtil.getConn();
                    list.add(conn);
                }
            }
            
            //remove(0) ---> 移除第一个。 移除的是集合中的第一个。  移除的是开始的那个元素
            Connection conn = list.remove(0);
            
            //在把这个对象抛出去的时候, 对这个对象进行包装。
            Connection connection = new ConnectionWrap(conn, list);
            
            return connection;
        }
        
        /**
         * 用完之后,记得归还。
         * @param conn
         */
        public void addBack(Connection conn){
            list.add(conn);
        }
        
        //----------------------------
    
        @Override
        public PrintWriter getLogWriter() throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public void setLogWriter(PrintWriter out) throws SQLException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void setLoginTimeout(int seconds) throws SQLException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public int getLoginTimeout() throws SQLException {
            // TODO Auto-generated method stub
            return 0;
        }
    
        @Override
        public Logger getParentLogger() throws SQLFeatureNotSupportedException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public <T> T unwrap(Class<T> iface) throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public boolean isWrapperFor(Class<?> iface) throws SQLException {
            // TODO Auto-generated method stub
            return false;
        }
    
        
    
        @Override
        public Connection getConnection(String username, String password) throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
    }
    出现的问题:
    1. 需要额外记住 addBack方法
     
         2. 单例。
     
         3. 无法面向接口编程。 
     
             UserDao dao = new UserDaoImpl();
             dao.insert();
     
     
             DataSource dataSource = new MyDataSource();
     
             因为接口里面没有定义addBack方法。 
     
         4. 怎么解决?   以addBack 为切入点。
    
    ###解决自定义数据库连接池出现的问题。 
    
    > 由于多了一个addBack 方法,所以使用这个连接池的地方,需要额外记住这个方法,并且还不能面向接口编程。
    
    > 我们打算修改接口中的那个close方法。  原来的Connection对象的close方法,是真的关闭连接。 
    > 打算修改这个close方法,以后在调用close, 并不是真的关闭,而是归还连接对象。
    如何扩展某一个方法?
    
    > 原有的方法逻辑,不是我们想要的。 想修改自己的逻辑
    
    1. 直接改源码  无法实现。
    
    2. 继承,必须得知道这个接口的具体实现是谁。 
    
    3. 使用装饰者模式。 
    我们使用装饰模式

    装饰模式其实就是 和 被装饰的类继承一个 接口 ,
    然后把装饰类 的构造方法 写成 加入 被装饰类对象然后再在
    装饰类中,写上调用对象方法 再添加自己的方法。

    public class ConnectionWrap  implements Connection{
        
        Connection connection = null;
        List <Connection> list ;
        public ConnectionWrap(Connection connection , List <Connection> list) {
            super();
            this.connection = connection;
            this.list = list;
        }
    
        @Override
        public void close() throws SQLException {
            //connection.close();
            System.out.println("有人来归还连接对象了。 归还之前,池子里面是:"+list.size());
            list.add(connection);
            System.out.println("有人来归还连接对象了。 归还之后...,池子里面是:"+list.size());
        }
    
        ......

    JDBCUtil

    import java.io.FileInputStream;
    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 {
        
        static String driverClass = null;
        static String url = null;
        static String name = null;
        static String password= null;
        
        static{
            try {
                //1. 创建一个属性配置对象
                Properties properties = new Properties();
                InputStream is = new FileInputStream("jdbc.properties");
                
                //使用类加载器,去读取src底下的资源文件。 后面在servlet
    //            InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
                //导入输入流。
                properties.load(is);
                
                //读取属性
                driverClass = properties.getProperty("driverClass");
                url = properties.getProperty("url");
                name = properties.getProperty("name");
                password = properties.getProperty("password");
                
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
        /**
         * 获取连接对象
         * @return
         */
        public static Connection getConn(){
            Connection conn = null;
            try {
                Class.forName(driverClass);
                //静态代码块 ---> 类加载了,就执行。 java.sql.DriverManager.registerDriver(new Driver());
                //DriverManager.registerDriver(new com.mysql.jdbc.Driver());
                //DriverManager.getConnection("jdbc:mysql://localhost/test?user=monty&password=greatsqldb");
                //2. 建立连接 参数一: 协议 + 访问的数据库 , 参数二: 用户名 , 参数三: 密码。
                conn = DriverManager.getConnection(url, name, password);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return conn;
        }
        
        /**
         * 释放资源
         * @param conn
         * @param st
         * @param rs
         */
        public static void release(Connection conn , Statement st , ResultSet rs){
            closeRs(rs);
            closeSt(st);
            closeConn(conn);
        }
        public static void release(Connection conn , Statement st){
            closeSt(st);
            closeConn(conn);
        }
    
        
        private static void closeRs(ResultSet rs){
            try {
                if(rs != null){
                    rs.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally{
                rs = null;
            }
        }
        
        private static void closeSt(Statement st){
            try {
                if(st != null){
                    st.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally{
                st = null;
            }
        }
        
        private static void closeConn(Connection conn){
            try {
                if(conn != null){
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }finally{
                conn = null;
            }
        }
    }

    测试代码:

    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    import javax.sql.DataSource;
    
    import org.junit.Test;
    
    public class TestPool {
    
        @Test
        public void testPool(){
            Connection conn = null;
            PreparedStatement ps = null;
            MyDataSource dataSource = new MyDataSource();
            try {
                conn =  dataSource.getConnection();
                
                String sql = "insert into account values (null , 'xilali' , 10)";
                ps = conn.prepareStatement(sql);
                ps.executeUpdate();
                
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                //归还连接
                //conn.close();
                //dataSource.addBack(conn);
                
                JDBCUtil.release(conn, ps);
            }
        }
    }

    完整装饰者代码:

    import java.sql.Array;
    import java.sql.Blob;
    import java.sql.CallableStatement;
    import java.sql.Clob;
    import java.sql.Connection;
    import java.sql.DatabaseMetaData;
    import java.sql.NClob;
    import java.sql.PreparedStatement;
    import java.sql.SQLClientInfoException;
    import java.sql.SQLException;
    import java.sql.SQLWarning;
    import java.sql.SQLXML;
    import java.sql.Savepoint;
    import java.sql.Statement;
    import java.sql.Struct;
    import java.util.List;
    import java.util.Map;
    import java.util.Properties;
    import java.util.concurrent.Executor;
    
    public class ConnectionWrap  implements Connection{
        
        Connection connection = null;
        List <Connection> list ;
        public ConnectionWrap(Connection connection , List <Connection> list) {
            super();
            this.connection = connection;
            this.list = list;
        }
    
        @Override
        public void close() throws SQLException {
            //connection.close();
            System.out.println("有人来归还连接对象了。 归还之前,池子里面是:"+list.size());
            list.add(connection);
            System.out.println("有人来归还连接对象了。 归还之后...,池子里面是:"+list.size());
        }
        
        
        @Override
        public PreparedStatement prepareStatement(String sql) throws SQLException {
            return connection.prepareStatement(sql);
        }
        
        
        
        
    
        @Override
        public <T> T unwrap(Class<T> iface) throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public boolean isWrapperFor(Class<?> iface) throws SQLException {
            // TODO Auto-generated method stub
            return false;
        }
    
        @Override
        public Statement createStatement() throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        
    
        @Override
        public CallableStatement prepareCall(String sql) throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public String nativeSQL(String sql) throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public void setAutoCommit(boolean autoCommit) throws SQLException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public boolean getAutoCommit() throws SQLException {
            // TODO Auto-generated method stub
            return false;
        }
    
        @Override
        public void commit() throws SQLException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void rollback() throws SQLException {
            // TODO Auto-generated method stub
            
        }
    
        
    
        @Override
        public boolean isClosed() throws SQLException {
            // TODO Auto-generated method stub
            return false;
        }
    
        @Override
        public DatabaseMetaData getMetaData() throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public void setReadOnly(boolean readOnly) throws SQLException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public boolean isReadOnly() throws SQLException {
            // TODO Auto-generated method stub
            return false;
        }
    
        @Override
        public void setCatalog(String catalog) throws SQLException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public String getCatalog() throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public void setTransactionIsolation(int level) throws SQLException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public int getTransactionIsolation() throws SQLException {
            // TODO Auto-generated method stub
            return 0;
        }
    
        @Override
        public SQLWarning getWarnings() throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public void clearWarnings() throws SQLException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
                throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public Map<String, Class<?>> getTypeMap() throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void setHoldability(int holdability) throws SQLException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public int getHoldability() throws SQLException {
            // TODO Auto-generated method stub
            return 0;
        }
    
        @Override
        public Savepoint setSavepoint() throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public Savepoint setSavepoint(String name) throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public void rollback(Savepoint savepoint) throws SQLException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void releaseSavepoint(Savepoint savepoint) throws SQLException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
                throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,
                int resultSetHoldability) throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency,
                int resultSetHoldability) throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public Clob createClob() throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public Blob createBlob() throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public NClob createNClob() throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public SQLXML createSQLXML() throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public boolean isValid(int timeout) throws SQLException {
            // TODO Auto-generated method stub
            return false;
        }
    
        @Override
        public void setClientInfo(String name, String value) throws SQLClientInfoException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void setClientInfo(Properties properties) throws SQLClientInfoException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public String getClientInfo(String name) throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public Properties getClientInfo() throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public void setSchema(String schema) throws SQLException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public String getSchema() throws SQLException {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public void abort(Executor executor) throws SQLException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
            // TODO Auto-generated method stub
            
        }
    
        @Override
        public int getNetworkTimeout() throws SQLException {
            // TODO Auto-generated method stub
            return 0;
        }
    
    }
  • 相关阅读:
    14.4.9 Configuring Spin Lock Polling 配置Spin lock 轮询:
    14.4.8 Configuring the InnoDB Master Thread IO Rate 配置InnoDB Master Thread I/O Rate
    14.4.7 Configuring the Number of Background InnoDB IO Threads 配置 后台InnoDB IO Threads的数量
    14.4.7 Configuring the Number of Background InnoDB IO Threads 配置 后台InnoDB IO Threads的数量
    14.4.6 Configuring Thread Concurrency for InnoDB 配置Thread 并发
    14.4.6 Configuring Thread Concurrency for InnoDB 配置Thread 并发
    14.4.5 Configuring InnoDB Change Buffering 配置InnoDB Change Buffering
    14.4.5 Configuring InnoDB Change Buffering 配置InnoDB Change Buffering
    14.4.4 Configuring the Memory Allocator for InnoDB InnoDB 配置内存分配器
    14.4.4 Configuring the Memory Allocator for InnoDB InnoDB 配置内存分配器
  • 原文地址:https://www.cnblogs.com/hetaoyuan/p/12509547.html
Copyright © 2011-2022 走看看