day12-SpringBoot資料庫操作

来源:https://www.cnblogs.com/liyuelian/archive/2023/03/24/17253315.html
-Advertisement-
Play Games

SpringBoot資料庫操作 1.JDBC+HikariDataSource 在SpringBoot 2.x項目中,預設使用Hikari連接池管理數據源。相比於傳統的 C3P0 、DBCP、Tomcat jdbc 等連接池更加優秀。 當項目pom.xml引入spring-boot-starter- ...


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;
image-20230324155814766

(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>
image-20230324162032138

(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
@AllArgsConstructor
public 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中開發測試類
 */
@SpringBootTest
public 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());
    }
}

測試結果:

image-20230324165748810
<!--要開發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
 * 配置類
 */
@Configuration
public class DruidDataSourceConfig {
    //註入DruidDataSource
    
    //通過@ConfigurationProperties指定讀取application.yml文件的數據
    //我們就不需要調用DruidDataSource的setXxx方法來配置(不推薦)
    @ConfigurationProperties("spring.datasource")
    @Bean
    public DataSource dataSource() {
        return new DruidDataSource();
    }
}

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

測試結果:

image-20230324172011689

2.2.1一個問題

問題:為什麼我們註入了自己的數據源,預設的HikariDataSource就失效了?

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

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

因此,如果你註入了自己的數據源,就不會註入預設的HikariDataSource。

DataSourceAutoConfiguration.java:

image-20230324173613192

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
 * 配置類
 */
@Configuration
public 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,輸入配置的用戶名和密碼,即可訪問到內置的監控頁面:

image-20230324180857019

2.3.2SQL監控

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

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

修改DruidDataSourceConfig.java:

image-20230324185141036

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

image-20230324190402462

2.3.3-Web關聯監控

Web關聯監控配置

Spring關聯監控配置

修改DruidDataSourceConfig.java:註入webStatFilter

//配置WebStatFilter,用於採集web-jdbc關聯的監控數據
@Bean
public 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請求情況:

image-20230324194032770 image-20230324193759394

2.3.4SQL防火牆

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

修改DruidDataSourceConfig.java:

image-20230324194830084

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

image-20230324195129936 image-20230324195245053 image-20230324195319834

2.3.5Session監控

註意:這裡的Session不包括Druid後臺監控系統產生的Session

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

image-20230324195859800

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>
image-20230324201812644

(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)相關代碼和案例寫一遍


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Vue是一款國產前端框架,它的作者尤雨溪(Evan You)是一位美籍華人,2014年2月,尤雨溪開源了一個前端開發庫 Vue.js,2015年發佈1.0.0版本,2016年4月發佈2.0版本,目前,尤雨溪全職投入 Vue.js 的開發與維護,立志將 Vue.js 打造成與 Angular/Reac ...
  • 外觀模式(Facade Pattern):它提供了一個簡單的介面,用於訪問複雜的系統或子系統。通過外觀模式,客戶端可以通過一個簡單的介面來訪問複雜的系統,而無需瞭解系統內部的具體實現細節。 在前端開發中,外觀模式常常被用於封裝一些常用的操作,以簡化代碼複雜度和提高代碼可維護性。比如,一個用於處理數據 ...
  • 最近,在看 LPL 比賽的時候,看到這樣一個有意思的六芒星能力圖動畫: 今天,我們就來使用純 CSS 實現這樣一個動畫效果! 實現背景網格 對於如下這樣一個背景網格,最好的方式當然肯定是切圖,或者使用 SVG 路徑。 如果一定要使用 CSS,勉強也能做,這就涉及了不規則圖形邊框效果,我們有一些方式可 ...
  • title: "modern C++ DesignPattern-Part3" date: 2018-04-12T19:08:49+08:00 lastmod: 2018-04-12T19:08:49+08:00 keywords: [設計模式, C++] tags: [設計模式] categori ...
  • 關於指針、數組、字元串的恩怨,這裡有你想知道的一切 記憶體組成、字元串定義、一/二維數組結構、數組中的指針等價關係、數組結構中對“指針常量”的理解、 指針 vs 數組 記憶體結構一圖流、One More Thing:當二維數組遇見qsort()庫函數,關於比較函數cmp的迷思 ...
  • 模型和基本欄位 在上一章的末尾,我們創建一個odoo模塊。然而,此時它仍然是一個空殼,不允許我們存儲任何數據。在我們的房地產模塊中,我們希望將與房地產相關的信息(名稱(name)、描述(description)、價格(price)、居住面積(living area)…)存儲在資料庫中。odoo框架提 ...
  • 該工程為在保存時執行開發的功能,函數入口點ufput。其他還有新建、打開、另存等都可以加入開發的操作,具體看UF_EXIT下的介紹。 用戶出口是一個可選特性,允許你在NX中某些預定義的位置(或出口)自動運行Open C API程式。如果你進入其中一個出口,NX會檢查你是否定義了指向Open C AP ...
  • 網站介紹 基於 python 開發的電子商城網站,平臺採用 B/S 結構,後端採用主流的 Python 語言進行開發,前端採用主流的 Vue.js 進行開發。這是給師弟開發的畢業設計。 整個平臺包括前臺和後臺兩個部分。 前臺功能包括:首頁、商品詳情頁、用戶中心模塊。 後臺功能包括:總覽、訂單管理、商 ...
一周排行
    -Advertisement-
    Play Games
  • C#TMS系統代碼-基礎頁面BaseCity學習 本人純新手,剛進公司跟領導報道,我說我是java全棧,他問我會不會C#,我說大學學過,他說這個TMS系統就給你來管了。外包已經把代碼給我了,這幾天先把增刪改查的代碼背一下,說不定後面就要趕鴨子上架了 Service頁面 //using => impo ...
  • 委托與事件 委托 委托的定義 委托是C#中的一種類型,用於存儲對方法的引用。它允許將方法作為參數傳遞給其他方法,實現回調、事件處理和動態調用等功能。通俗來講,就是委托包含方法的記憶體地址,方法匹配與委托相同的簽名,因此通過使用正確的參數類型來調用方法。 委托的特性 引用方法:委托允許存儲對方法的引用, ...
  • 前言 這幾天閑來沒事看看ABP vNext的文檔和源碼,關於關於依賴註入(屬性註入)這塊兒產生了興趣。 我們都知道。Volo.ABP 依賴註入容器使用了第三方組件Autofac實現的。有三種註入方式,構造函數註入和方法註入和屬性註入。 ABP的屬性註入原則參考如下: 這時候我就開始疑惑了,因為我知道 ...
  • C#TMS系統代碼-業務頁面ShippingNotice學習 學一個業務頁面,ok,領導開完會就被裁掉了,很突然啊,他收拾東西的時候我還以為他要旅游提前請假了,還在尋思為什麼回家連自己買的幾箱飲料都要叫跑腿帶走,怕被偷嗎?還好我在他開會之前拿了兩瓶芬達 感覺感覺前面的BaseCity差不太多,這邊的 ...
  • 概述:在C#中,通過`Expression`類、`AndAlso`和`OrElse`方法可組合兩個`Expression<Func<T, bool>>`,實現多條件動態查詢。通過創建表達式樹,可輕鬆構建複雜的查詢條件。 在C#中,可以使用AndAlso和OrElse方法組合兩個Expression< ...
  • 閑來無聊在我的Biwen.QuickApi中實現一下極簡的事件匯流排,其實代碼還是蠻簡單的,對於初學者可能有些幫助 就貼出來,有什麼不足的地方也歡迎板磚交流~ 首先定義一個事件約定的空介面 public interface IEvent{} 然後定義事件訂閱者介面 public interface I ...
  • 1. 案例 成某三甲醫預約系統, 該項目在2024年初進行上線測試,在正常運行了兩天後,業務系統報錯:The connection pool has been exhausted, either raise MaxPoolSize (currently 800) or Timeout (curren ...
  • 背景 我們有些工具在 Web 版中已經有了很好的實踐,而在 WPF 中重新開發也是一種費時費力的操作,那麼直接集成則是最省事省力的方法了。 思路解釋 為什麼要使用 WPF?莫問為什麼,老 C# 開發的堅持,另外因為 Windows 上已經裝了 Webview2/edge 整體打包比 electron ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...