SpringBoot整合(五)HikariCP、Druid数据库连接池—多数据源配置
作者:mmseoamin日期:2023-12-20

在项目中,数据库连接池基本是必不可少的组件。在目前数据库连接池的选型中,主要是

  • Druid ,为监控而生的数据库连接池。
  • HikariCP ,号称性能最好的数据库连接池。

    在Spring Boot 2.X 版本,默认采用 HikariCP 连接池。而阿里大规模采用 Druid 。下面介绍在SpringBoot中使用HikariCP、Druid连接池。

    1、HikariCP数据库连接池

    1.1 HikariCP单数据源配置

    1.1.1 pom文件

    
    
        
            org.springframework.boot
            spring-boot-starter-parent
            2.1.3.RELEASE
             
        
        4.0.0
        HikariCP-Boot
        
            
            
                org.springframework.boot
                spring-boot-starter-jdbc
            
            
                mysql
                mysql-connector-java
                5.1.48
            
            
            
                org.springframework.boot
                spring-boot-starter-test
                test
            
        
    
    
    • 无需主动引入 HikariCP 的依赖。因为在 Spring Boot 2.X 中,spring-boot-starter-jdbc 默认引入 com.zaxxer.HikariCP 依赖。

      1.1.2 yml配置

      server:
        port: 7890
      spring:
        # datasource 数据源配置内容,对应 DataSourceProperties 配置属性类
        datasource:
          url: jdbc:mysql://127.0.0.1:3306/test?useSSL=false&useUnicode=true&characterEncoding=UTF-8
          driver-class-name: com.mysql.jdbc.Driver
          username: root # 数据库账号
          password: root # 数据库密码
          # HikariCP 自定义配置,对应 HikariConfig 配置属性类
          hikari:
            minimum-idle: 10 # 池中维护的最小空闲连接数,默认为 10 个。
            maximum-pool-size: 10 # 池中最大连接数,包括闲置和使用中的连接,默认为 10 个。
      
      • 在 spring.datasource 配置项下,我们可以添加数据源的通用配置。
      • 在 spring.datasource.hikari 配置项下,我们可以添加 HikariCP 连接池的自定义配置。然后 DataSourceConfiguration.Hikari会自动化配置 HikariCP 连接池。

        1.1.3 主启动类

        package com.yyds;
        import org.slf4j.Logger;
        import org.slf4j.LoggerFactory;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.boot.CommandLineRunner;
        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        import javax.sql.DataSource;
        import java.sql.Connection;
        import java.sql.SQLException;
        @SpringBootApplication
        public class ApplicationBak implements CommandLineRunner {
            private Logger logger = LoggerFactory.getLogger(ApplicationBak.class);
            @Autowired
            private DataSource dataSource;
            public static void main(String[] args) {
                // 启动 Spring Boot 应用
                SpringApplication.run(ApplicationBak.class, args);
            }
            @Override
            public void run(String... args) {
                try (Connection conn = dataSource.getConnection()) {
                    // 这里,可以做点什么
                    logger.info("[run][获得连接:{}]", conn);
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        

        通过实现 CommandLineRunner接口,应用启动完成后,回调 #run(String... args) 方法,输出 Connection 信息。

        1.2 HikariCP多数据源配置

        1.2.1 pom文件

        如1.2.1所示。

        1.2.2 yml配置

        spring:
          # datasource 数据源配置内容
          datasource:
            # 订单数据源配置
            orders:
              url: jdbc:mysql://127.0.0.1:3306/test_orders?useSSL=false&useUnicode=true&characterEncoding=UTF-8
              driver-class-name: com.mysql.jdbc.Driver
              username: root
              password: root
              # HikariCP 自定义配置,对应 HikariConfig 配置属性类
              hikari:
                minimum-idle: 20 # 池中维护的最小空闲连接数,默认为 10 个。
                maximum-pool-size: 20 # 池中最大连接数,包括闲置和使用中的连接,默认为 10 个。
            # 用户数据源配置
            users:
              url: jdbc:mysql://127.0.0.1:3306/test_users?useSSL=false&useUnicode=true&characterEncoding=UTF-8
              driver-class-name: com.mysql.jdbc.Driver
              username: root
              password: root
              # HikariCP 自定义配置,对应 HikariConfig 配置属性类
              hikari:
                minimum-idle: 15 # 池中维护的最小空闲连接数,默认为 10 个。
                maximum-pool-size: 15 # 池中最大连接数,包括闲置和使用中的连接,默认为 10 个。
        

        1.2.3 主启动类

        package com.yyds;
        import org.slf4j.Logger;
        import org.slf4j.LoggerFactory;
        import org.springframework.boot.CommandLineRunner;
        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        import javax.annotation.Resource;
        import javax.sql.DataSource;
        import java.sql.Connection;
        import java.sql.SQLException;
        @SpringBootApplication
        public class Application implements CommandLineRunner {
            private Logger logger = LoggerFactory.getLogger(Application.class);
            @Resource(name = "ordersDataSource")
            private DataSource ordersDataSource;
            @Resource(name = "usersDataSource")
            private DataSource usersDataSource;
            public static void main(String[] args) {
                // 启动 Spring Boot 应用
                SpringApplication.run(Application.class, args);
            }
            @Override
            public void run(String... args) {
                // orders 数据源
                try (Connection conn = ordersDataSource.getConnection()) {
                    // 这里,可以做点什么
                    logger.info("[run][ordersDataSource 获得连接:{}]", conn);
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
                // users 数据源
                try (Connection conn = usersDataSource.getConnection()) {
                    // 这里,可以做点什么
                    logger.info("[run][usersDataSource 获得连接:{}]", conn);
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        

        1.2.4 配置类

        package com.yyds.config;
        import com.zaxxer.hikari.HikariDataSource;
        import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
        import org.springframework.boot.context.properties.ConfigurationProperties;
        import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.Configuration;
        import org.springframework.context.annotation.Primary;
        import org.springframework.util.StringUtils;
        import javax.sql.DataSource;
        @Configuration
        public class DataSourceConfig {
            /**
             * 创建 orders 数据源的配置对象
             */
            @Primary
            @Bean(name = "ordersDataSourceProperties")
            @ConfigurationProperties(prefix = "spring.datasource.orders") // 读取 spring.datasource.orders 配置到 DataSourceProperties 对象
            public DataSourceProperties ordersDataSourceProperties() {
                return new DataSourceProperties();
            }
            /**
             * 创建 orders 数据源
             */
            @Bean(name = "ordersDataSource")
            @ConfigurationProperties(prefix = "spring.datasource.orders.hikari") // 读取 spring.datasource.orders 配置到 HikariDataSource 对象
            public DataSource ordersDataSource() {
                // <1.1> 获得 DataSourceProperties 对象
                DataSourceProperties properties =  this.ordersDataSourceProperties();
                // <1.2> 创建 HikariDataSource 对象
                return createHikariDataSource(properties);
            }
            /**
             * 创建 users 数据源的配置对象
             */
            @Bean(name = "usersDataSourceProperties")
            @ConfigurationProperties(prefix = "spring.datasource.users") // 读取 spring.datasource.users 配置到 DataSourceProperties 对象
            public DataSourceProperties usersDataSourceProperties() {
                return new DataSourceProperties();
            }
            /**
             * 创建 users 数据源
             */
            @Bean(name = "usersDataSource")
            @ConfigurationProperties(prefix = "spring.datasource.users.hikari")
            public DataSource usersDataSource() {
                // 获得 DataSourceProperties 对象
                DataSourceProperties properties =  this.usersDataSourceProperties();
                // 创建 HikariDataSource 对象
                return createHikariDataSource(properties);
            }
            private static HikariDataSource createHikariDataSource(DataSourceProperties properties) {
                // 创建 HikariDataSource 对象
                HikariDataSource dataSource = properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
                // 设置线程池名
                if (StringUtils.hasText(properties.getName())) {
                    dataSource.setPoolName(properties.getName());
                }
                return dataSource;
            }
        }
        

        ordersDataSourceProperties()方法,创建orders数据源的DataSourceProperties配置对象。

        • @Primary注解,保证项目中有一个主的DataSourceProperties Bean。

        • 加上 @Bean(name = “ordersDataSourceProperties”)注解,会创建一个名字位ordersDataSourceProperties的DataSourceProperties Bean

        • @ConfigurationProperties(prefix = “spring.datasource.orders”)注解,会将spring.datasource.orders配置项,逐个属性赋值给DataSourceProperties Bean

          ordersDataSource()方法,创建orders数据源。

          • DataSourceProperties properties = this.ordersDataSourceProperties();获取orders数据源的DataSourceProperties配置对象

          • createHikariDataSource()方法创建HikariDataSource对象,这样,"spring.datasource.orders" 配置项,逐个属性赋值给 HikariDataSource Bean 。

          • 搭配上 @Bean(name = "ordersDataSource") 注解,会创建一个名字为 "ordersDataSource" 的 HikariDataSource Bean 。

          • @ConfigurationProperties(prefix = "spring.datasource.orders.hikari") 注解,会将 HikariCP 的 "spring.datasource.orders.hikari" 自定义配置项,逐个属性赋值给 HikariDataSource Bean 。

            SpringBoot整合(五)HikariCP、Druid数据库连接池—多数据源配置,在这里插入图片描述,第1张

            2、Druid数据库连接池

            2.1 Druid单数据源配置

            2.1.1 pom文件

            
            
                
                    org.springframework.boot
                    spring-boot-starter-parent
                    2.1.3.RELEASE
                     
                
                4.0.0
                Druid-Boot
                
                    
                    
                        org.springframework.boot
                        spring-boot-starter-jdbc
                    
                    
                    
                        com.alibaba
                        druid-spring-boot-starter
                        1.1.21
                    
                     
                        mysql
                        mysql-connector-java
                        5.1.48
                    
                    
                    
                        org.springframework.boot
                        spring-boot-starter-web
                    
                    
                    
                        org.springframework.boot
                        spring-boot-starter-test
                        test
                    
                
            
            

            2.1.2 yml配置

            spring:
              # datasource 数据源配置内容,对应 DataSourceProperties 配置属性类
              datasource:
                url: jdbc:mysql://127.0.0.1:3306/test?useSSL=false&useUnicode=true&characterEncoding=UTF-8
                driver-class-name: com.mysql.jdbc.Driver
                username: root # 数据库账号
                password: root # 数据库密码
                type: com.alibaba.druid.pool.DruidDataSource # 设置类型为 DruidDataSource
                # Druid 自定义配置,对应 DruidDataSource 中的 setting 方法的属性
                druid:
                  min-idle: 0 # 池中维护的最小空闲连接数,默认为 0 个。
                  max-active: 20 # 池中最大连接数,包括闲置和使用中的连接,默认为 8 个。
                  filter:
                    stat: # 配置 StatFilter ,对应文档 https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatFilter
                      log-slow-sql: true # 开启慢查询记录
                      slow-sql-millis: 5000 # 慢 SQL 的标准,单位:毫秒
                  stat-view-servlet: # 配置 StatViewServlet ,对应文档 https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatViewServlet%E9%85%8D%E7%BD%AE
                    enabled: true # 是否开启 StatViewServlet
                    login-username: root # 账号
                    login-password: root # 密码
            

            2.1.3主启动类

            package com.yyds;
            import org.slf4j.Logger;
            import org.slf4j.LoggerFactory;
            import org.springframework.beans.factory.annotation.Autowired;
            import org.springframework.boot.CommandLineRunner;
            import org.springframework.boot.SpringApplication;
            import org.springframework.boot.autoconfigure.SpringBootApplication;
            import javax.sql.DataSource;
            @SpringBootApplication
            public class ApplicationBak implements CommandLineRunner {
                private Logger logger = LoggerFactory.getLogger(ApplicationBak.class);
                @Autowired
                private DataSource dataSource;
                public static void main(String[] args) {
                    // 启动 Spring Boot 应用
                    SpringApplication.run(ApplicationBak.class, args);
                }
                @Override
                public void run(String... args) {
                    logger.info("[run][获得数据源:{}]", dataSource.getClass());
                }
            }
            

            2.1.4 监控

            因为做了如下操作:

            • 通过 spring.datasource.filter.stat 配置了 StatFilter ,统计监控信息。
            • 通过 spring.datasource.filter.stat-view-servlet 配置了 StatViewServlet ,提供监控信息的展示的 html 页面和 JSON API

              所以我们在启动项目后,访问 http://127.0.0.1:8080/druid 地址,账户密码为配置的root,可以看到监控 html 页面。

              SpringBoot整合(五)HikariCP、Druid数据库连接池—多数据源配置,在这里插入图片描述,第2张

              • 在界面的顶部,提供了数据源、SQL 监控、SQL 防火墙等功能。
              • 每个界面上,可以通过 [View JSON API]获得数据的来源。
              • 因为监控信息是存储在 JVM 内存中,在 JVM 进程重启时,信息将会丢失。如果我们希望持久化到 MySQL、Elasticsearch、HBase 等存储器中,可以通过 StatViewServlet 提供的 JSON API 接口,采集监控信息。

                Druid 的文档:https://github.com/alibaba/druid/wiki/ 。

                2.2 Druid多数据源配置

                2.2.1 pom文件

                如2.1.1

                2.2.2 yml配置

                spring:
                  # datasource 数据源配置内容
                  datasource:
                    # 订单数据源配置
                    orders:
                      url: jdbc:mysql://127.0.0.1:3306/test_orders?useSSL=false&useUnicode=true&characterEncoding=UTF-8
                      driver-class-name: com.mysql.jdbc.Driver
                      username: root
                      password:
                      type: com.alibaba.druid.pool.DruidDataSource # 设置类型为 DruidDataSource
                      # Druid 自定义配置,对应 DruidDataSource 中的 setting 方法的属性
                      min-idle: 0 # 池中维护的最小空闲连接数,默认为 0 个。
                      max-active: 20 # 池中最大连接数,包括闲置和使用中的连接,默认为 8 个。
                    # 用户数据源配置
                    users:
                      url: jdbc:mysql://127.0.0.1:3306/test_users?useSSL=false&useUnicode=true&characterEncoding=UTF-8
                      driver-class-name: com.mysql.jdbc.Driver
                      username: root
                      password: root
                      type: com.alibaba.druid.pool.DruidDataSource # 设置类型为 DruidDataSource
                      # Druid 自定义配置,对应 DruidDataSource 中的 setting 方法的属性
                      min-idle: 0 # 池中维护的最小空闲连接数,默认为 0 个。
                      max-active: 20 # 池中最大连接数,包括闲置和使用中的连接,默认为 8 个。
                    # Druid 自定已配置
                    druid:
                      # 过滤器配置
                      filter:
                        stat: # 配置 StatFilter ,对应文档 https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatFilter
                          log-slow-sql: true # 开启慢查询记录
                          slow-sql-millis: 5000 # 慢 SQL 的标准,单位:毫秒
                      # StatViewServlet 配置
                      stat-view-servlet: # 配置 StatViewServlet ,对应文档 https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_StatViewServlet%E9%85%8D%E7%BD%AE
                        enabled: true # 是否开启 StatViewServlet
                        login-username: root # 账号
                        login-password: root # 密码
                

                2.2.3主启动类

                package com.yyds;
                import org.slf4j.Logger;
                import org.slf4j.LoggerFactory;
                import org.springframework.boot.CommandLineRunner;
                import org.springframework.boot.SpringApplication;
                import org.springframework.boot.autoconfigure.SpringBootApplication;
                import javax.annotation.Resource;
                import javax.sql.DataSource;
                @SpringBootApplication
                public class Application implements CommandLineRunner {
                    private Logger logger = LoggerFactory.getLogger(Application.class);
                    @Resource(name = "ordersDataSource")
                    private DataSource ordersDataSource;
                    @Resource(name = "usersDataSource")
                    private DataSource usersDataSource;
                    public static void main(String[] args) {
                        // 启动 Spring Boot 应用
                        SpringApplication.run(Application.class, args);
                    }
                    @Override
                    public void run(String... args) {
                        // orders 数据源
                        logger.info("[run][获得数据源:{}]", ordersDataSource.getClass());
                        // users 数据源
                        logger.info("[run][获得数据源:{}]", usersDataSource.getClass());
                    }
                }
                

                2.2.4 配置类

                package com.yyds.config;
                import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
                import org.springframework.boot.context.properties.ConfigurationProperties;
                import org.springframework.context.annotation.Bean;
                import org.springframework.context.annotation.Configuration;
                import org.springframework.context.annotation.Primary;
                import javax.sql.DataSource;
                @Configuration
                public class DataSourceConfig {
                    /**
                     * 创建 orders 数据源
                     */
                    @Primary
                    @Bean(name = "ordersDataSource")
                    @ConfigurationProperties(prefix = "spring.datasource.orders") 
                    public DataSource ordersDataSource() {
                        return DruidDataSourceBuilder.create().build();
                    }
                    /**
                     * 创建 users 数据源
                     */
                    @Bean(name = "usersDataSource")
                    @ConfigurationProperties(prefix = "spring.datasource.users")
                    public DataSource usersDataSource() {
                        return DruidDataSourceBuilder.create().build();
                    }
                }
                

                可以看到数据源加载成功。

                SpringBoot整合(五)HikariCP、Druid数据库连接池—多数据源配置,在这里插入图片描述,第3张