1. 程式人生 > >SpringBoot配置Druid數據源

SpringBoot配置Druid數據源

director 監測 jdbc 最小 upa 禁用 getc 是否有效 顯示調用

在我剛開始接觸JDBC的時候,用的是DriveManager驅動來連接數據庫的。而現在大多是用DataSource。

這裏先簡單說一下區別:

1、datasource是與連接池獲取連接,而DriverManager是獲取與數據庫的連接!
DriverManager類的主要作用是管理註冊到DriverManager中的JDBC驅動程序,並根據需要使用JDBC驅動程序建立與數據服務器的網絡連接。但是建立與數據庫的連接是一項較耗資源的工作,頻繁的進行數據庫連接建立操作會產生較大的系統開銷,為了解決上述問題,可以采用數據庫連接池技術。
2、datasource內部封裝了 DriverManager的使用。。。
DataSource主要是為了方便配置使用。。。 作為OO概念上也需要有這個類和對象來表示數據的來源。。。
3、 jdk api解釋
public interface DataSourceextends CommonDataSource, Wrapper
該工廠用於提供到此 DataSource 對象所表示的物理數據源的連接。作為 DriverManager 工具的替代項,DataSource 對象是獲取連接的首選方法。實現 DataSource 接口的對象通常在基於 JavaTM Naming and Directory Interface (JNDI) API 的命名服務中註冊。
DataSource 接口由驅動程序供應商實現。共有三種類型的實現:

1.基本實現 - 生成標準的 Connection 對象

2.連接池實現 - 生成自動參與連接池的 Connection 對象。此實現與中間層連接池管理器一起使用。

3.分布式事務實現 - 生成一個 Connection 對象,該對象可用於分布式事務,大多數情況下總是參與連接池。此實現與中間層事務管理器一起使用,大多數情況下總是與連接池管理器一起使用。


DataSource 對象的屬性在必要時可以修改。例如,如果將數據源移動到另一個服務器,則可更改與服務器相關的屬性。其優點在於,由於可以更改數據源的屬性,所以任何訪問該數據源的代碼都無需更改。
通過 DataSource 對象訪問的驅動程序本身不會向 DriverManager 註冊。通過查找操作獲取 DataSource 對象,然後使用該對象創建 Connection 對象。使用基本的實現,通過 DataSource 對象獲取的連接與通過 DriverManager 設施獲取的連接相同。

SpringBoot中默認使用的DataSource是org.apache.tomcat.jdbc.pool.DataSource數據源,配置的時候也很簡單,引入springboot和jdbc有關的包之後只要簡單的幾行配置即可:

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db_stupayment
spring.datasource.username=root
spring.datasource.password=4008

然後就是我們的Druid了:

DRUID是阿裏巴巴開源平臺上一個數據庫連接池實現,它結合了C3P0、DBCP、PROXOOL等DB池的優點,同時加入了日誌監控,可以很好的監控DB池連接和SQL的執行情況,可以說是針對監控而生的DB連接池

現在就來講講在SpringBoot中怎麽配置Druid

首先是在pom中加入相關的依賴:

<!--druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.19</version>
        </dependency>

然後是配置文件:

#Druid and datasourcee

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db_stupayment
spring.datasource.username=root
spring.datasource.password=4008

#下面開始是和druid相關的配置

spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20

spring.datasource.maxWait=60000

spring.datasource.timeBetweenEvictionRunsMillis=60000

spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false

#false is the default,the mysql suggested to false,or it will cost a lot of storage
#suggested true in the orcale
#spring.datasource.poolPreparedStatements=true 
#spring.datasource.maxPoolPreparedStatementPerConnectionSize=20

spring.datasource.filters=stat,wall,log4j

spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

spring.datasource.useGlobalDataSourceStat=true



spring.datasource.loginUsername=admin
spring.datasource.loginPassword=400831
spring.datasource.resetEnable=false
spring.datasource.urlMappings=/druid/*
spring.datasource.urlPatterns=/*
spring.datasource.exclusions=*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*

#druid and datasource end

前面五行配置是spring檢測的出的配置,相當於告訴spring一些關於數據庫的信息,還有連接池的種類。

之後的配置spring都是檢測不出的,但我們會在代碼的配置文件中引用。

技術分享圖片

然後關於這些配置的含義,在下面的代碼中有註解。

現在來看代碼中的配置:(下面的代碼都是在一個.java文件中的)

先完成field從配置文件中獲取值並註入:

package com.stuPayment.config;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;

/**
 * 配置DruidDataSource
 * @author 85060
 *
 */
@Configuration
public class DruidConfig {

    private Logger logger = LoggerFactory.getLogger(DruidConfig.class);
    
    @Value("${spring.datasource.url}")   //數據庫地址
    private String dbUrl;

    @Value("${spring.datasource.username}")   //數據庫登錄的賬號名
    private String username;

    @Value("${spring.datasource.password}")   //數據庫登錄的密碼
    private String password;

    @Value("${spring.datasource.driver-class-name}")   //數據庫驅動名
    private String driverClassName;

    @Value("${spring.datasource.initialSize}")   //初始化連接數量 初始化時建立物理連接的個數。初始化發生在顯示調用init方法,或者第一次getConnection時
    private int initialSize;

    @Value("${spring.datasource.minIdle}")//最小連接數量
    private int minIdle;

    @Value("${spring.datasource.maxActive}")   //最大連接數量
    private int maxActive;

    @Value("${spring.datasource.maxWait}")  //獲取連接時最大等待時間,單位毫秒。配置了maxWait之後,缺省啟用公平鎖,並發效率會有所下降,如果需要可以通過配置useUnfairLock屬性為true使用非公平鎖。
    private int maxWait;

    @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")  //配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒
    private int timeBetweenEvictionRunsMillis;

    @Value("${spring.datasource.minEvictableIdleTimeMillis}")   //配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒
    private int minEvictableIdleTimeMillis;

    @Value("${spring.datasource.validationQuery}")   //用來檢測連接是否有效的sql,要求是一個查詢語句。如果validationQuery為null,testOnBorrow、testOnReturn、testWhileIdle都不會其作用。
    private String validationQuery;

    @Value("${spring.datasource.testWhileIdle}")   //建議配置為true,不影響性能,並且保證安全性。申請連接的時候檢測,如果空閑時間大於timeBetweenEvictionRunsMillis,執行validationQuery檢測連接是否有效。
    private boolean testWhileIdle;

    @Value("${spring.datasource.testOnBorrow}")   //申請連接時執行validationQuery檢測連接是否有效,做了這個配置會降低性能。
    private boolean testOnBorrow;

    @Value("${spring.datasource.testOnReturn}")  //歸還連接時執行validationQuery檢測連接是否有效,做了這個配置會降低性能
    private boolean testOnReturn;

    @Value("${spring.datasource.filters}") //屬性類型是字符串,通過別名的方式配置擴展插件,常用的插件有: 監控統計用的filter:stat日誌用的filter:log4j防禦sql註入的filter:wall
    private String filters;

    @Value("${spring.datasource.connectionProperties}")  //通過connectProperties屬性來打開mergeSql功能;慢SQL記錄
    private String connectionProperties;
    
    @Value("${spring.datasource.useGlobalDataSourceStat}")  //合並多個DruidDataSource的監控數據
    private boolean  useGlobalDataSourceStat;
    
    
    
    @Value("${spring.datasource.loginUsername}")  //在druid監測servlet中配置用的,用來登錄監測網頁界面的用戶名
    private String loginUsername;
    
    @Value("${spring.datasource.loginPassword}")  //在druid監測servlet中配置用的,用來登錄監測網頁界面的密碼
    private String loginPassword; 
    
    @Value("${spring.datasource.resetEnable}")  //在druid監測servlet中配置用的,禁用頁面上的“Reset All”功能
    private String resetEnable;
    
    @Value("${spring.datasource.urlMappings}")  //在druid監測servlet中配置用的,設置用來訪問監測界面的url
    private String urlMappings;
    
    @Value("${spring.datasource.urlPatterns}")  //在druid監測filter中配置用的,過濾規則
    private String urlPatterns;

    @Value("${spring.datasource.exclusions}")   //在druid監測servlet中配置用的,忽略資源
    private String exclusions;

然後是Druid作為DataSource的bean的配置:

/**
     * druid數據源的配置    
     * @return
     */
    @Primary // 默認數據源  如果有多個實例,優先註入
    @Bean(name = "dataSource", destroyMethod = "close")
    public DataSource druidDataSource() {
        
        DruidDataSource dataSource = new DruidDataSource();
        
        dataSource.setUrl(dbUrl);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setDriverClassName(driverClassName);
        
        //configuration
        dataSource.setInitialSize(initialSize);
        dataSource.setMinIdle(minIdle);
        dataSource.setMaxActive(maxActive);
        dataSource.setMaxWait(maxWait);
        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        dataSource.setValidationQuery(validationQuery);
        dataSource.setTestWhileIdle(testWhileIdle);
        dataSource.setTestOnBorrow(testOnBorrow);
        dataSource.setTestOnReturn(testOnReturn);
        
        try {
            
            
            dataSource.setFilters(filters);
            
            
        } catch (SQLException e) {
            // TODO Auto-generated catch block

            logger.error("druid configuration initialization filter", e);

            
        }
        
        dataSource.setConnectionProperties(connectionProperties);
        dataSource.setUseGlobalDataSourceStat(useGlobalDataSourceStat);
        
        return dataSource;


    }

然後是配置與註冊druid監測系統的servlet(因為druid提供了個網頁界面做監控界面所以要有個servlet)

/**
     * 配置druid監控系統的servlet
     * 這裏就是註冊了一個servlet相當於
     * @return
     */
    @Bean
    public ServletRegistrationBean druidServlet() {
        
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean();
        
        servletRegistrationBean.setServlet(new StatViewServlet());//Druid提供的servlet
        
        servletRegistrationBean.addUrlMappings(urlMappings);//設置用來訪問監測界面的請求url
        
        //添加初始化參數:initParams
        /** 白名單,如果不配置或value為空,則允許所有 */
        //servletRegistrationBean.addInitParameter("allow","127.0.0.1,192.0.0.1");
        
        /** 黑名單,與白名單存在相同IP時,優先於白名單 */
        //servletRegistrationBean.addInitParameter("deny","192.0.0.1");
        
        /** 用戶名 */
        servletRegistrationBean.addInitParameter("loginUsername",loginUsername);
        
        /** 密碼 */
        servletRegistrationBean.addInitParameter("loginPassword",loginPassword);
        
        /** 禁用頁面上的“Reset All”功能 */
        servletRegistrationBean.addInitParameter("resetEnable",resetEnable);

        return servletRegistrationBean;
        
    }

然後是配置與註冊druid監控系統的filter

/**
     * 配置Druid監控系統的filter
     * 這裏就相當於註冊了一個filter
     * @return
     */
    @Bean
    FilterRegistrationBean druidFilter() {
        
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        
        filterRegistrationBean.setFilter(new WebStatFilter());
        
        /** 過濾規則 */
        filterRegistrationBean.addUrlPatterns(urlPatterns);
        /** 忽略資源 */
        filterRegistrationBean.addInitParameter("exclusions", exclusions);
        
        return filterRegistrationBean;
        
    }

在SpringBoot中註冊servlet和filter有兩種方法,在我的博客“記錄一下在SpringBoot中實現簡單的登錄認證”中有提到filter的兩種方法。

最後運行工程,然後輸入請求:

技術分享圖片

輸入自己設置的登錄賬號和密碼,成功進入監測界面monitor:

技術分享圖片

配置成功!!

參考過的博客:

講DriverManager和DataSource的區別的:

  https://www.cnblogs.com/549294286/p/3559422.html

講DruidDataSource一些配置參數的:

  https://www.cnblogs.com/wuyun-blog/p/5679073.html

講SpringBoot中怎麽配置Druid的:

  https://www.cnblogs.com/liuchuanfeng/p/7002046.html

  https://www.cnblogs.com/Jason-Xiang/p/7992370.html

SpringBoot配置Druid數據源