在JDBC编程的时候,获取到一个数据库连接资源是很宝贵的,倘若数据库访问量超大,而数据库连接资源又没能得到及时的释放,就会导致系统的崩溃甚至宕机。造成的损失将会是巨大的。再看有了数据库连接池的JDBC,就会较好的解决资源的创建与连接问题,其主要还是针对于连接资源使用层面的改进。下面我就谈一谈我对数据库连接池的理解。


数据库连接池理论基础


对于创建一个数据库连接池,需要做好准备工作。原理就是先实现DataSource接口,覆盖里面的getConnection()方法,这个方法是我们最为关注的。既然是池,就不会是一个连接对象,因此需要使用集合来保存这些个连接对象。

但是,最为关键的是,开发人员在使用完连接对象后通常会调用conn.close(),方法来释放数据库连接资源,这将会把数据库连接返还给数据库,而不是数据库连接池,因此,数据库连接池的存在就没了意义了。所以我们要增强close方法,来保证数据库连接资源返还给数据库连接池。


创建数据库连接池


public class JDCBCPool implements DataSource {

    /*
     * 既然是一个数据库连接池,就必须有许多的连接,所以需要使用一个集合类保存这些连接 (non-Javadoc)
     *
     * @see javax.sql.CommonDataSource#getLogWriter()
     */
    private static  LinkedList<Connection> list = new LinkedList<Connection>();

    // 创建一个配置文件,用于读取相应配置文件中保存的数据信息
    private static Properties config = new Properties();

    /*
     * 在这里向数据库申请一批数据库连接 为了只加载一次驱动程序,因此在静态代码块中进行声明,这样驱动就只会加载一次
     */
    static {

        try {
            config.load(JDBCUtils.class.getClassLoader().getResourceAsStream("db.properties"));
            // Class.forName("com.mysql.jdbc.Driver");
            Class.forName(config.getProperty("DRIVER"));
            try {
                //申请十个数据库连接对象,也就是数据库连接池的容量是10
                for(int i=0 ;i<10;i++){
                    Connection conn =  DriverManager.getConnection(config.getProperty("URL"),
                            config.getProperty("USER"),config.getProperty("PASSWORD"));
                    list.add(conn);
                }
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        } catch (ClassNotFoundException | IOException e) {
            // TODO Auto-generated catch block
            throw new ExceptionInInitializerError();
        }
    }

    @Override
    public Connection getConnection() throws SQLException {

        if(list.size()<=0){
            throw new RuntimeException("数据库忙,请待会再试试吧!");
        }
        //需要注意的是,不能使用get方式(这个方法知识返回一个引用而已),
        //应该在获取的同时,删除掉这个链接,之后再还回来.现在注意是返还给数据库连接池!!!
        Connection conn = list.removeFirst();
        MyConnection myconn = new MyConnection(conn);

        //从这里开始返回的就是一个数据库连接池对象的conn
        return myconn;
    }

/////////////////////////////////////////////////////////////////////////datasource接口的实现方法开始    

    @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;
    }
}

不难看出,数据库连接池相对于普通的数据库连接的创建,并没有什么特别难写的部分。

增强close方法,保证数据库连接资源用完后返还给连接池


要想增强close方法的功能,一般来说我们有如下几种方式。

  • 创建子类,覆盖close方法,但是创建子类的时候要实现的部分可能会特别多,因此并不常用
  • 使用包装设计模式
  • 使用动态代理方式

今天我就来实现一下怎么使用包装设计模式来实现close方法的增强。

包装设计模式实现close方法的增强


要实现包装设计模式,思路很简单。

  • 创建一个类,实现与被增强对象相同的接口
  • 将被增强对象作为一个成员变量加到这个类中
  • 定义一个构造方法,并把被增强对象作为参数传进来
  • 覆盖要增强的方法,这里是close方法
  • 对于不想进行增强的方法,借助于被增强对象实现即可。

下面是基于包装设计模式实现的增强的MyConnection类:

class MyConnection implements Connection {

        private Connection conn ;

        public MyConnection(Connection conn ){
            this.conn = conn;
        }

        /**
         * 自定义的包装设计模式类,增强close方法,
         * 将数据库链接资源返还给数据库连接池,而不是数据库
         */
        public void close(){
            list.add(conn);
        }

        @Override
        public <T> T unwrap(Class<T> iface) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.unwrap(iface);
        }

        @Override
        public boolean isWrapperFor(Class<?> iface) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.isWrapperFor(iface);
        }

        @Override
        public Statement createStatement() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.createStatement();
        }

        @Override
        public PreparedStatement prepareStatement(String sql) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.prepareStatement(sql);
        }

        @Override
        public CallableStatement prepareCall(String sql) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.prepareCall(sql);
        }

        @Override
        public String nativeSQL(String sql) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.nativeSQL(sql);
        }

        @Override
        public void setAutoCommit(boolean autoCommit) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.setAutoCommit(autoCommit);
        }

        @Override
        public boolean getAutoCommit() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getAutoCommit();
        }

        @Override
        public void commit() throws SQLException {
            // TODO Auto-generated method stub
            this.conn.commit();
        }

        @Override
        public void rollback() throws SQLException {
            // TODO Auto-generated method stub
            this.conn.rollback();
        }

        @Override
        public boolean isClosed() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.isClosed();
        }

        @Override
        public DatabaseMetaData getMetaData() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getMetaData();
        }

        @Override
        public void setReadOnly(boolean readOnly) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.setReadOnly(readOnly);
        }

        @Override
        public boolean isReadOnly() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.isReadOnly();
        }

        @Override
        public void setCatalog(String catalog) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.setCatalog(catalog);
        }

        @Override
        public String getCatalog() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getCatalog();
        }

        @Override
        public void setTransactionIsolation(int level) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.setTransactionIsolation(level);
        }

        @Override
        public int getTransactionIsolation() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getTransactionIsolation();
        }

        @Override
        public SQLWarning getWarnings() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getWarnings();
        }

        @Override
        public void clearWarnings() throws SQLException {
            // TODO Auto-generated method stub
            this.conn.clearWarnings();
        }

        @Override
        public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.createStatement(resultSetType, resultSetConcurrency);
        }

        @Override
        public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
                throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.prepareStatement(sql, resultSetType, resultSetConcurrency);
        }

        @Override
        public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.prepareCall(sql, resultSetType, resultSetConcurrency);
        }

        @Override
        public Map<String, Class<?>> getTypeMap() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getTypeMap();
        }

        @Override
        public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.setTypeMap(map);
        }

        @Override
        public void setHoldability(int holdability) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.setHoldability(holdability);
        }

        @Override
        public int getHoldability() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getHoldability();
        }

        @Override
        public Savepoint setSavepoint() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.setSavepoint();
        }

        @Override
        public Savepoint setSavepoint(String name) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.setSavepoint(name);
        }

        @Override
        public void rollback(Savepoint savepoint) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.rollback(savepoint);
        }

        @Override
        public void releaseSavepoint(Savepoint savepoint) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.releaseSavepoint(savepoint);
        }

        @Override
        public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
                throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
        }

        @Override
        public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,
                int resultSetHoldability) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
        }

        @Override
        public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency,
                int resultSetHoldability) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
        }

        @Override
        public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.prepareStatement(sql, autoGeneratedKeys);
        }

        @Override
        public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.prepareStatement(sql, columnIndexes);
        }

        @Override
        public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.prepareStatement(sql, columnNames);
        }

        @Override
        public Clob createClob() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.createClob();
        }

        @Override
        public Blob createBlob() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.createBlob();
        }

        @Override
        public NClob createNClob() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.createNClob();
        }

        @Override
        public SQLXML createSQLXML() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.createSQLXML();
        }

        @Override
        public boolean isValid(int timeout) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.isValid(timeout);
        }

        @Override
        public void setClientInfo(String name, String value) throws SQLClientInfoException {
            // TODO Auto-generated method stub
            this.conn.setClientInfo(name, value);
        }

        @Override
        public void setClientInfo(Properties properties) throws SQLClientInfoException {
            // TODO Auto-generated method stub
            this.conn.setClientInfo(properties);
        }

        @Override
        public String getClientInfo(String name) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getClientInfo(name);
        }

        @Override
        public Properties getClientInfo() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getClientInfo();
        }

        @Override
        public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.createArrayOf(typeName, elements);
        }

        @Override
        public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.createStruct(typeName, attributes);
        }

        @Override
        public void setSchema(String schema) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.setSchema(schema);
        }

        @Override
        public String getSchema() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getSchema();
        }

        @Override
        public void abort(Executor executor) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.abort(executor);
        }

        @Override
        public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.setNetworkTimeout(executor, milliseconds);
        }

        @Override
        public int getNetworkTimeout() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getNetworkTimeout();
        }

    }

一个简单的数据库连接池的实现案例


说是一个案例,其实也可以作为一个工具类作为今后程序开发的使用,这将会大大的提升数据库连接资源的使用。需要注意的是,里面的驱动程序是基于我自己的数据库来书写的,进行使用时记得修改一下配置文件db.properties.文件中的内容即可。

db.properties中内容如下:

#when use this db.properties ,need to change the database name
DRIVER = com.mysql.jdbc.Driver
URL = jdbc:mysql://localhost:3306/test
USER = root
PASSWORD = mysql

下面就是JDBCPool工具类的实现:

package utils;

import java.io.IOException;
import java.io.PrintWriter;
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.DriverManager;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
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.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
import java.util.logging.Logger;

import javax.sql.DataSource;

/**
 * 数据库连接池工具类
 *
 * @author Summer
 *
 */
public class JDCBCPool implements DataSource {

    /*
     * 既然是一个数据库连接池,就必须有许多的连接,所以需要使用一个集合类保存这些连接 (non-Javadoc)
     *
     * @see javax.sql.CommonDataSource#getLogWriter()
     */
    private static  LinkedList<Connection> list = new LinkedList<Connection>();

    // 创建一个配置文件,用于读取相应配置文件中保存的数据信息
    private static Properties config = new Properties();

    /*
     * 在这里向数据库申请一批数据库连接 为了只加载一次驱动程序,因此在静态代码块中进行声明,这样驱动就只会加载一次
     */
    static {

        try {
            config.load(JDBCUtils.class.getClassLoader().getResourceAsStream("db.properties"));
            // Class.forName("com.mysql.jdbc.Driver");
            Class.forName(config.getProperty("DRIVER"));
            try {
                //申请十个数据库连接对象,也就是数据库连接池的容量是10
                for(int i=0 ;i<10;i++){
                    Connection conn =  DriverManager.getConnection(config.getProperty("URL"),
                            config.getProperty("USER"),config.getProperty("PASSWORD"));
                    list.add(conn);
                }
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        } catch (ClassNotFoundException | IOException e) {
            // TODO Auto-generated catch block
            throw new ExceptionInInitializerError();
        }
    }

    @Override
    public Connection getConnection() throws SQLException {

        if(list.size()<=0){
            throw new RuntimeException("数据库忙,请待会再试试吧!");
        }
        //需要注意的是,不能使用get方式(这个方法知识返回一个引用而已),
        //应该在获取的同时,删除掉这个链接,之后再还回来.现在注意是返还给数据库连接池!!!
        Connection conn = list.removeFirst();
        MyConnection myconn = new MyConnection(conn);

        //从这里开始返回的就是一个数据库连接池对象的conn
        return myconn;
    }

/////////////////////////////////////////////////////////////////////////datasource接口的实现方法开始    

    @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;
    }
/////////////////////////////////////////////////////////////////////////datasource接口的实现方法结束

    /**
     * 包装设计模式实现流程:
     * 1.创建一个类,实现与被增强对象相同的接口
     * 2.将被增强对象当做自定义类的一个成员变量
     * 3.定义一个构造方法,将被增强对象传递进去
     * 4.增强想要增强的方法,进行覆盖即可
     * 5.对于不像被增强的方法,调用被增强对象的方法进行处理即可
     * @author Summer
     *
     */

///////////////////////////////////////////////////////////////////////使用包装设计模式,增强close方法的自定义类开始
    class MyConnection implements Connection {

        private Connection conn ;

        public MyConnection(Connection conn ){
            this.conn = conn;
        }

        /**
         * 自定义的包装设计模式类,增强close方法,
         * 将数据库链接资源返还给数据库连接池,而不是数据库
         */
        public void close(){
            list.add(conn);
        }

        @Override
        public <T> T unwrap(Class<T> iface) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.unwrap(iface);
        }

        @Override
        public boolean isWrapperFor(Class<?> iface) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.isWrapperFor(iface);
        }

        @Override
        public Statement createStatement() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.createStatement();
        }

        @Override
        public PreparedStatement prepareStatement(String sql) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.prepareStatement(sql);
        }

        @Override
        public CallableStatement prepareCall(String sql) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.prepareCall(sql);
        }

        @Override
        public String nativeSQL(String sql) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.nativeSQL(sql);
        }

        @Override
        public void setAutoCommit(boolean autoCommit) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.setAutoCommit(autoCommit);
        }

        @Override
        public boolean getAutoCommit() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getAutoCommit();
        }

        @Override
        public void commit() throws SQLException {
            // TODO Auto-generated method stub
            this.conn.commit();
        }

        @Override
        public void rollback() throws SQLException {
            // TODO Auto-generated method stub
            this.conn.rollback();
        }

        @Override
        public boolean isClosed() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.isClosed();
        }

        @Override
        public DatabaseMetaData getMetaData() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getMetaData();
        }

        @Override
        public void setReadOnly(boolean readOnly) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.setReadOnly(readOnly);
        }

        @Override
        public boolean isReadOnly() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.isReadOnly();
        }

        @Override
        public void setCatalog(String catalog) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.setCatalog(catalog);
        }

        @Override
        public String getCatalog() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getCatalog();
        }

        @Override
        public void setTransactionIsolation(int level) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.setTransactionIsolation(level);
        }

        @Override
        public int getTransactionIsolation() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getTransactionIsolation();
        }

        @Override
        public SQLWarning getWarnings() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getWarnings();
        }

        @Override
        public void clearWarnings() throws SQLException {
            // TODO Auto-generated method stub
            this.conn.clearWarnings();
        }

        @Override
        public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.createStatement(resultSetType, resultSetConcurrency);
        }

        @Override
        public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
                throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.prepareStatement(sql, resultSetType, resultSetConcurrency);
        }

        @Override
        public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.prepareCall(sql, resultSetType, resultSetConcurrency);
        }

        @Override
        public Map<String, Class<?>> getTypeMap() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getTypeMap();
        }

        @Override
        public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.setTypeMap(map);
        }

        @Override
        public void setHoldability(int holdability) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.setHoldability(holdability);
        }

        @Override
        public int getHoldability() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getHoldability();
        }

        @Override
        public Savepoint setSavepoint() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.setSavepoint();
        }

        @Override
        public Savepoint setSavepoint(String name) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.setSavepoint(name);
        }

        @Override
        public void rollback(Savepoint savepoint) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.rollback(savepoint);
        }

        @Override
        public void releaseSavepoint(Savepoint savepoint) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.releaseSavepoint(savepoint);
        }

        @Override
        public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
                throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
        }

        @Override
        public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,
                int resultSetHoldability) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
        }

        @Override
        public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency,
                int resultSetHoldability) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
        }

        @Override
        public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.prepareStatement(sql, autoGeneratedKeys);
        }

        @Override
        public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.prepareStatement(sql, columnIndexes);
        }

        @Override
        public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.prepareStatement(sql, columnNames);
        }

        @Override
        public Clob createClob() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.createClob();
        }

        @Override
        public Blob createBlob() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.createBlob();
        }

        @Override
        public NClob createNClob() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.createNClob();
        }

        @Override
        public SQLXML createSQLXML() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.createSQLXML();
        }

        @Override
        public boolean isValid(int timeout) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.isValid(timeout);
        }

        @Override
        public void setClientInfo(String name, String value) throws SQLClientInfoException {
            // TODO Auto-generated method stub
            this.conn.setClientInfo(name, value);
        }

        @Override
        public void setClientInfo(Properties properties) throws SQLClientInfoException {
            // TODO Auto-generated method stub
            this.conn.setClientInfo(properties);
        }

        @Override
        public String getClientInfo(String name) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getClientInfo(name);
        }

        @Override
        public Properties getClientInfo() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getClientInfo();
        }

        @Override
        public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.createArrayOf(typeName, elements);
        }

        @Override
        public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.createStruct(typeName, attributes);
        }

        @Override
        public void setSchema(String schema) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.setSchema(schema);
        }

        @Override
        public String getSchema() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getSchema();
        }

        @Override
        public void abort(Executor executor) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.abort(executor);
        }

        @Override
        public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
            // TODO Auto-generated method stub
            this.conn.setNetworkTimeout(executor, milliseconds);
        }

        @Override
        public int getNetworkTimeout() throws SQLException {
            // TODO Auto-generated method stub
            return this.conn.getNetworkTimeout();
        }

    }
/////////////////////////////////////////////////////////////////////////////包装设计模式结束
}

总结


  • 在实际的开发过程中,数据库连接池使用的很广泛,我们应该加以掌握。
  • 数据库连接对象应从数据库连接池中获取,使用完之后再返还给数据库连接池
  • 使用包装设计模式进行方法的增强是较为合理的,但是更为常用的是开源的数据库连接池,即动态代理方式。如DBCP等等

JDBC编程学习笔记之数据库连接池的实现的更多相关文章

  1. JDBC学习笔记(8)——数据库连接池(dbcp&C3P0)

    JDBC数据库连接池的必要性 一.在使用开发基于数据库的web程序时,传统的模式基本是按一下步骤: 1)在主程序(如servlet/beans)中建立数据库连接 2)进行sql操作 3)断开数据库连接 ...

  2. 【转】JDBC学习笔记(8)——数据库连接池(dbcp&C3P0)

    转自:http://www.cnblogs.com/ysw-go/ JDBC数据库连接池的必要性 一.在使用开发基于数据库的web程序时,传统的模式基本是按一下步骤: 1)在主程序(如servlet/ ...

  3. java学习笔记—第三方数据库连接池包1(29)

    第一步:导入dbcp包 第二步:通过核心类连接数据 BasicDataSource它是javax.sql.DataSrouce的子类. 一个工具类:BasicDataSourceFactory. 手工 ...

  4. 并发编程学习笔记(14)----ThreadPoolExecutor(线程池)的使用及原理

    1. 概述 1.1 什么是线程池 与jdbc连接池类似,在创建线程池或销毁线程时,会消耗大量的系统资源,因此在java中提出了线程池的概念,预先创建好固定数量的线程,当有任务需要线程去执行时,不用再去 ...

  5. 并发编程学习笔记(8)----ThreadLocal的使用及源码分析

    1. ThreadLocal的理解 ThreadLocal,顾名思义,就是线程的本地变量,ThreadLocal会为每个线程创建一个本地变量副本,使得使用ThreadLocal管理的变量在多线程的环境 ...

  6. 多线程编程学习笔记——async和await(一)

    接上文 多线程编程学习笔记——任务并行库(一) 接上文 多线程编程学习笔记——任务并行库(二) 接上文 多线程编程学习笔记——任务并行库(三) 接上文 多线程编程学习笔记——任务并行库(四) 通过前面 ...

  7. 多线程编程学习笔记——async和await(二)

    接上文 多线程编程学习笔记——async和await(一) 三.   对连续的异步任务使用await操作符 本示例学习如何阅读有多个await方法方法时,程序的实际流程是怎么样的,理解await的异步 ...

  8. 多线程编程学习笔记——async和await(三)

    接上文 多线程编程学习笔记——async和await(一) 接上文 多线程编程学习笔记——async和await(二) 五.   处理异步操作中的异常 本示例学习如何在异步函数中处理异常,学习如何对多 ...

  9. 多线程编程学习笔记——使用异步IO(一)

    接上文 多线程编程学习笔记——使用并发集合(一) 接上文 多线程编程学习笔记——使用并发集合(二) 接上文 多线程编程学习笔记——使用并发集合(三) 假设以下场景,如果在客户端运行程序,最的事情之一是 ...

随机推荐

  1. JSONObject转换分析

    net.sf.json.JSONObject采用反射的方式,对POJO进行转换.JSONObject类实现了JSON.Map和Comparable接口,如下: class JSONObject ext ...

  2. 以太坊MetaMask钱包插件简介

    MetaMask是一个以太坊钱包插件,虽然只能在Chrome浏览器中使用,但作为以太坊钱包的metamask却很受以太坊开发者欢迎. MetaMask 评价(5★):安装设置:★★★★界面操作:★★★ ...

  3. 如何理解主函数main中变量(int argc,char *argv[])的含义

    每一个C语言的初学者,都会注意到主函数main()里的两个参数,但是初学者一般不会去关注这两个参数的具体作用,下面我们就来介绍这两个参数的具体作用. main()函数是控制台程序的入口,int mai ...

  4. 第三次C语言作业

    (一)改错题 计算f(x)的值:输入实数x,计算并输出下列分段函数f(x)的值,输出时保留1位小数. 输入输出样例1: Enterr x: 10.0 f(10.0) = 0.1 输入输出样例2: En ...

  5. hive 存储,解析,处理json数据

    hive 处理json数据总体来说有两个方向的路走 1.将json以字符串的方式整个入Hive表,然后通过使用UDF函数解析已经导入到hive中的数据,比如使用LATERAL VIEW json_tu ...

  6. swiper display:none 后 在显示 滑动问题

    一般这种问题  必须在本身元素  或者父元素  显示出来  然后调用swiper实例 或者只需加两行 observer:true, // 修改swiper自己或子元素时,自动初始化swiper obs ...

  7. map函数、filer函数、reduce函数的用法和区别

    Map函数 map函数的用法如下: def add_one(x): return x+1 #使用普通函数 v1 = map(add_one,[1,2,3]) v1 = list(v1) print(v ...

  8. PHP MySQL 插入数据

    PHP MySQL 插入数据 使用 MySQLi 和 PDO 向 MySQL 插入数据 在创建完数据库和表后,我们可以向表中添加数据. 以下为一些语法规则: PHP 中 SQL 查询语句必须使用引号 ...

  9. vue关于数组使用的坑

    关于数组使用的坑 https://vuejs.org/v2/guide/list.html#Caveats 简言之, 不要使用a[i] = v 的形式, 用a.splice(i, 1, v), 或Vu ...

  10. Connection Reset By Peer 解析

    linux网络编程 Connection reset by peer错误服务器向客户端发送了数据,客户端没有接收就关闭了,服务器read就会发生Connection reset by peer错误.我 ...