c3p0、Druid连接池+工具类 Apache-DbUtils (详解!!!)

        数据库连接池是在应用程序启动时创建一定数量的数据库连接,并将这些连接存储在池中。当应用程序需要与数据库通信时,它可以向池中请求一个连接,使用完后将连接归还给池,而不是关闭连接。这样可以减少创建和关闭连接的开销,提高应用程序的性能。

一、Apache-DbUtils工具类

        Apache DbUtils 是一个简化 JDBC 编程的开源工具类库,它封装了 JDBC API 中的许多重复性任务,如结果集的处理、连接的管理等。DbUtils 提供了几个核心类和接口,帮助开发者更高效地编写数据库访问代码。

1.安装commons-dbutils-1.3.jar

下载官网:DbUtils – Download Apache Commons DbUtils

下载后将jar文件复制粘贴到idea的lib目录

在IDEA中,右击jar包,选择“Add as Library”将其添加到项目库中

2.核心类与接口

类/接口作用
QueryRunnerQueryRunner 是 DbUtils 中最常用的类之一,它简化了执行 SQL 查询和更新的过程。QueryRunner 使用 DataSource 来获取数据库连接,并在执行完操作后自动关闭连接。
ResultSetHandlerResultSetHandler 是一个接口,用于将 ResultSet 转换为其他对象。DbUtils 提供了多个实现类,如 BeanHandlerBeanListHandlerColumnListHandlerScalarHandler 等。
DbUtils工具类,提供静默关闭连接、提交事务等辅助方法 
BasicRowProcessor BasicRowProcessor 是一个用于处理 ResultSet 的类,它负责将 ResultSet 中的数据映射到 Java 对象。BasicRowProcessor 可以与 ResultSetHandler 一起使用。

二、c3p0的配置与运用

        C3P0是一个开源的JDBC连接池,它实现了数据源和连接池的管理。C3P0提供了很多功能,比如连接测试、自动回收空闲连接、支持多种数据库等等。

下载官网:c3p0:JDBC DataSources/Resource Pools download | SourceForge.net

解压下载的压缩包,所需的jar包位于解压后的lib目录下,主要包括:

  • c3p0-0.9.5.5.jar
  • c3p0-oracle-thin-extras-0.9.5.5.jar
  • mchange-commons-java-0.2.19.jar
  1. 添加jar包到IDEA项目

    • 将下载并解压后的jar包文件(如c3p0-0.9.5.5.jarmchange-commons-java-0.2.19.jar)复制到项目的lib目录下。
    • 在IDEA中,右击这些jar包,选择“Add as Library”将其添加到项目库中

    2.创建和配置c3p0-config.xml文件

    • 在项目的src目录下新建一个名为c3p0-config.xml的文件,配置数据库连接池的相关参数。例如:
    <c3p0-config><named-config name="my">
    <!-- 驱动类 --><property name="driverClass">com.mysql.cj.jdbc.Driver</property><!-- url--><property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/mydb</property><!-- 用户名 --><property name="user">root</property><!-- 密码 --><property name="password">root</property><!-- 每次增长的连接数--><property name="acquireIncrement">5</property><!-- 初始的连接数 --><property name="initialPoolSize">10</property><!-- 最小连接数 --><property name="minPoolSize">5</property><!-- 最大连接数 --><property name="maxPoolSize">10</property><!-- 可连接的最多的命令对象数 --><property name="maxStatements">5</property> <!-- 每个连接对象可连接的最多的命令对象数 --><property name="maxStatementsPerConnection">2</property></named-config>
    </c3p0-config>

    注意:

    (1).我用的mysql是8.0版本所以类名是com.mysql.cj.jdbc.Driver

    (2).文件名不要写错了,尽量fic3p0-config.xml

    3.使用c3p0连接池+Apache-DbUtils工具类:

    例如:c3p0连接池连接MySQL+Apache-DbUtils的QueryRunner类,查询数据

    import DAO_.Bean.Student; // 引入Student类
    import com.mchange.v2.c3p0.ComboPooledDataSource; // 引入连接池类
    import org.apache.commons.dbutils.QueryRunner; // 引入查询运行器类
    import org.apache.commons.dbutils.handlers.BeanListHandler; // 引入结果集处理类
    import java.beans.PropertyVetoException; // 引入属性否定异常
    import java.io.FileInputStream; // 引入文件输入流
    import java.io.FileNotFoundException; // 引入文件未找到异常
    import java.io.IOException; // 引入IO异常
    import java.sql.Connection; // 引入数据库连接接口
    import java.sql.SQLException; // 引入SQL异常
    import java.util.List; // 引入列表接口
    import java.util.Properties; // 引入属性类public class A {public static void main(String[] args) {// 加载配置文件Properties properties = new Properties();try (FileInputStream fis = new FileInputStream("src/mysql.properties")) {properties.load(fis);} catch (FileNotFoundException e) {System.err.println("配置文件未找到!");return;} catch (IOException e) {System.err.println("读取配置文件失败!");return;}// 从配置文件中获取数据库连接信息String url = properties.getProperty("url");String user = properties.getProperty("user");String password = properties.getProperty("password");String driver = properties.getProperty("driver");// 创建数据库连接池ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();try {comboPooledDataSource.setPassword(password);comboPooledDataSource.setUser(user);comboPooledDataSource.setJdbcUrl(url);comboPooledDataSource.setDriverClass(driver);comboPooledDataSource.setInitialPoolSize(50);comboPooledDataSource.setMaxPoolSize(100);} catch (PropertyVetoException e) {System.err.println("设置数据库连接池参数失败!");return;}// 从连接池中获取数据库连接try (Connection connection = comboPooledDataSource.getConnection()) {// SQL查询语句String sql = "select * from t2;";// 创建查询运行器QueryRunner queryRunner = new QueryRunner();// 执行查询,并将结果集转换为Student对象的列表List<Student> students = queryRunner.query(connection, sql, new BeanListHandler<>(Student.class));// 遍历并打印学生信息for (Student student : students) {System.out.println(student);}//关闭连接connection.close();} catch (SQLException e) {System.err.println("数据库操作失败!");}}
    }

    查询结果: 


    三、Druid连接池的配置与运用

            Druid是阿里巴巴开源的数据库连接池,不仅提供连接池管理,还包含强大的监控和扩展能力,性能优秀,尤其适用于高并发场景。

    1.安装druid-1.1.10.jar

    下载地址:Central Repository: com/alibaba/druid/1.2.23 (maven.org)

    和以上连接池一样操作,这里就不演示了

    2.创建和配置druid.properties文件

    #key=value
    driverClassName=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql://localhost:3306/mydb?rewriteBatchedStatements=true
    #url=jdbc:mysql://localhost:3306/mydb
    username=root
    password=root
    #initial connection Size
    initialSize=10
    #min idle connecton size
    minIdle=5
    #max active connection size
    maxActive=20
    #max wait time (5000 mil seconds)
    maxWait=5000

    3.使用Druid连接池+Apache-DbUtils工具类:

    例如:Druid连接池连接MySQL+Apache-DbUtils的QueryRunner类,查询数据

    import DAO_.Bean.Student; // 引入Student类
    import com.alibaba.druid.pool.DruidDataSourceFactory;
    import org.apache.commons.dbutils.QueryRunner; // 引入查询运行器类
    import org.apache.commons.dbutils.handlers.BeanListHandler; // 引入结果集处理类
    import javax.sql.DataSource;
    import java.io.FileInputStream; // 引入文件输入流
    import java.io.FileNotFoundException; // 引入文件未找到异常
    import java.io.IOException; // 引入IO异常
    import java.sql.Connection; // 引入数据库连接接口
    import java.sql.SQLException; // 引入SQL异常
    import java.util.List; // 引入列表接口
    import java.util.Properties; // 引入属性类public class Test{public static void main(String[] args) {// 加载配置文件Properties properties = new Properties();try (FileInputStream fis = new FileInputStream("src/druid.properties")) {properties.load(fis);} catch (FileNotFoundException e) {System.err.println("配置文件未找到!");return;} catch (IOException e) {System.err.println("读取配置文件失败!");return;}Connection connection;// 创建数据库连接池try {DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);connection = dataSource.getConnection();} catch (Exception e) {throw new RuntimeException(e);}// 从连接池中获取数据库连接try {// SQL查询语句String sql = "select * from t2;";// 创建查询运行器QueryRunner queryRunner = new QueryRunner();// 执行查询,并将结果集转换为Student对象的列表List<Student> students = queryRunner.query(connection, sql, new BeanListHandler<>(Student.class));// 遍历并打印学生信息for (Student student : students) {System.out.println(student);}//关闭连接connection.close();} catch (SQLException e) {System.err.println("数据库操作失败!");}}
    }

    查询结果: 

    补充:Druid连接池的二次封装-->DruidUtil

    package DAO_.Utils;import com.alibaba.druid.pool.DruidDataSourceFactory; // 导入Druid数据源工厂类
    import javax.sql.DataSource; // 导入数据源接口
    import java.io.FileInputStream; // 导入文件输入流类
    import java.sql.Connection; // 导入数据库连接接口
    import java.sql.ResultSet; // 导入结果集接口
    import java.sql.SQLException; // 导入SQL异常类
    import java.sql.Statement; // 导入SQL语句接口
    import java.util.Properties; // 导入属性类public class DruidUtil {private static DataSource dataSource; // 定义数据源对象,用于获取数据库连接static {Properties properties = new Properties(); // 创建属性对象,用于加载配置文件try {properties.load(new FileInputStream("src\\druid.properties")); // 加载配置文件dataSource = DruidDataSourceFactory.createDataSource(properties); // 根据配置文件创建数据源} catch (Exception e) {throw new RuntimeException(e); // 如果出现异常,抛出运行时异常}}/*** 获取数据库连接** @return 数据库连接对象* @throws SQLException 如果获取连接失败,抛出SQL异常*/public static Connection getconnection() throws SQLException {return dataSource.getConnection(); // 从数据源获取数据库连接}/*** 关闭数据库资源** @param resultSet  结果集对象* @param connection 数据库连接对象* @param statement  SQL语句对象*/public static void close(ResultSet resultSet, Connection connection, Statement statement) {try {if (resultSet != null) {resultSet.close(); // 如果结果集对象不为空,则关闭结果集}if (connection != null) {connection.close(); // 如果连接对象不为空,则关闭连接}if (statement != null) {statement.close(); // 如果语句对象不为空,则关闭语句}} catch (SQLException e) {throw new RuntimeException(e); // 如果关闭过程中出现异常,抛出运行时异常}}
    }
    

    封装好的方法可以直接调用连接和关闭

    例如:

    @Test
    // 使用BeanListHandler来处理查询结果,将每行数据转换为Student对象,并存储在ArrayList集合中返回
    public void test() throws SQLException {Connection connection = DruidUtil.getconnection(); // 获取数据库连接String sql = "select * from t2 where id =?"; // 定义SQL查询语句,参数占位符为?QueryRunner queryRunner = new QueryRunner(); // 创建QueryRunner对象,用于执行SQL语句// 执行查询操作,将结果集转换为List<Student>对象// 参数说明:connection - 数据库连接对象;sql - SQL查询语句;new BeanListHandler<Student>(Student.class) - 结果集处理方式,将每行数据转换为Student对象;1 - SQL语句中的参数值,对应占位符?List<Student> students = queryRunner.query(connection, sql, new BeanListHandler<Student>(Student.class), 1);// 遍历List集合,打印每个Student对象for (Student student : students) {System.out.println(student);}// 关闭数据库连接,释放资源// 参数说明:null - 结果集对象,此处为null because no ResultSet is used;connection - 数据库连接对象;null - SQL语句对象,此处为null because no Statement is explicitly createdDruidUtil.close(null, connection, null);
    }
    

    四、C3P0与Druid的比较

    • 性能

      • Druid在高并发环境下性能优于C3P0。
    • 扩展性

      • Druid支持过滤器机制,易于扩展功能,如SQL日志记录、权限控制等。
      • C3P0的扩展性不如Druid。
    • 配置复杂度

      • C3P0配置相对简单,易于上手。
      • Druid配置较为复杂,学习曲线较陡。

    比较的代码:

    测试c3p0连接MySQL50万次:

     @Test
    // 测试使用c3p0连接池获取数据库连接public void TestPool() throws IOException, PropertyVetoException, SQLException {Properties properties = new Properties();// 加载配置文件properties.load(new FileInputStream("src\\mysql.properties"));// 从配置文件中获取数据库连接信息String user = properties.getProperty("user");String password = properties.getProperty("password");String driver = properties.getProperty("driver");String url = properties.getProperty("url");// 创建c3p0连接池数据源实例ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();// 设置数据库连接驱动comboPooledDataSource.setDriverClass(driver);// 设置数据库用户名comboPooledDataSource.setUser(user);// 设置数据库URLcomboPooledDataSource.setJdbcUrl(url);// 设置数据库密码comboPooledDataSource.setPassword(password);// 设置连接池的初始大小comboPooledDataSource.setInitialPoolSize(50);// 设置连接池的最大大小comboPooledDataSource.setMaxPoolSize(100);// 记录开始时间long l = System.currentTimeMillis();// 循环获取和释放连接,测试连接池性能for (int i = 0; i < 500000; i++) {Connection connection = comboPooledDataSource.getConnection(user, password);connection.close();}// 记录结束时间long l1 = System.currentTimeMillis();// 打印连接池获取连接所需的总时间System.out.println("连接的时间:"+(l1-l));}
    

    结果: 

     

     测试druid连接MySQL50万次:

    @Test
    // 测试使用druid连接池获取数据库连接public void testDruid() throws Exception {Properties properties = new Properties();// 加载druid连接池配置文件properties.load(new FileInputStream("src\\druid.properties"));// 使用DruidDataSourceFactory创建数据源实例DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);// 记录开始时间long l = System.currentTimeMillis();// 循环获取和释放连接,测试连接池性能for (int i = 0; i < 500000; i++) {Connection connection = dataSource.getConnection();connection.close();}// 记录结束时间long l1 = System.currentTimeMillis();// 打印连接池获取连接所需的总时间System.out.println("时间是:"+(l1-l));}

    结果: 

    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/23632.html

    如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

    相关文章

    数仓搭建实操(传统数仓oracle):DWD数据明细层

    数据处理思路 DWD层, 数据明细层>>数据清洗转换, 区分事实表,维度表 全是事实表,没有维度表>>不做处理 数据清洗>>数据类型varchar 变成varchar2, 日期格式统一(时间类型变成varchar2); 字符数据去空格 知识补充: varchar 存储定长字符类型 ; 存储的数据会…

    2.1 第一个程序:从 Hello World 开始

    版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 同大多数编程语言教程一样&#xff0c;本书第一个代码也是输出&#xff1a;Hello world! 这似乎也是惯例。我们也先从这个简单的代码…

    2025年02月21日Github流行趋势

    项目名称&#xff1a;source-sdk-2013 项目地址url&#xff1a;https://github.com/ValveSoftware/source-sdk-2013项目语言&#xff1a;C历史star数&#xff1a;7343今日star数&#xff1a;929项目维护者&#xff1a;JoeLudwig, jorgenpt, narendraumate, sortie, alanedwarde…

    【WSL2】 Ubuntu20.04 GUI图形化界面 VcXsrv ROS noetic Vscode 配置

    【WSL2】 Ubuntu20.04 GUI图形化界面 VcXsrv ROS noetic Vscode 配置 前言整体思路安装 WSL2Windows 环境升级为 WIN11 专业版启用window子系统及虚拟化 安装WSL2通过 Windows 命令提示符安装 WSL安装所需的 Linux 发行版&#xff08;如 Ubuntu 20.04&#xff09;查看和设置 WS…

    7.建立文件版题库|编写model文件|使用boost split字符串切分(C++)

    建立文件版题库 题目的编号题目的标题题目的难度题目的描述&#xff0c;题面时间要求(内部处理)空间要求(内部处理) 两批文件构成第一个&#xff1a;questions.list : 题目列表&#xff08;不需要题目的内容&#xff09;第二个&#xff1a;题目的描述&#xff0c;题目的预设置…

    LabVIEW中CFURL.llb 工具库说明

    CFURL.llb 是 LabVIEW 2019 安装目录下 C:\Program Files (x86)\National Instruments\LabVIEW 2019\vi.lib\Platform\ 路径下的工具库&#xff0c;主要用于处理 LabVIEW 与 URL 相关的操作&#xff0c;涵盖 URL 解析、HTTP 请求发送、数据传输等功能模块&#xff0c;帮助开发者…

    网络运维学习笔记 017 HCIA-Datacom综合实验01

    文章目录 综合实验1实验需求总部特性 分支8分支9 配置一、 基本配置&#xff08;IP二层VLAN链路聚合&#xff09;ACC_SWSW-S1SW-S2SW-Ser1SW-CoreSW8SW9DHCPISPGW 二、 单臂路由GW 三、 vlanifSW8SW9 四、 OSPFSW8SW9GW 五、 DHCPDHCPGW 六、 NAT缺省路由GW 七、 HTTPGW 综合实…

    6.✨Python学习价值与优势分析

    ✨Python 是一种值得深入学习的编程语言&#xff0c;其设计哲学、广泛的应用场景以及强大的社区支持使其成为当今最受欢迎的编程语言之一。以下从多个角度分析为什么 Python 值得深入学习&#xff1a; 1.&#x1f98b; 简洁易学的语法 Python 以简洁、可读性强著称&#xff0c…

    Android Audio其他——数字音频接口(附)

    数字音频接口 DAI,即 Digital Audio Interfaces,顾名思义,DAI 表示在板级或板间传输数字音频信号的方式。相比于模拟接口,数字音频接口抗干扰能力更强,硬件设计简单,DAI 在音频电路设计中得到越来越广泛的应用。 一、音频链路 1、模拟音频信号 可以看到在传统的…

    Spring AI + Ollama 实现调用DeepSeek-R1模型API

    一、前言 随着人工智能技术的飞速发展&#xff0c;大语言模型&#xff08;LLM&#xff09;在各个领域的应用越来越广泛。DeepSeek 作为一款备受瞩目的国产大语言模型&#xff0c;凭借其强大的自然语言处理能力和丰富的知识储备&#xff0c;迅速成为业界关注的焦点。无论是文本生…

    2.3 变量

    版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 变量是用来存放某个值的数据&#xff0c;它可以表示一个数字、一个字符串、一个结构、一个类等。变量包含名称、类型和值。在代码中…

    LLM大语言模型私有化部署-使用Dify的工作流编排打造专属AI诗词数据分析师

    背景 前面的文章通过 Ollama 私有化部署了 Qwen2.5 (7B) 模型&#xff0c;然后使用 Docker Compose 一键部署了 Dify 社区版平台。 LLM大语言模型私有化部署-使用Dify与Qwen2.5打造专属知识库&#xff1a;在 Dify 平台上&#xff0c;通过普通编排的方式&#xff0c;创建了基于…

    ESP32S3:参考官方提供的led_strip组件使用 SPI + DMA 方式驱动WS2812 RGB灯的实现思路 (实现各个平台移植使用该方式)

    目录 引言使用SPI + DMA 方式实现思路分析1. 查看WS2812的datasheet手册2. 根据官方的led_strip组件的方式,自己手把手实现一遍3.完整的程序(实现霓虹灯效果)引言 参考官方提供的led_strip组件使用 SPI + DMA 方式驱动WS2812 RGB灯的实现思路,只有明白实现的思路,方能将其…

    工程师 - VSCode的AI编码插件介绍: MarsCode

    豆包 MarsCode MarsCode AI: Coding Assistant Code and Innovate Faster with AI 豆包 MarsCode - 编程助手 安装完成并使能后&#xff0c;会在下方状态栏上显示MarsCode AI。 安装完并重启VSCode后&#xff0c;要使用这个插件&#xff0c;需要注册一下账号。然后授权VSCod…

    DPVS-5: 后端服务监控原理与测试

    后端监控原理 被动监测 DPVS自带了被动监控&#xff0c;通过监控后端服务对外部请求的响应情况&#xff0c;判断服务器是否可用。 DPVS的被动监测&#xff0c;并不能获取后端服务器的详细情况&#xff0c;仅仅通过丢包/拒绝情况来发觉后端服务是否可用。 TCP session state…

    Tag标签的使用

    一个非常适合运用在vue项目中的组件&#xff1a;Tag标签。 目录 一、准备工作 1、安装element-plus库 2、配置element-plus库 二、Tag标签入门 1、打开element官网&#xff0c;搜索tag标签 2、体验Tag标签的基础用法 三、Tag标签进阶训练1 1、定义一个数组&#xff0c;…

    算法-图-数据结构(邻接矩阵)-BFS广度优先遍历

    邻接矩阵广度优先遍历&#xff08;BFS&#xff09;是一种用于遍历或搜索图的算法&#xff0c;以下是具体介绍&#xff1a; 1. 基本概念 图是一种非线性的数据结构&#xff0c;由顶点和边组成&#xff0c;可分为无向图、有向图、加权图、无权图等。邻接矩阵是表示图的一种数…

    Ryu:轻量开源,开启 SDN 新程

    1. Ryu 控制器概述 定位&#xff1a;轻量级、开源的SDN控制器&#xff0c;专为开发者和研究人员设计&#xff0c;基于Python实现。开发者&#xff1a;由日本NTT实验室主导开发&#xff0c;遵循Apache 2.0开源协议。核心理念&#xff1a;简化SDN应用开发&#xff0c;提供友好的…

    内容中台架构下智能推荐系统的算法优化与分发策略

    内容概要 在数字化内容生态中&#xff0c;智能推荐系统作为内容中台的核心引擎&#xff0c;承担着用户需求与内容资源精准匹配的关键任务。其算法架构的优化路径围绕动态特征建模与多模态数据融合展开&#xff0c;通过深度强化学习技术实现用户行为特征的实时捕捉与动态更新&a…

    【odoo18-文件管理】在uniapp上访问odoo系统上的图片

    在uniapp上访问odoo系统上的图片 1、以url的形式访问 a&#xff1a;以odoo本身的域名&#xff0c;比如http://127.0.0.1:8069/web/image/product.template/3/image_128?unique1740380422000&#xff0c;这种方式需要解决跨域的问题。 b&#xff1a;以文件服务器的形式&…