Spring boot 数据库连接池

Spring Boot 使用 Druid 数据库连接池详解
本文详细介绍了如何在 Spring Boot 中使用 Druid 数据库连接池,包括配置 Druid、添加依赖、设置监控功能,如开启监控 UI 页面、配置 SQL 日志打印、防火墙等,并讨论了 Druid 的优势和监控功能。

Spring boot 数据库连接池

上一节 Spring boot jdbcTemplate

Spring boot jdbcTemplate

源码

[源码地址]:(https://gitee.com/mayun_xiaodu/spring-boot-all)


Spring boot 数据库连接池

上一章节我们使用了jdbcTemplate 进行数据库的简单操作,这章我们给数据库连接添加上数据连接池。
springboot 默认数据库 Hikari

springboot 内置式默认支持HiKari 数据库连接池的;在 DataSourceConfiguration 配置类 中我可以看到
默认引入创建了HikariDatasource ; hikari 号称是 最快的数据库连接池,不过国内一般使用druid

	/**
	 * Hikari DataSource configuration.
	 */
	@Configuration
	@ConditionalOnClass(HikariDataSource.class)
	@ConditionalOnMissingBean(DataSource.class)
	@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource",
			matchIfMissing = true)
	static class Hikari {

		@Bean
		@ConfigurationProperties(prefix = "spring.datasource.hikari")
		public HikariDataSource dataSource(DataSourceProperties properties) {
			HikariDataSource dataSource = createDataSource(properties, HikariDataSource.class);
			if (StringUtils.hasText(properties.getName())) {
				dataSource.setPoolName(properties.getName());
			}
			return dataSource;
		}

	}

springboot 已经自动装配了 HikarDataSource 数据源所以我们只需要在配置文件中配置下连接池信息即可;
配置文件中使用 spring.hikari 前缀进行数据库连接配置

spring:
  application:
    name: test-jdbcPool
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/mytest?useSSL=false&charsetEncoding=utf8
    driver-class-name: com.mysql.jdbc.Driver
    hikari:
      maximum-pool-size: 10  # 最大连接数
      minimum-idle: 5 # 最小空闲数
      connection-timeout: 2000 # 获取连接超时时间; 默认30s
      pool-name: my-test-hikari # 连接池名称
      idle-timeout: 600000 # 空闲超时时间;默认是十分钟;空闲时间超过设定时间则会被回收
      auto-commit: true # 是否自动提交
      max-lifetime: 1800000 # 最大存活时间,默认30分钟
     # connection-test-query: SELECT 1  # 连接数据库后测试语句
      validation-timeout: 1000 #
      # schema: 设置模式,例如 postgresql 有模式这个概念

配置完以上后我们使用 jdbcTemplate 或者mybatis 等进行数据库操作的时候就会默认使用上HikarDataSource 进行数据库连接操作。

alibaba Druid 数据库连接池

简述
Druid是Java语言中综合最好的数据库连接池。Druid能够提供强大的监控和扩展功能;我们把springboot 默认的 数据库连接池 hikar 缓存Druid 。
使用 druid 数据库连接池的好处:

  • 开源,国内活跃度高
  • 性能好,国内号称是java里最好的数据库连接池
  • 功能多,提供了 sql统计,sql过滤,数据库密码加密等功能

druid github 地址


使用:

添加pom 依赖

我们这里选用druid 提供的springboot starter

 <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.18</version>
        </dependency>
配置连接池信息

配置文件中配置连接池信息

spring:
  # 数据源配置
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/mytest?useSSL=false&charsetEncoding=utf8
    driver-class-name: com.mysql.jdbc.Driver
    # 连接池配置
    druid:
      max-active: 10 # 最大活跃数量 默认8
      min-idle:  2 # 最小空闲数 默认0
      initial-size: 5 # 初始连接数
      max-wait: 2000 # 获取连接最大等待时间 默认 -1
      validation-query: select 1
      validation-query-timeout: 5000
      time-between-eviction-runs-millis: 2000 # 间隔多久进行检测需要关闭的空闲连接
      min-evictable-idle-time-millis: 600000 # 配置连接在池中最小生存的时间
      max-wait-thread-count: 20 # 最大等待线程数

集成依赖springboot durid starter 后springboot 就会自动装配了DruidDatasource,改变了jdbc操作数据使用的DataSource.
druid 自动装配类:
这里面创建了 DruidDataSourceWrapper() 其本身就是 DruidDatasource, 通过 注解@AutoConfigureBefore(DataSourceAutoConfiguration.class) 可知此配置类是在 DataSourceAutoConfiguration 之前生效,所以
优于springboot 默认创建的 hikarDatasource;

@Configuration
@ConditionalOnClass(DruidDataSource.class)
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
@EnableConfigurationProperties({DruidStatProperties.class, DataSourceProperties.class})
@Import({DruidSpringAopConfiguration.class,
    DruidStatViewServletConfiguration.class,
    DruidWebStatFilterConfiguration.class,
    DruidFilterConfiguration.class})
public class DruidDataSourceAutoConfigure {

    private static final Logger LOGGER = LoggerFactory.getLogger(DruidDataSourceAutoConfigure.class);

    @Bean(initMethod = "init")
    @ConditionalOnMissingBean
    public DataSource dataSource() {
        LOGGER.info("Init DruidDataSource");
        return new DruidDataSourceWrapper();
    }
}

所以加入了 Druid 的依赖后 就会自动选择使用 druidDatasource 作为数据源的操作,即可直接使用。

druid 监控功能

durid 的监控统计也是非常好用的;durid 内置了比较多的 Filter ;对sql的执行,和过滤监控,url 的方法都进行了比较好的统计。

配置Filters 开启哪些filter

在 spring.datasource.druid.filters 中配置, 多个使用逗号隔开; druid 在springboot 配置文件中前缀都是 spring.datasource.druid 所以有些截图就不添加

   # 配置filters ;
      #内置了日志类型: log4j ,slf4j, log4j2; 用于日志打印
      #监控统计: stat ;
      #解密和配置远程配置文件: config
      #防火墙: wall
      filters: stat,slf4j,wall
开启监控UI页面 StatViewServlet
     stat-view-servlet:
        enabled: true
        login-username: root  # 监控页面登录名
        login-password: 123456 # 监控页面密码

开启 监控页面后, 就可以登录监控页面

监控页面

访问路径: localhost:8181/druid 就可以观察到相关的
在这里插入图片描述

数据源 记录了我们的数据库连接信息
sql监控 监控执行过的sql 数量,执行时间, 并发数等
Sql防火墙 监控我们配置的wallFilter 信息;

配置慢sql 扫描
spring:
  datasource:
    druid: 
	  filter:
	    stat: # 监控配置
          enabled: true
          db-type: mysql
         # 慢sql配置
          log-slow-sql: true
          # sql 执行超过多少ms算慢sql
          slow-sql-millis: 1000

慢sql会在日志中打印 ,以及监控页面中sql监控中显示

配置 sql日志打印

使用slf4j; 配置文件中filters中添加slf4j

filters: stat,slf4j,wall

编写logback日志配置文件, 配置druid.sql.Statement 的日志输出配置 进行日志的打印和输出到日志文件; 我这里只配置了输出到控制台
logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--获取spirng配置信息-->
    <springProperty name="APP" source="spring.application.name"/>
    <!--   日志颜色转换器 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>

    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <Target>System.out</Target>
        <encoder>
            <pattern>%clr(${APP}){magenta} -- %d{yyyy-MM-dd HH:mm:ss.SSS} %clr([%5level]) %blue([%10t]) %cyan(%40logger{39}) : %clr(%m) %n
            </pattern>
        </encoder>
    </appender>
    <logger name="com.xiaodu" additivity="false">
        <level value="warn"/>
    </logger>
    <!--配置sql打印-->
    <logger name="druid.sql.Statement" level="debug" additivity="false">
        <appender-ref ref="console"/>
    </logger>
    <root>
        <level value="info"/>
        <appender-ref ref="console"/>
    </root>
</configuration>

日志打印信息

test-jdbcPool -- 2021-04-13 10:49:36.940 [DEBUG] [http-nio-8181-exec-1]                      druid.sql.Statement : {conn-10005, pstmt-20005} created. insert into t_user(u_id,u_name,password,money,create_time) values(?,?,?,?,?) 
test-jdbcPool -- 2021-04-13 10:49:36.940 [DEBUG] [http-nio-8181-exec-1]                      druid.sql.Statement : {conn-10005, pstmt-20005} Parameters : [e0b2ae8bfd23497f9d0d5fa59d450add, xiaodu, xiaodu, 123456, 2021-04-13 10:49:36.939] 
test-jdbcPool -- 2021-04-13 10:49:36.940 [DEBUG] [http-nio-8181-exec-1]                      druid.sql.Statement : {conn-10005, pstmt-20005} Types : [VARCHAR, VARCHAR, VARCHAR, BIGINT, TIMESTAMP] 
test-jdbcPool -- 2021-04-13 10:49:36.993 [DEBUG] [http-nio-8181-exec-1]                      druid.sql.Statement : {conn-10005, pstmt-20005} update executed. effort 1. 52.4484 millis. insert into t_user(u_id,u_name,password,money,create_time) values(?,?,?,?,?) 
test-jdbcPool -- 2021-04-13 10:49:36.993 [DEBUG] [http-nio-8181-exec-1]                      druid.sql.Statement : {conn-10005, pstmt-20005} closed 
配置sql防火墙 WallFilter

配置sql语句的检测,是否能进行一些危险的sql操作

spring:
  datasource:
    druid:
      filter:
        wall:  # sql防火墙配置
          enabled: true
          db-type: mysql
          config:
            select-all-column-allow: false # 是否允许select *
            delete-allow: false # 是否允许delete 语句
            drop-table-allow: false # 是否允许 drop table 语句
            alter-table-allow: false # 是否允许 alter table 语句
            truncate-allow: false
            update-where-alay-true-check: true # 检测update 语句是否条件永远为真
            update-where-none-check: true # 检测update 语句是否没有 where 条件
            delete-where-none-check: true # 检测delete 语句是否没有 where 条件
            delete-where-alway-true-check: true # 检测delete 语句是否条件永远为真
配置web应用和URL监控 WebStatFilter
spring:
  datasource:
    druid:
     # web应用 和URL 监控
      web-stat-filter:
        enabled: true
        exclusions: /static/*,*.js,*.gif,*.jpg,*.css,*.ico,/druid/* # 排除url
配置ConfigFilter

configFilter 可以进行数据库信息配置文件的位置,通过file 或者http 进行获取;和数据库密码加密操作;
重点说下数据库密码加密; 数据库密码在配置文件中明文显示是很敏感的。
数据库密码加密

  1. 使用durid 提供的 工具类生成加密后的密码
public class TestConfigFilter {

    public static void main(String[] args) throws Exception {
        String[] arg = new String[]{"123456"};  // 你的密码
        ConfigTools.main(arg);
    }
}

控制台输出加密后的密码信息
在这里插入图片描述
   2. 配置configFilter

  • filters 中加上config
 filters: stat,slf4j,wall,config
  • 添加工具类生成的公钥
db:
 publickey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAI9GVgduCJuY7K0Do7fSyrR0AyF+9leXaE4NlDnyEm/ZBixDPZCTgZLsaGkXFhiJ/14m7J+Ai1sC7q2RWbIoZSMCAwEAAQ==

  • 添加connection-properties 开启解密
spring:
  datasource:
    druid:
      connection-properties: config.decrypt=true;config.decrypt.key=${db.publickey}
  • 修改密码为加密后的密码
spring:
 # 数据源配置
 datasource:
   username: root
   password: XGsrLVwuuZJNCxZBJ5Q398P32SKDYYqL/MsqbAFAnIyd0X+SBcTQztWfZNm9D/GmRh4M95yP4ABd3WuA9EMUFA==

以上就是 configFIlter 对数据库密码加密的操作。

配置spring 监控

配置spring监控中 就会拦截指定的springbean ;在 监控页面的spring监控模块中显示 那些方法执行了那些sql, 耗时等信息。
这里简单以按照spring bean类型拦截监控为例。 其他例如通过正则, springbean id 请参考官网。

    @Bean
        public DruidStatInterceptor druidStatInterceptor() throws Exception {
            DruidStatInterceptor druidStatInterceptor = new DruidStatInterceptor();
            druidStatInterceptor.afterPropertiesSet();
            return druidStatInterceptor;
        }

        @Bean
        public BeanTypeAutoProxyCreator beanTypeAutoProxyCreator() {
            BeanTypeAutoProxyCreator beanTypeAutoProxyCreator = new BeanTypeAutoProxyCreator();
            beanTypeAutoProxyCreator.setTargetBeanType(UserController.class);  // 拦截的目标
            beanTypeAutoProxyCreator.setInterceptorNames("druidStatInterceptor"); // bean拦截器名称
            return beanTypeAutoProxyCreator;
        }

配置完后; 我们访问Usercontroller 类中的方法; 然后看ui页面 spring监控
在这里插入图片描述
其他方式参考官网wiki

扩展-通过spring 注解配置druid

也可以在配置类中配置相关的druid信息, 例如 datasource, druid提供的监控功能filter功能等。

          /*-------------使用配置类配置druid相关信息-----------------*/

        @Bean
        public DruidDataSource dataSource(DataSourceProperties dataSourceProperties) throws SQLException {
            DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
            dataSource.setFilters("slf4j,wall,stat");
            dataSource.setMaxActive(5);
            return dataSource;
        }

        @Bean
        public WallFilter wallFilter() {
            WallFilter wallFilter = new WallFilter();
            wallFilter.setConfig(wallConfig());
            wallFilter.setThrowException(true); // 对被认为是攻击的sql进行抛异常
            wallFilter.setLogViolation(true); // 对被认为是攻击的sql进行error 输出
            return wallFilter;
        }

        @Bean
        public WallConfig wallConfig() {
            WallConfig wallConfig = new WallConfig();
            wallConfig.setDeleteWhereAlwayTrueCheck(true);
            wallConfig.setUpdateWhereAlayTrueCheck(true);
            wallConfig.setDeleteWhereNoneCheck(true);
            wallConfig.setUpdateWhereNoneCheck(true);
            return wallConfig;
        }

        @Bean
        public StatFilter statFilter() {
            StatFilter statFilter = new StatFilter();
            statFilter.setDbType("mysql");
            statFilter.setLogSlowSql(true);
            statFilter.setSlowSqlMillis(2000);
            return statFilter;
        }

下一节 Spring boot restTemplate

Spring boot restTemplate

### Spring Boot 数据库连接池配置教程 Spring Boot 提供了一种简便的方式来管理和配置数据库连接池默认情况下,Spring Boot 使用 HikariCP 作为其内置的数据库连接池实现[^2]。以下是关于如何在 Spring Boot 中配置数据库连接池的具体方法。 #### 1. `application.properties` 或 `application.yml` 配置文件 可以通过修改 `application.properties` 文件或 `application.yml` 文件来完成数据库连接池的基础配置。以下是一个基于 YAML 的示例: ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/your_database_name?useSSL=false&serverTimezone=UTC username: your_username password: your_password driver-class-name: com.mysql.cj.jdbc.Driver hikari: connection-timeout: 30000 # 连接超时时间 (毫秒) idle-timeout: 600000 # 空闲连接的最大存活时间 (毫秒) max-lifetime: 1800000 # 单个连接的最大生命周期 (毫秒) minimum-idle: 10 # 最小空闲连接数 maximum-pool-size: 200 # 最大连接池大小 ``` 以上配置展示了如何调整 HikariCP 的核心参数以满足不同的性能需求[^4]。 #### 2. 自定义 DataSource Bean 如果需要更灵活的控制,可以手动创建一个 `DataSource` Bean 并注入到 Spring 容器中。这种方式适用于复杂的场景或者当需要切换其他类型的连接池(如 Apache DBCP 或 C3P0)时。 ```java import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; @Configuration public class DatabaseConfiguration { @Bean public DataSource dataSource() { HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:mysql://localhost:3306/your_database_name"); config.setUsername("your_username"); config.setPassword("your_password"); config.addDataSourceProperty("cachePrepStmts", "true"); config.addDataSourceProperty("prepStmtCacheSize", "250"); config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); // 设置 HikariCP 参数 config.setMaximumPoolSize(20); config.setMinimumIdle(5); return new HikariDataSource(config); } } ``` 此代码片段演示了如何通过 Java 配置类的方式显式地初始化 HikariCP 数据源并应用特定属性[^3]。 #### 3. 测试数据库连接池功能 为了验证数据库连接池的功能是否正常工作,在应用程序启动后可以编写单元测试或集成测试来模拟高并发环境下的行为。例如,使用 JUnit 和 Mockito 来执行基本查询操作。 ```java @SpringBootTest class ApplicationTests { @Autowired private DataSource dataSource; @Test void testConnectionPool() throws SQLException { try (Connection conn = dataSource.getConnection()) { System.out.println("Database Connection Established!"); } catch (SQLException e) { fail("Failed to establish database connection."); } } } ``` 这段代码用于确认数据源能够成功获取数据库连接[^1]。 --- ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值