当前位置: 首页 > news >正文

Druid数据库连接池

原生的jdbc,每次查询都会创建新的连接对象

package com.ruoyi.deno;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;/*** User: ldj* Date: 2025/7/31* Time: 19:20* Description: No Description*/
public class JdbcExample {public static void main(String[] args) {Connection conn = null;Statement stmt = null;ResultSet rs = null;try {// 1. 加载JDBC驱动程序Class.forName("com.mysql.cj.jdbc.Driver");// 2. 建立连接String url = "jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8";String user = "root";String password = "password";conn = DriverManager.getConnection(url, user, password);// 3. 创建Statement对象stmt = conn.createStatement();// 4. 执行查询String sql = "SELECT id, name FROM employees";rs = stmt.executeQuery(sql);// 5. 处理结果集while (rs.next()) {int id = rs.getInt("id");String name = rs.getString("name");System.out.println("ID: " + id + ", Name: " + name);}} catch (Exception e) {e.printStackTrace();} finally {// 6. 关闭资源try { if (rs != null) rs.close(); } catch (Exception e) { /* ignored */ }try { if (stmt != null) stmt.close(); } catch (Exception e) { /* ignored */ }try { if (conn != null) conn.close(); } catch (Exception e) { /* ignored */ }}}
}

使用连接池后,会复用连接对象

package com.ruoyi.deno;import com.alibaba.druid.pool.DruidDataSource;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;/*** User: ldj* Date: 2025/7/31* Time: 19:22* Description: No Description*/
public class DruidJdbcExample {private static DruidDataSource dataSource;static {dataSource = new DruidDataSource();dataSource.setUrl("jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8");dataSource.setUsername("root");dataSource.setPassword("password");// 其他配置...}public static void main(String[] args)  throws Exception {Connection conn = null;PreparedStatement pstmt = null;ResultSet rs = null;try {// 从连接池中获取连接 (是代理对象Proxy)conn = dataSource.getConnection();// 准备SQL语句String sql = "SELECT id, name FROM employees WHERE id = ?";pstmt = conn.prepareStatement(sql);pstmt.setInt(1, 1); // 设置参数// 执行查询rs = pstmt.executeQuery();// 处理结果集while (rs.next()) {int id = rs.getInt("id");String name = rs.getString("name");System.out.println("ID: " + id + ", Name: " + name);}} finally {// 关闭资源if (rs != null) rs.close();if (pstmt != null) pstmt.close();// 注意这里的close()实际上是把连接归还给连接池 (因为 Druid 返回给你的 Connection 对象,是一个“伪装者”(代理对象),它把 .close() 这个动作“偷梁换柱”了)if (conn != null) conn.close();}}
}

补充:springboot 整合Druid的配置文件,这里有扩展的功能读写分离开启慢sql记录,按照以往的做法是直接修改MySQL 配置文件 (my.cnf 或 my.ini)

你可以编辑 MySQL 的配置文件来启用慢查询日志

[mysqld]
slow_query_log = 1
slow_query_log_file = /path/to/your/slow-query.log
long_query_time = 2  # 设置慢查询的时间阈值,单位秒
log_queries_not_using_indexes = 1  # 是否记录未使用索引的查询

现在不需要那样干了,直接在application.yml修改就行 

# 数据源配置
spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: com.mysql.cj.jdbc.Driverdruid:# 主库数据源 (修改自己的地址、账号、密码)master:url: jdbc:mysql://192.168.208.110:3306/ruoyi?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: rootpassword: root# 从库数据源slave:# 从数据源开关/默认关闭enabled: falseurl: username: password: # 初始连接数initialSize: 5# 最小连接池数量minIdle: 10# 最大连接池数量maxActive: 20# 配置获取连接等待超时的时间maxWait: 60000# 配置连接超时时间connectTimeout: 30000# 配置网络超时时间socketTimeout: 60000# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒timeBetweenEvictionRunsMillis: 60000# 配置一个连接在池中最小生存的时间,单位是毫秒minEvictableIdleTimeMillis: 300000# 配置一个连接在池中最大生存的时间,单位是毫秒maxEvictableIdleTimeMillis: 900000# 配置检测连接是否有效 'SELECT 1 FROM DUAL' 是 Oracle/MySQL 的通用心跳语句validationQuery: SELECT 1 FROM DUAL# 空闲时检测连接是否有效(推荐开启)testWhileIdle: true# 从池中取出连接时检测数据库连接是否仍然有效(影响性能,通常关闭)testOnBorrow: false# 归还连接时检测数据库连接是否仍然有效(也影响性能,一般关闭)testOnReturn: falsewebStatFilter: enabled: truestatViewServlet:enabled: true# 设置白名单,不填则允许所有访问allow:url-pattern: /druid/*# Druid控制台管理用户名和密码 (http://localhost:8080/druid/login.html)login-username: ruoyilogin-password: 12345filter:stat:enabled: true# 慢SQL记录log-slow-sql: trueslow-sql-millis: 1000merge-sql: truewall:config:multi-statement-allow: true

整合spring-boot注意的地方:排除SpringBoot数据源自动配置类

/*** 启动程序** @author ruoyi* DataSourceAutoConfiguration 检查你有没有配置数据库连接(如 spring.datasource.url, username, password)* 如果有,就自动创建一个 DataSource Bean(通常是 HikariCP 连接池), 让你的应用可以直接使用数据库(比如配合 JPA、MyBatis 等)* 我现在使用的Druid的连接池,不要SpringBoot默认的配置的 HikariCP*/
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class RuoYiApplication {public static void main(String[] args) {// System.setProperty("spring.devtools.restart.enabled", "false");SpringApplication.run(RuoYiApplication.class, args);System.out.println("(♥◠‿◠)ノ゙  若依启动成功   ლ(´ڡ`ლ)゙  \n" +" .-------.       ____     __        \n" +" |  _ _   \\      \\   \\   /  /    \n" +" | ( ' )  |       \\  _. /  '       \n" +" |(_ o _) /        _( )_ .'         \n" +" | (_,_).' __  ___(_ o _)'          \n" +" |  |\\ \\  |  ||   |(_,_)'         \n" +" |  | \\ `'   /|   `-'  /           \n" +" |  |  \\    /  \\      /           \n" +" ''-'   `'-'    `-..-'              ");}
}

场景1:如果你已经写了一个配置类来创建 DataSource Bean:

@Configuration
public class DataSourceConfig {@Beanpublic DataSource dataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setUrl("jdbc:mysql://localhost:3306/mydb");dataSource.setUsername("root");dataSource.setPassword("123456");return dataSource;}
}

这时候,Spring Boot 的 DataSourceAutoConfiguration 也想创建一个 DataSource(默认是 Hikari),就会导致:

❌ 报错:有多个 DataSource Bean,不知道该注入哪一个

 场景2:只要你引入了 spring-boot-starter-jdbcmybatis-spring-boot-starter或者mybatis-plus,Spring Boot 就会尝试自动配置数据源。如果没有排除,启动时会报错:

Failed to configure a DataSource: 'url' attribute is not specified

解决办法:排除自动配置,告诉 Spring Boot:“别管数据库了,我自己来!”  

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})

Druid 还提供功能非常强大的可视化监控面板,账号和密码自定义(http://localhost:8080/druid/login.html

http://www.lryc.cn/news/605651.html

相关文章:

  • MongoDB系列教程-第四章:MongoDB Compass可视化和管理MongoDB数据库
  • 使用 Elasticsearch 和 AI 构建智能重复项检测
  • Jmeter 命令行压测、HTML 报告、Jenkins 配置目录
  • HTML-取消div,a等标签点击效果
  • 深入探索Weaviate:构建高效AI应用的数据库解决方案
  • 常用设计模式系列(十七)—命令模式
  • LCM中间件入门(2):LCM核心实现原理解析
  • 《人工智能导论》(python版)第2章 python基础2.2编程基础
  • [算法]Leetcode3487
  • Video_1920×1080i 1920_1080p
  • 大白话解释---FreeRTOS中的队列集
  • 基于知识驱动的解释性条件扩散模型用于无对比剂心肌梗死增强合成|文献速递-医学影像算法文献分享
  • CSS和XPATH选择器对比
  • 《Java 程序设计》第 15 章 - 事件处理与常用控件
  • Vibe Coding:AI驱动开发的安全暗礁与防护体系
  • 异步I/O和同步I/O
  • Day15--二叉树--222. 完全二叉树的节点个数,110. 平衡二叉树,257. 二叉树的所有路径,404. 左叶子之和
  • 在Linux中创建LVGL应用
  • Kotlin -> 普通Lambda vs 挂起Lambda
  • 【Django】-1- 开发项目搭建
  • Django模型迁移指南:从命令用法到最佳实践
  • HttpServletRequest详细解释
  • 如何在NPM上发布自己的React组件(包)
  • 人工智能概念之十一:常见的激活函数与参数初始化
  • Cesium 快速入门(四)相机控制完全指南
  • langchain--1--prompt、output格式、LCEL示例
  • 【烧脑算法】Dijkstra 算法:解决最短路问题
  • 会议室预定系统核心技术:如何用一行SQL解决时间冲突检测难题
  • LLC电源原边MOS管DS增加RC吸收对ZVS的影响分析
  • ode with me是idea中用来干嘛的插件