在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. python正则表达式与Re库

    正则表达式是用来简洁表达一组字符串的表达式,一行胜千言,有点类似于数列的通项公式. 在python中提供了re库(regular expression)即正则表达式库,内置于python的标准库中,导 ...

  2. jquery 跨域请求数据问题

    昨天参加了一个前端的面试,被问到一个跨域请求数据问题,我们之前一直用的是apicloud的api进行请求的,跨域是被apicloud封装起来的,也就没有注意跨域请求数据的问题.当被问到用jquery跨 ...

  3. Linux学习之CentOS(十八)-----恢复Ext3下被删除的文件与 使用grep恢复被删文件内容(转)

    前言 下面是这个教程将教你如何在Ext3的文件系统中恢复被rm掉的文件. 删除文件 假设我们有一个文件名叫 'test.txt' $ls -il test.txt 15 -rw-rw-r– 2 roo ...

  4. 学习C语言第一天!

    整理心得笔记: 1)c语言程序由函数构成,每个函数可以实现一个或多个功能.  2)一个正规程序可以有多个函数,但是有且只有一个主函数.  3)函数只有在被调用的时候才执行,主函数由系统调用执行.  4 ...

  5. Linux 管理软件

    公司的openfire先前运行在windows上的,但由于在windows上openfire内存机制问题,最多只能占用2GB内存,且时间稍微长久一些就会自动挂掉,用户无法登陆和连接,因此迁移到了Cen ...

  6. Java关键字---this的由来和其三大作用

    [声明]欢迎转载,但请保留文章原始出处→_→ 秦学苦练:http://www.cnblogs.com/Qinstudy/ 文章来源:http://www.cnblogs.com/Qinstudy/p/ ...

  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. MySQL 排序

    MySQL 排序 我们知道从MySQL表中使用SQL SELECT 语句来读取数据. 如果我们需要对读取的数据进行排序,我们就可以使用MySQL的 ORDER BY 子句来设定你想按哪个字段哪中方式来 ...

  9. Java实验链接

    第1次实验 课堂实验内容:Java入门+Eclipse+PTA+Git+博客 实验任务书:第01次试验(安装JDK.编辑器.编写出第一个Java程序).pdf Eclipse简明教程(by郑如滨).p ...

  10. Bootstrap3 排版-引用

    在你的文档中引用其他来源的内容. 默认样式的引用 将任何 HTML 元素包裹在 <blockquote> 中即可表现为引用样式.对于直接引用,我们建议用 <p> 标签. Lor ...