天天看點

SpringBoot資料庫操作的應用

作者:黑芝麻湯圓他爹

1.JDBC+HikariDataSource

在SpringBoot 2.x項目中,預設使用Hikari連接配接池管理資料源。相比于傳統的 C3P0 、DBCP、Tomcat jdbc 等連接配接池更加優秀。

當項目pom.xml引入spring-boot-starter-jdbc啟動器依賴後,即可自動導入Hikari,該啟動器不但依賴它,還會對其自動配置并建立資料源。我們以MySQL資料庫為例,介紹如何使用Hikari。

資料源是啥?為什麼要用?怎麼用?

1.1應用執行個體

示範SpringBoot如何通過 JDBC+HikariDataSource 完成對Mysql操作。

(1)資料庫和表

-- 建立資料庫DROP DATABASE IF EXISTS spring_boot;CREATE DATABASE spring_boot;USE spring_boot; -- 建立表CREATE TABLE furn(`id` INT(11) PRIMARY KEY AUTO_INCREMENT, #id`name` VARCHAR(64) NOT NULL, #家居名`maker` VARCHAR(64) NOT NULL, #廠商`price` DECIMAL(11,2) NOT NULL, #價格`sales` INT(11) NOT NULL, #銷量`stock` INT(11) NOT NULL, #庫存`img_path` VARCHAR(256) NOT NULL #照片路徑); -- 初始化家居資料INSERT INTO furn(`id` , `name` , `maker` , `price` , `sales` , `stock` , `img_path`) VALUES(NULL , '北歐風格小桌子' , '熊貓家居' , 180 , 666 , 7 , 'assets/images/product-image/6.jpg'); INSERT INTO furn(`id` , `name` , `maker` , `price` , `sales` , `stock` , `img_path`) VALUES(NULL , '簡約風格小椅子' , '熊貓家居' , 180 , 666 , 7 , 'assets/images/product-image/4.jpg'); INSERT INTO furn(`id` , `name` , `maker` , `price` , `sales` , `stock` , `img_path`) VALUES(NULL , '典雅風格小台燈' , '螞蟻家居' , 180 , 666 , 7 , 'assets/images/product-image/14.jpg'); INSERT INTO furn(`id` , `name` , `maker` , `price` , `sales` , `stock` , `img_path`) VALUES(NULL , '溫馨風格盆景架' , '螞蟻家居' , 180 , 666 , 7 , 'assets/images/product-image/16.jpg'); SELECT * FROM furn;           
SpringBoot資料庫操作的應用

(2)進行資料庫開發,首先要在pom.xml檔案中引入spring-boot-starter-data-jdbc。SpringBoot不知道項目要操作Mysql還是Oracle,是以還需要導入資料庫驅動,并指定對應版本。

<!--進行資料庫開發,引入data-jdbc starter--><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-data-jdbc</artifactId></dependency> <!--導入mysql驅動,如果使用版本仲裁,SpringBoot預設的版本為8.0.26--><dependency>    <groupId>mysql</groupId>    <artifactId>mysql-connector-java</artifactId>    <version>5.1.49</version></dependency>           
SpringBoot資料庫操作的應用

(3)在application.yml配置操作資料源的資訊

spring:  datasource: #配置資料源    #說明:如果沒有配置useSSL=true,啟動項目會報紅警告,但不影響使用    url: jdbc:mysql://localhost:3306/spring_boot?useSSL=true&useUnicode=true&characterEncoding=UTF-8    username: root    password: 123456    driver-class-name: com.mysql.jdbc.Driver           

(4)建立Javabean--Furn.java

package com.li.thymeleaf.bean; import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor; import java.math.BigDecimal; /** * @author 李 * @version 1.0 */@Data@NoArgsConstructor@AllArgsConstructorpublic class Furn {    private Integer id;    private String name;    private String maker;    private BigDecimal price;    private Integer sales;    private Integer stock;    private String imgPath;}           

(5)測試類ApplicationTests.java

package com.li.thymeleaf; import com.li.thymeleaf.bean.Furn;import org.junit.jupiter.api.Test;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.JdbcTemplate; import javax.annotation.Resource;import java.util.List; /** * @author 李 * @version 1.0 * 示範如何在SpringBoot中開發測試類 */@SpringBootTestpublic class ApplicationTests {    //這裡使用spring的JDBCTemplate    @Resource    private JdbcTemplate jdbcTemplate;     @Test    public void contextLoads() {        //使用RowMapper接口來對傳回的資料進行封裝(底層是反射->setter)        BeanPropertyRowMapper<Furn> rowMapper =                new BeanPropertyRowMapper<>(Furn.class);        List<Furn> furns = jdbcTemplate.query("select * from furn", rowMapper);        for (Furn furn : furns) {            System.out.println("furn=" + furn);        }        //檢視底層使用的是什麼資料源        System.out.println(jdbcTemplate.getDataSource().getClass());    }}           

測試結果:

SpringBoot資料庫操作的應用
<!--要開發SpringBoot測試類,需要引入test starter--><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId></dependency>

2.整合Druid到SpringBoot

2.1Druid介紹

alibaba/druid: 為監控而生的資料庫連接配接池 (github.com)

官方使用文檔 · alibaba/druid Wiki (github.com)

Druid資料庫連接配接池性能優秀,它除了提供性能卓越的資料池功能外,還繼承了SQL監控,黑名單攔截等功能。強大的監控特性,通過Druid提供的監控功能,可以清楚知道連接配接池和SQL的工作情況,是以根據項目需要,我們也要掌握Druid和SpringBoot的整合。

整合Druid到SpringBoot的方式:

  • 自定義方式
  • 引入starter

2.2Druid基本使用

(1)修改pom.xml,引入druid依賴

<!--引入druid依賴--><dependency>    <groupId>com.alibaba</groupId>    <artifactId>druid</artifactId>    <version>1.1.17</version></dependency>           

(2)建立配置類 DruidDataSourceConfig.java,将DruidDataSource注入容器

package com.li.thymeleaf.config; import com.alibaba.druid.pool.DruidDataSource;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; /** * @author 李 * @version 1.0 * 配置類 */@Configurationpublic class DruidDataSourceConfig {    //注入DruidDataSource        //通過@ConfigurationProperties指定讀取application.yml檔案的資料    //我們就不需要調用DruidDataSource的setXxx方法來配置(不推薦)    @ConfigurationProperties("spring.datasource")    @Bean    public DataSource dataSource() {        return new DruidDataSource();    }}           

(3)測試類ApplicationTests.java(略,同上)

測試結果:

SpringBoot資料庫操作的應用

2.2.1一個問題

問題:為什麼我們注入了自己的資料源,預設的HikariDataSource就失效了?

先來弄明白,預設的HikariDataSource 是如何配置的:

SpringBoot通過DataSourceAutoConfiguration.java來進行資料源的配置,在進行預設的配置之前,如果檢測到容器中已經有DataSource Bean,就不會注入預設的HikariDataSource。

是以,如果你注入了自己的資料源,就不會注入預設的HikariDataSource。

DataSourceAutoConfiguration.java:

SpringBoot資料庫操作的應用

2.3Druid監控功能

2.3.1開啟内置監控頁

怎樣使用Druid的内置監控頁面:内置監控頁面是一個Servlet,具體配置看這裡

(1)在配置類中,啟用druid的監控頁功能:

在web項目中使用web.xml配置,若在SpringBoot中,有兩種方法注入Servlet---注解和RegistrationBean,這裡使用RegistrationBean

DruidDataSourceConfig.java:

package com.li.thymeleaf.config; import com.alibaba.druid.pool.DruidDataSource;import com.alibaba.druid.support.http.StatViewServlet;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.boot.web.servlet.ServletRegistrationBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; /** * @author 李 * @version 1.0 * 配置類 */@Configurationpublic class DruidDataSourceConfig {    //注入DruidDataSource    //通過@ConfigurationProperties指定讀取yml檔案的字首的資料    @ConfigurationProperties("spring.datasource")    @Bean    public DataSource dataSource() {        return new DruidDataSource();    }     //配置Druid的監控頁功能    @Bean    public ServletRegistrationBean statViewServlet() {        //建立StatViewServlet        ServletRegistrationBean<StatViewServlet> registrationBean                = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");        //設定初始化參數-使用者名和密碼-根據官方配置檔案設定        registrationBean.addInitParameter("loginUsername", "olien");        registrationBean.addInitParameter("loginPassword", "123456");        return registrationBean;    }}           

(2)啟動項目,浏覽器中通路http://項目ip:項目端口/項目名稱/druid/index.html,輸入配置的使用者名和密碼,即可通路到内置的監控頁面:

SpringBoot資料庫操作的應用

2.3.2SQL監控

配置_StatFilter · alibaba/druid Wiki (github.com)

除了文檔中的配置方式,也可在配置類中直接對資料源進行設定。

修改DruidDataSourceConfig.java:

SpringBoot資料庫操作的應用

啟用SQL監控功能之後,在監控頁中可以檢視到所有對資料庫發出的SQL語句:

SpringBoot資料庫操作的應用

2.3.3-Web關聯監控

Web關聯監控配置

Spring關聯監控配置

修改DruidDataSourceConfig.java:注入webStatFilter

//配置WebStatFilter,用于采集web-jdbc關聯的監控資料@Beanpublic FilterRegistrationBean webStatFilter() {    //建立過濾器webStatFilter    WebStatFilter webStatFilter = new WebStatFilter();    FilterRegistrationBean<WebStatFilter> filterRegistrationBean =            new FilterRegistrationBean<>(webStatFilter);    //設定webStatFilter的監控url    filterRegistrationBean.setUrlPatterns(Arrays.asList("/*"));    //根據官方文檔設定webStatFilter排除的url    filterRegistrationBean.addInitParameter("exclusions",            "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");    return filterRegistrationBean;}           

啟用URI監控功能之後,在監控頁中可以檢視到所有的Web應用情況和URI請求情況:

SpringBoot資料庫操作的應用
SpringBoot資料庫操作的應用

2.3.4SQL防火牆

Druid提供了WallFilter,它是基于SQL語義分析來實作防禦SQL注入攻擊的。具體配置看這裡

修改DruidDataSourceConfig.java:

SpringBoot資料庫操作的應用

啟用SQL防火牆之後,在監控頁中可以檢視到所有的SQL情況:

SpringBoot資料庫操作的應用
SpringBoot資料庫操作的應用
SpringBoot資料庫操作的應用

2.3.5Session監控

注意:這裡的Session不包括Druid背景監控系統産生的Session

Druid的Session監控不需要配置,在開啟了内置監控功能後就可以使用了。

SpringBoot資料庫操作的應用

2.4Druid-Starter

整合Druid到SpringBoot的方式有兩種:自定義方式和引入starter。

2.3中的所有例子中我們使用的是自己引入druid+配置類方式整合druid和監控。此外,還可以引入Druid Srping Boot Starter,讓程式員在SpringBoot項目中更加輕松內建Druid和監控。

示範使用Druid-Starter(示範之前,删除之前所有的自定義方式操作)

(1)pom.xml引入druid-spring-boot-starter

<!--引入druid的starter--><dependency>    <groupId>com.alibaba</groupId>    <artifactId>druid-spring-boot-starter</artifactId>    <version>1.1.17</version></dependency>           
SpringBoot資料庫操作的應用

(2)在application.yml檔案中配置druid和監控功能

spring:  datasource: #配置資料源    #如果沒有配置useSSL=true,啟動項目會報紅警告,但不影響使用    url: jdbc:mysql://localhost:3306/spring_boot?useSSL=true&useUnicode=true&characterEncoding=UTF-8    username: root    password: 123456    driver-class-name: com.mysql.jdbc.Driver    #配置druid和監控功能    druid:      stat-view-servlet: #(1)開啟監控頁        enabled: true        login-username: jack        login-password: 1234        reset-enable: false      web-stat-filter: #(2)啟用web監控功能        enabled: true        url-pattern: /*        exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"      filter:        stat: #(3)啟用sql監控功能          slow-sql-millis: 1000 #機關ms          log-slow-sql: true #啟用慢查詢的sql日志          enabled: true        wall: #(4)啟用sql防火牆功能          enabled: true          config:            drop-table-allow: false #是否允許進行删除表的操作            select-all-column-allow: false #是否允許查詢所有字段的操作           

3.練習

将異常處理、注入Servlet、Filter、Listener,Tomcat切換,資料庫操作(HikariDataSource&DruidDataSource)相關代碼和案例寫一遍