• 3. 使用装饰者设计模式创建数据库连接池


    装饰者设计模式

    如果想要对某个对象的功能进行扩展时,就可以使用装饰者设计模式。

    装饰者设计模式的使用方式:

    1. 编写一个类,实现与被包装类相同的接口。【就是说和你新建的装饰类要模仿别的一样 这里指的是 实现Connction接口 就模仿了JDBC的Connction接口.
    2. 定义一个被包装类类型的变量。
    3. 定义构造方法,把被包装类的对象注入,给被包装类变量赋值。
    4. 对于不需要改写的方法,调用原有的方法。
    5. 对于需要改写的方法,写自己的代码。

    目前的问题在于我们不希望Connection对象中的close方法关闭连接,而是希望去将连接返回到池中这时就需要对Connection类进行包装因为我们使用的Mysql数据库,所以这里面实际上是对com.mysql.jdbc.Connection的包装。根据上面的方式,来包装一下Connection类。

    全代码: Util > DB.java:

    package Util;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    
    public class DB {
        private static String url = "jdbc:mysql://localhost:3306/jdbc";
        private static String user = "root";
        private static String pass = "root";
    
        static {
            // 连接数据库
            try {
                Class.forName("com.mysql.jdbc.Driver");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static Connection GetConnction() {
            try {
                return DriverManager.getConnection(url, user, pass);
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }
    }
    package Util;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    
    public class DB {
        private static String url = "jdbc:mysql://localhost:3306/jdbc";
        private static String user = "root";
        private static String pass = "root";
    
        static {
            // 连接数据库
            try {
                Class.forName("com.mysql.jdbc.Driver");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static Connection GetConnction() {
            try {
                return DriverManager.getConnection(url, user, pass);
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }
    }

    然后我们包装一个自己的 Connction 主要重写Close方法:

    MyCloseConnection > MyConntion.java:

    package MyCloseConnection;
    
    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.LinkedList;
    import java.util.Map;
    import java.util.Properties;
    import java.util.concurrent.Executor;
    
    public class MyConntion implements Connection{
        
        private Connection mConn = null;
        private LinkedList<Connection> mPool = null;
        
        /***
         * 构造函数
         * @param mConn
         * @param mPool
         */
        public MyConntion(Connection mConn, LinkedList<Connection> mPool) {
            this.mConn = mConn;
            this.mPool = mPool;
        }
        
        
        
        
    
    
    /*----------------------------------------------------*/
        
        //主要还得重写这个Close!!
        @Override
        public void close() throws SQLException {
            this.mPool.add(mConn);    //使用完 放回去
        }
    
        
        
        @Override
        public boolean isWrapperFor(Class<?> arg0) throws SQLException {
            
            return false;
        }
    
        @Override
        public <T> T unwrap(Class<T> arg0) throws SQLException {
            
            return null;
        }
    
        @Override
        public void abort(Executor executor) throws SQLException {
    
        }
    
        @Override
        public void clearWarnings() throws SQLException {
    
        }
    
    
        @Override
        public void commit() throws SQLException {
    
        }
    
        @Override
        public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
            
            return null;
        }
    
        @Override
        public Blob createBlob() throws SQLException {
            
            return null;
        }
    
        @Override
        public Clob createClob() throws SQLException {
            
            return null;
        }
    
        @Override
        public NClob createNClob() throws SQLException {
            
            return null;
        }
    
        @Override
        public SQLXML createSQLXML() throws SQLException {
            
            return null;
        }
    
        @Override
        public Statement createStatement() throws SQLException {
            
            return null;
        }
    
        @Override
        public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
                throws SQLException {
            
            return null;
        }
    
        @Override
        public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
            
            return null;
        }
    
        @Override
        public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
            
            return null;
        }
    
        @Override
        public boolean getAutoCommit() throws SQLException {
            
            return false;
        }
    
        @Override
        public String getCatalog() throws SQLException {
            
            return null;
        }
    
        @Override
        public Properties getClientInfo() throws SQLException {
            
            return null;
        }
    
        @Override
        public String getClientInfo(String name) throws SQLException {
            
            return null;
        }
    
        @Override
        public int getHoldability() throws SQLException {
            
            return 0;
        }
    
        @Override
        public DatabaseMetaData getMetaData() throws SQLException {
            
            return null;
        }
    
        @Override
        public int getNetworkTimeout() throws SQLException {
            
            return 0;
        }
    
        @Override
        public String getSchema() throws SQLException {
            
            return null;
        }
    
        @Override
        public int getTransactionIsolation() throws SQLException {
            
            return 0;
        }
    
        @Override
        public Map<String, Class<?>> getTypeMap() throws SQLException {
            
            return null;
        }
    
        @Override
        public SQLWarning getWarnings() throws SQLException {
            
            return null;
        }
    
        @Override
        public boolean isClosed() throws SQLException {
            
            return false;
        }
    
        @Override
        public boolean isReadOnly() throws SQLException {
            
            return false;
        }
    
        @Override
        public boolean isValid(int timeout) throws SQLException {
            
            return false;
        }
    
        @Override
        public String nativeSQL(String sql) throws SQLException {
            
            return null;
        }
    
        @Override
        public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency,
                int resultSetHoldability) throws SQLException {
            
            return null;
        }
    
        @Override
        public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
            
            return null;
        }
    
        @Override
        public CallableStatement prepareCall(String sql) throws SQLException {
            
            return null;
        }
    
        @Override
        public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,
                int resultSetHoldability) throws SQLException {
            
            return null;
        }
    
        @Override
        public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
                throws SQLException {
            
            return null;
        }
    
        @Override
        public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
            
            return null;
        }
    
        @Override
        public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
            
            return null;
        }
    
        @Override
        public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
            
            return null;
        }
    
        @Override
        public PreparedStatement prepareStatement(String sql) throws SQLException {
            
            return null;
        }
    
        @Override
        public void releaseSavepoint(Savepoint savepoint) throws SQLException {
        
        }
    
        @Override
        public void rollback() throws SQLException {
    
        }
    
        @Override
        public void rollback(Savepoint savepoint) throws SQLException {
    
        }
    
        @Override
        public void setAutoCommit(boolean autoCommit) throws SQLException {
    
        }
    
        @Override
        public void setCatalog(String catalog) throws SQLException {
    
        }
    
        @Override
        public void setClientInfo(Properties properties) throws SQLClientInfoException {
    
        }
    
        @Override
        public void setClientInfo(String name, String value) throws SQLClientInfoException {
    
        }
    
        @Override
        public void setHoldability(int holdability) throws SQLException {
    
        }
    
        @Override
        public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
    
        }
    
        @Override
        public void setReadOnly(boolean readOnly) throws SQLException {
    
        }
    
        @Override
        public Savepoint setSavepoint() throws SQLException {
            
            return null;
        }
    
        @Override
        public Savepoint setSavepoint(String name) throws SQLException {
            
            return null;
        }
    
        @Override
        public void setSchema(String schema) throws SQLException {
    
        }
    
        @Override
        public void setTransactionIsolation(int level) throws SQLException {
    
        }
    
        @Override
        public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
            
        }
    
    }

    后面的代码用不到的你别去写即可。

    然后我们新建一个连接池【规范的】:

    ConnPool > Connpool.java

    主要重写GetConntion 方法 ,返回的是自己包装过的【改写过Close的】, 那么就很完美了。

    package ConnPool;
    
    import java.io.PrintWriter;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.sql.SQLFeatureNotSupportedException;
    import java.util.Collection;
    import java.util.Collections;
    import java.util.LinkedList;
    import java.util.logging.Logger;
    
    import javax.sql.DataSource;
    
    import MyCloseConnection.MyConntion;
    import Util.DB;
    
    public class Connpool implements DataSource{
        
        private static LinkedList<Connection> pool = (LinkedList<Connection>) Collections.synchronizedList(new LinkedList<Connection>());
        
        static {
            //创建连接池 顺便解决线程不安全
            for(int i = 0;i < 10;i++) {
                Connection conn = DB.GetConnction();
                if(conn != null) {
                    pool.add(conn);
                }
            }
            //是否成功添加
            System.out.println("数据库连接池初始化成功:" + pool.size() + "个");
        }
        
        /*------------------------------------------------------------------------*/
    
        //主要重写这个GetConnection【无参的】 关键看这里! 因为取出是最关键的!
        @Override
        public Connection getConnection() throws SQLException {
            
            if(pool.size() > 0) {
                //在池中取出一个连接
                Connection conn = pool.removeFirst();
                //放入自己包装过的 Conntion中【这个包装过的 也是一个Connection ! 记住啊】
                MyConntion myConntion = new MyConntion(conn, pool);
                
                //返回我包装过的‘Connection’
                return myConntion;
                
            }else {
                throw new ExceptionInInitializerError("服务器繁忙,请稍后重试");
            }
        }
    
        @Override
        public Connection getConnection(String username, String password) throws SQLException {
            return null;
        }
        
        @Override
        public PrintWriter getLogWriter() throws SQLException {
            return null;
        }
    
        @Override
        public int getLoginTimeout() throws SQLException {
            return 0;
        }
    
        @Override
        public Logger getParentLogger() throws SQLFeatureNotSupportedException {
            return null;
        }
    
        @Override
        public void setLogWriter(PrintWriter arg0) throws SQLException {
        }
    
        @Override
        public void setLoginTimeout(int arg0) throws SQLException {
        }
    
        @Override
        public boolean isWrapperFor(Class<?> arg0) throws SQLException {
            return false;
        }
    
        @Override
        public <T> T unwrap(Class<T> arg0) throws SQLException {
            return null;
        }
    
    
    
    }

    注意: 上面的代码会报错 ,但是不是为了去实现它 而是学它的原理

    嫌代码多的可 使用适配器模式创建 。

    至于为什么报错 以后会了再说,现在主要是懂思想即可,后面直接用第三方的连接池.

    本文来自博客园,作者:咸瑜,转载请注明原文链接:https://www.cnblogs.com/bi-hu/p/14881392.html

  • 相关阅读:
    IOS照相
    起学习iOS开发专用词汇
    django[post与get测试]
    起名字好难啊!(初识Django)
    MTV模型
    Django安装以及介绍
    数据库操作
    数据库其它操作
    数据库经典习题,
    数据库基本操作
  • 原文地址:https://www.cnblogs.com/bi-hu/p/14881392.html
Copyright © 2020-2023  润新知