Java数据库连接池

本文介绍了Java数据库连接池的核心思想——连接复用,通过建立、管理和关闭连接池,减少数据库连接的开销。文章列举了proxool、DBCP、C3P0等常见的连接池技术,并详细讲解了Java如何实现数据库连接池,包括DBPool数据库连接池的Bean、管理类和操作类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概述

核心思想:连接复用,通过建立一个数据库连接池以及一套连接使用、分配、管理策略,使得该连接池中的链接可以得到高效、安全的复用,避免数据库连接的频繁建立、关闭的开销。

组成部分:建立、管理、关闭

  自己维护一些数据库连接,需要使用的时候直接使用其中一个连接,用完之后不是关闭而是将其归还,等待其他操作使用。

这里写图片描述

常见技术:proxool/DBCP/C3P0三种常见的连接池技术

Proxool是一种Java数据库连接池技术。sourceforge下的一个开源项目,这个项目提供一个健壮、已用的连接池,最为关键的是这个连接池提供监控的功能,方便已用,便于发现连接泄漏的情况。
这里写图片描述

二、Java实现数据库连接池

DBPool数据库连接池Bean

public class DBPool {
    private String poolPath;//数据库连接池的配置文件路径

    private DBPool() {
    }

    /**
     * @return
     * @Author:lulei  
     * @Description: 返回DBPool对象
     */
    public static DBPool getDBPool() {
        return DBPoolDao.dbPool;
    }

    /**
     *@Description: 静态内部类实现单例模式
     *@Author:lulei  
     *@Version:1.1.0
     */
    private static class DBPoolDao{
        private static DBPool dbPool = new DBPool();
    }

    public String getPoolPath() {
        if (poolPath == null) {
            //如果poolPath为空,赋值为默认值
            poolPath = ClassUtil.getClassRootPath(DBPool.class) + "proxool.xml";
        }
        return poolPath;
    }

    /**
     * @param poolPath
     * @Author:lulei  
     * @Description: 设置数据库连接池的配置文件路径
     */
    public void setPoolPath(String poolPath) {
        this.poolPath = poolPath;
    }

}
    public static String getClassRootPath(Class<?> c) {
        return c.getResource("/").getPath().replaceAll("%20", " ");
    }

数据库管理类:

public class DBManager {

    private DBManager(){
        try {
            //数据库连接池配置文件
            JAXPConfigurator.configure(DBPool.getDBPool().getPoolPath(), false);
            //数据库加载驱动类
            Class.forName("org.logicalcobwebs.proxool.ProxoolDriver");
        } catch (Exception e) {
            // TODO Auto-generated catch block  
            e.printStackTrace();
        }
    }

    /**
     * @param poolName
     * @return
     * @throws SQLException
     * @Author:lulei  
     * @Description: 获取数据库连接
     */
    public Connection getConnection(String poolName) throws SQLException {
        return DriverManager.getConnection(poolName);
    }

    /**
     *@Description: 内部静态类实现单例模式 
     *@Author:lulei  
     *@Version:1.1.0
     */
    private static class DBManagerDao {
        private static DBManager dbManager = new DBManager();
    }

    /**
     * @return
     * @Author:lulei  
     * @Description: 返回数据库连接池管理类
     */
    public static DBManager getDBManager() {
        return DBManagerDao.dbManager;
    }

}

数据库操作类:

public class DBOperation {
    private String poolName;//数据库连接池别名
    private Connection con = null;//数据库连接

    public DBOperation(String poolName) {
        this.poolName = poolName;
    }

    /**
     * @Author:lulei  
     * @Description:关闭数据库连接
     */
    public void close() {
        try {
            if (this.con != null) {
                this.con.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @throws SQLException
     * @Author:lulei  
     * @Description: 打开数据库连接
     */
    private void open() throws SQLException {
        //先关闭后打开,防止数据库连接溢出
        close();
        this.con = DBManager.getDBManager().getConnection(this.poolName);
    }

    /**
     * @param sql
     * @param params
     * @return
     * @throws SQLException
     * @throws ClassNotFoundException
     * @Author:lulei  
     * @Description: sql语句参数转化
     */
    private PreparedStatement setPres(String sql, HashMap<Integer, Object> params) throws SQLException, ClassNotFoundException{
        if (null == params || params.size() < 1) {
            return null;
        }
        PreparedStatement pres = this.con.prepareStatement(sql);
        for (int i = 1; i <= params.size(); i++) {
            if (params.get(i) == null) {
                pres.setString(i, "");
            } else if (params.get(i).getClass() == Class.forName("java.lang.String")) {
                pres.setString(i, params.get(i).toString());
            } else if (params.get(i).getClass() == Class.forName("java.lang.Integer")) {
                pres.setInt(i, (Integer) params.get(i));
            } else if (params.get(i).getClass() == Class.forName("java.lang.Long")) {
                pres.setLong(i, (Long) params.get(i));
            } else if (params.get(i).getClass() == Class.forName("java.lang.Double")) {
                pres.setDouble(i, (Double) params.get(i));
            } else if (params.get(i).getClass() == Class.forName("java.lang.Flaot")) {
                pres.setFloat(i, (Float) params.get(i));
            } else if (params.get(i).getClass() == Class.forName("java.lang.Boolean")) {
                pres.setBoolean(i, (Boolean) params.get(i));
            } else if (params.get(i).getClass() == Class.forName("java.sql.Date")) {
                pres.setDate(i, java.sql.Date.valueOf(params.get(i).toString()));
            } else {
                return null;
            }
        }
        return pres;
    }

    /**
     * @param sql
     * @return
     * @throws SQLException
     * @Author:lulei  
     * @Description: 执行SQL语句,返回影响行数
     */
    public int executeUpdate(String sql) throws SQLException {
        this.open();
        Statement state = this.con.createStatement();
        return state.executeUpdate(sql);
    }

    /**
     * @param sql
     * @param params
     * @return
     * @throws SQLException
     * @throws ClassNotFoundException
     * @Author:lulei  
     * @Description: 执行sql语句,返回影响行数
     */
    public int executeUpdate(String sql, HashMap<Integer, Object> params) throws SQLException, ClassNotFoundException {
        this.open();
        PreparedStatement pres = setPres(sql, params);
        if (null == pres) {
            return 0;
        }
        return pres.executeUpdate();
    }

    /**
     * @param sql
     * @return
     * @throws SQLException
     * @Author:lulei  
     * @Description: 执行sql语句,返回结果集
     */
    public ResultSet executeQuery(String sql) throws SQLException {
        this.open();
        Statement state = this.con.createStatement();
        return state.executeQuery(sql);
    }

    /**
     * @param sql
     * @param params
     * @return
     * @throws SQLException
     * @throws ClassNotFoundException
     * @Author:lulei  
     * @Description:执行sql语句,返回结果集
     */
    public ResultSet executeQuery(String sql, HashMap<Integer, Object> params) throws SQLException, ClassNotFoundException {
        this.open();
        PreparedStatement pres = setPres(sql, params);
        if (null == pres) {
            return null;
        }
        return pres.executeQuery();
    }

}

数据库服务:

public class DBServer {
    private DBOperation dbOperation;

    public DBServer(String poolName) {
        dbOperation = new DBOperation(poolName);
    }

    /**
     * @Author:lulei  
     * @Description: 关闭数据库连接
     */
    public void close() {
        dbOperation.close();
    }

    /**
     * @param sql
     * @return
     * @throws SQLException
     * @Author:lulei  
     * @Description: 数据库新增操作
     */
    public int insert(String sql) throws SQLException {
        return dbOperation.executeUpdate(sql);
    }

    /**
     * @param tableName
     * @param columns
     * @param params
     * @return
     * @throws SQLException
     * @throws ClassNotFoundException
     * @Author:lulei  
     * @Description: 数据库新增操作
     */
    public int insert(String tableName, String columns, HashMap<Integer, Object> params) throws SQLException, ClassNotFoundException {
        String sql = insertSql(tableName, columns);
        return dbOperation.executeUpdate(sql, params);
    }

    /**
     * @param sql
     * @return
     * @throws SQLException
     * @Author:lulei  
     * @Description: 数据库删除操作
     */
    public int delete(String sql) throws SQLException {
        return dbOperation.executeUpdate(sql);
    }

    /**
     * @param tableName
     * @param condition
     * @return
     * @throws SQLException
     * @Author:lulei  
     * @Description: 数据库删除操作
     */
    public int delete(String tableName, String condition) throws SQLException {
        if (null == tableName) {
            return 0;
        }
        String sql = "delete from " + tableName + " " + condition;
        return dbOperation.executeUpdate(sql);
    }

    /**
     * @param sql
     * @return
     * @throws SQLException
     * @Author:lulei  
     * @Description: 数据库更新操作
     */
    public int update(String sql) throws SQLException {
        return dbOperation.executeUpdate(sql);
    }

    /**
     * @param tableName
     * @param columns
     * @param condition
     * @param params
     * @return
     * @throws SQLException
     * @throws ClassNotFoundException
     * @Author:lulei  
     * @Description: 数据库更新操作
     */
    public int update(String tableName, String columns, String condition, HashMap<Integer, Object> params) throws SQLException, ClassNotFoundException {
        String sql = updateSql(tableName, columns, condition);
        return dbOperation.executeUpdate(sql, params);
    }

    /**
     * @param sql
     * @return
     * @throws SQLException
     * @Author:lulei  
     * @Description: 数据库查询操作 
     */
    public ResultSet select(String sql) throws SQLException {
        return dbOperation.executeQuery(sql);
    }

    /**
     * @param tableName
     * @param columns
     * @param condition
     * @return
     * @throws SQLException
     * @Author:lulei  
     * @Description: 数据库查询操作
     */
    public ResultSet select(String tableName, String columns, String condition) throws SQLException {
        String sql = "select " + columns + " from " + tableName + " " + condition;
        return dbOperation.executeQuery(sql);
    }

    /**
     * @param tableName
     * @param columns
     * @param condition
     * @return
     * @Author:lulei  
     * @Description: 组装 update sql eg: update tableName set column1=?,column2=? condition 
     */
    private String updateSql(String tableName, String columns, String condition) {
        if (tableName == null || columns == null) {
            return "";
        }
        String[] column = columns.split(",");
        StringBuilder sb = new StringBuilder();
        sb.append("update ");
        sb.append(tableName);
        sb.append(" set ");
        sb.append(column[0]);
        sb.append("=?");
        for (int i = 1; i < column.length; i++) {
            sb.append(", ");
            sb.append(column[i]);
            sb.append("=?");
        }
        sb.append(" ");
        sb.append(condition);
        return sb.toString();
    }

    /**
     * @param tableName
     * @param columns
     * @return
     * @Author:lulei  
     * @Description: 组装 insert sql eg: insert into tableName (column1, column2) values (?,?)
     */
    private String insertSql(String tableName, String columns) {
        if (tableName == null || columns == null) {
            return "";
        }
        int n = columns.split(",").length;
        StringBuilder sb = new StringBuilder("");
        sb.append("insert into ");
        sb.append(tableName);
        sb.append(" (");
        sb.append(columns);
        sb.append(") values (?");
        for (int i = 1; i < n; i++) {
            sb.append(",?");
        }
        sb.append(")");
        return sb.toString();
    }

}

参考资料:
[极客学院]

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值