• 装饰者模式-自定义连接池


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

    为什么要有连接池

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

    如何创建简单的连接池

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

    代码实现自定义连接池

    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;
        }
    
    }
  • 相关阅读:
    数组常用遍历方法总结
    文本控制行数,超出省略号显示
    数据结构入门
    数论函数补充 公式推导
    几何入门合集 gym101968 problem F. Mirror + gym102082 Problem F Fair Chocolate-Cutting + gym101915 problem B. Ali and Wi-Fi
    COCI 2018/2019 CONTEST #2 T4 Maja T5Sunčanje Solution
    数论函数
    数论入门
    USACO1.4 1.5 搜索剪枝与数字 洛谷OJ P1214 P1215 P1217 P1218
    USACO Section 1.3 题解 (洛谷OJ P1209 P1444 P3650 P2693)
  • 原文地址:https://www.cnblogs.com/hetaoyuan/p/12509547.html
Copyright © 2020-2023  润新知