Phase2 Day23 数据库连接池&DbUtils

数据库连接池

所谓的数据库连接池技术,就是用来分配,管理,释放数据库连接的。我们以前用 JDBC 操作数据库的时候,每次操作完都会将连接关闭。数据库连接是极其宝贵的资源,频繁的创建和销毁会极大地降低服务器的性能。因此,我们可以利用池化技术,重复利用数据库资源,避免没必要的开销

MyConnectionPool

package com.cskaoyan.ds;

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.sql.*;
import java.util.Properties;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;

public class MyConnectionPool {
    private int INIT_SIZE;
    private int MAX_SIZE;
    private int size; //当前有多少个连接
    //queue用来存放空闲的连接
    private Queue<Connection> queue = new ArrayBlockingQueue<>(MAX_SIZE);
    private Properties info = new Properties();

    public MyConnectionPool() {
        try (Reader reader = new FileReader("pool.properties")) {
            info.load(reader);
        } catch (IOException e) {
            e.printStackTrace();
        }
        INIT_SIZE = Integer.parseInt(info.getProperty("INIT_SIZE"));
        MAX_SIZE = Integer.parseInt(info.getProperty("MAX_SIZE"));
        for (int i = 0; i < INIT_SIZE; i++) {
            Connection conn = createConnection();
            queue.offer(conn);
        }
    }

    private Connection createConnection() {
        String url = info.getProperty("url");
        String user = info.getProperty("user");
        String password = info.getProperty("password");
        Connection conn = null;
        try {
            Connection connection = DriverManager.getConnection(url, user, password);
            conn = new WorkConnection(connection);
            size++;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

    public Connection getConnection() {
        if (!queue.isEmpty()) return queue.poll();
        if (size < MAX_SIZE) return createConnection();
        throw new RuntimeException("数据库连接数目已达到最大");
    }

    private class WorkConnection extends ConnectionWrapper {
   	//ConnectionWrapper其实就是继承connection后将close方法改成了抽象方法,为了接下来重写close方法
        public WorkConnection(Connection conn) {
            super(conn);
        }

        @Override
        public void close() throws SQLException {
            if (queue.size() < INIT_SIZE) {
                queue.offer(this);
            } else {
                size--;
                conn.close();
            }
        }
    }
}


数据库连接池的优点

  • 数据库连接得以重用,避免了频繁创建和销毁引起的大量性能开销,同时也增加了系统的稳定性。
  • 数据库连接池在初始化过程中,往往就已经创建了若干个连接。因此可以提高系统的反应速度。、
  • 如果有多个应用共用一个 DBMS,由于 DBMS 的连接是有限的,因此我们可以通过数据库连接池限制一个应用最大的连接数目,避免某一应用独占所有的连接。
  • 在较为完善的数据库连接池中,可以设置占用超时,强制回收被占用的连接,从而避免了常规数据库连接操作中可能出现的资源泄露问题。

DbUtils

1.简介

commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对 JDBC 的简单封装,学习成本极低,使用 dbutils 可以简化 jdbc 编码的工作量,同时也不会影响程序的性能。

使用 DBUtils 需要导入 commons-dbutils-1.7.jar。DBUtils 有三个核心的组件:

  • QueryRunner:该类提供了 DML 和 DQL 的 API。
  • ResultSetHandler:该接口定义如何封装结果集。
  • DbUtils:一个简单的工具类,简化了关闭资源和事务处理,可以简化JDBC操作的模板代码

2.QueryRunner

2.1 构造方法
QueryRunner(); // 需要指定连接
QueryRunner(DataSource ds);  //从数据源中获取连接
2.2 常用API
<T> T query(Connection conn, String sql, ResultSetHandler<T> rsh, Object...params);
<T> T query(Connection conn, String sql, ResultSetHandler<T> rsh);
<T> T query(String sql, ResultSetHandler<T> rsh, Object... params);
<T> T query(String sql, ResultSetHandler<T> rsh);
int update(Connection conn, String sql, Object... params);
int update(Connection conn, String sql);
int update(String sql, Object... params);
int update(String sql);
int[] batch(Connection conn, String sql, Object[][] params)
int[] batch(String sql, Object[][] params)

2 ResultSetHandler

该接口用于处理 ResultSet,将查询返回的 ResultSet 按要求转换为另一种形式。该接口的定义如下

public interface ResultSetHandler<T> {
  T handle(ResultSet rs) throws SQLException;
}
2.1 实现类
  • ArrayHandler:把结果集中的第一行数据转成对象数组。
  • ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。
  • BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
  • BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
  • ColumnListHandler:将结果集中某一列的数据存放到List中。
  • KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。
  • MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值

使用 BeanHandler 和 BeanListHandler 需要注意以下几点:

  1. 对应的 JavaBean 必须提供无参构造方法。
  2. JavaBean 的属性名应该和返回结果的字段名相同。
  3. JavaBean 中必须提供公共的 Setter 方法。

3 DbUtils

提供如关闭连接、装载JDBC驱动程序等常规工作的工具类,里面的所有方法都是静态的

API

void close(Connection conn); //可以避免空指针异常
void close(ResultSet rs);
void close(Statement stmt);
void closeQuietly(Connection conn); //不需要判空, 处理异常
void closeQuietly(ResultSet rs);
void closeQuietly(Statement stmt);
void closeQuietly(Connection conn, Statement stmt, ResultSet rs);
void commitAndClose(Connection conn); // 提交事务并且关闭连接
void commitAndCloseQuietly(Connection conn);
boolean loadDriver(String driverClassName)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值