JDBC 数据库连接池 Druid

501 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情

写在前面👀

这篇文章主要讲Druid数据库连接池的配置文件和工具类使用

一、数据库连接池

1️⃣什么是数据库连接池

  • 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。

2️⃣数据库连接池的好处

  • 因为建立数据库连接是一个非常耗时、耗资源的行为,所以通过连接池预先同数据库建立一些连接,放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完后再放回去,极大的提高了数据库连接的性能问题,节省了资源和时间

3️⃣Java常见连接池技术

  1. C3P0:是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。

  2. Druid:Druid不仅是一个数据库连接池,还包含一个ProxyDriver、一系列内置的JDBC组件库、一个SQL Parser。支持所有JDBC兼容的数据库,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等。

  3. Proxool:是一个Java SQL Driver驱动程序,提供了对选择的其它类型的驱动程序的连接池封装。可以非常简单的移植到现存的代码中,完全可配置,快速、成熟、健壮。可以透明地为现存的JDBC驱动程序增加连接池功能。

  4. DBCP:DBCP是一个依赖Jakarta commons-pool对象池机制的数据库连接池,DBCP可以直接的在应用程序中使用,Tomcat的数据源使用的就是DBCP。

二、Druid连接池技术

Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。-----来自阿里官方的自信介绍

1️⃣Druid相关资料

1.Druid官方文档

2.Druid官方下载地址

2️⃣导入Druid的jar包

  • 这里以druid-1.0.9.jar为例演示
  • 提示:MySQL驱动包也要导入哦
  • 添加为库文件

image.png

3️⃣定义配置文件

  • 文件类型:.properties
  • 文件名就叫druid.properties
  • 放在src包下
# 注册驱动,可以缺省,会根据url自动识别
driverClassName=com.mysql.cj.jdbc.Driver
# 数据库连接地址
url=jdbc:mysql://127.0.0.1:3306/db
# 数据库管理员名称
username=root
# 数据库密码
password=123456
##初始连接数,默认0
initialSize=5
# 最大连接数,默认8
maxActive=10
# 最小闲置数
minIdle=10
# 获取连接的最大等待时间,单位毫秒
maxWait=3000
  • 演示结果如下👇

image.png

  • 踩坑记录:将.properties文件编码格式改为utf-8才能添加中文注释哦,不然会报错

image.png

4️⃣测试连接

public class testDruid {


    @Test
    public void test() {
        Connection coon = null;
        try {
            //加载配置文件
            Properties pr = new Properties();
            InputStream is = testDruid.class.getClassLoader().getResourceAsStream("druid.properties");
            pr.load(is);
            //获取连接池对象
            DataSource dataSource = DruidDataSourceFactory.createDataSource(pr);
            //获取连接
            coon = dataSource.getConnection();
            //测试连接是否成功
            if (coon != null) System.out.println("Druid连接成功~");
        } catch (Exception e) {
            e.printStackTrace();
        }
        //关闭连接。实际上是将连接归还给连接池
        try {
            if (coon != null) {
                coon.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
  • 测试结果如下👇
  • 上面一串红是正常的日志提示

image.png

三、添加工具类

为了提高代码的重复利用率,我们可以为Druid添加一个工具类

1️⃣定义DruidUtils工具类

public class DruidUtils {
    private static DataSource ds;

    static {
        //加载配置文件和建立连接池
        try {
            Properties pro = new Properties();
            InputStream resourceAsStream = DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties");
            pro.load(resourceAsStream);
            ds = DruidDataSourceFactory.createDataSource(pro);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取数据库连接池
     */
    public static DataSource getDataSource() {
        return ds;
    }

    /**
     * 获取连接池中的一个连接
     */
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

    /**
     * 关闭数据库的资源  三个对象都存在时
     *
     * @param conn
     * @param res
     * @param pstmt
     */
    public static void close(Connection conn, ResultSet res, PreparedStatement pstmt) {
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (res != null) {
            try {
                res.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (pstmt != null) {
            try {
                pstmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 关闭数据库的连接(只存在Connection和PreparedStatement对象时)
     *
     * @param conn
     * @param pstmt
     */
    public static void close(Connection conn, PreparedStatement pstmt) {
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (pstmt != null) {
            try {
                pstmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

2️⃣测试一下

public class DruidDemo {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            //1.获取连接对象
            conn = DruidUtils.getConnection();
            //2.定义SQL语句
            String sql = "insert into user values(2,?,?) ";
            //3.获取pstmt对象
            pstmt = conn.prepareStatement(sql);
            //4.给字段赋值
            pstmt.setString(1, "倔强的牛角");
            pstmt.setString(2, "88888888");
            //5.执行SQL语句
            int count = pstmt.executeUpdate();
            System.out.println("受影响的行数:" + count);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DruidUtils.close(conn, pstmt);
        }
    }
}
  • 演示结果如下👇

image.png

写在后面🍻

感谢观看啦✨
有什么不足,欢迎指出哦💖
掘金的运营同学审核辛苦了💗