小黑子——springBoot基礎

springBoot簡單學習

  • 一、SpringBoot簡介
    • 1.1 springBoot快速入門
      • 1.1.1 開發步驟
      • 1.1.2 對比
      • 1.1.3 官網構建工程
      • 1.1.3 SpringBoot工程快速啟動
    • 1.2 springBoot概述
      • 1.2.1 起步依賴
        • I. 探索父工程
        • II. 探索依賴
        • III. 小結
      • 1.2.2 程序啟動
      • 1.2.3 切換web服務器-jetty
  • 二、配置文件
    • 2.1 配置文件格式
      • 2.1.1 不同配置文件演示
      • 2.1.2 三種配合文件的優先級
    • 2.2 yaml
      • 2.2.1 yaml配置文件格式讀取
        • I. 環境準備
        • II. 讀取配置文件
    • 2.3 多環境啟動
      • 2.3.1 yaml文件
      • 2.3.2 properties文件
      • 2.3.3 命令行啟動參數設置
      • 2.3.4 maven與springboot多環境兼容問題
    • 2.4 配置文件分類
  • 三、SpringBoot整合Junit
    • 3.1 環境準備
    • 3.2 編寫測試類
  • 四、SpringBoot整合Mybatis
    • 4.1 回顧Spring整合MyBatis
    • 4.2 SpringBoot整合MyBatis
    • 4.3 SpringBoot整合Druid
  • 五、案例
    • 5.1 創建工程
    • 5.2 代碼拷貝
    • 5.3 配置文件
    • 5.4 靜態資源
  • 六、總結
    • 6.1 流程分析
    • 6.2 整合配置
    • 6.3 功能模塊開發
    • 6.4 統一結果封裝
    • 6.5 統一異常處理
    • 6.6 前端內容

一、SpringBoot簡介

SpringBoot是由Pivotal團隊提供的全新框架,其設計目的是用來簡化Spring應用的初始搭建以及開發過程

使用了Spring框架后已經簡化了我們的開發,而SpringBoot又是對Spring開發進行簡化的,可想而知SpringBoot使用的簡單及廣泛性。
既然SpringBoot是用來簡化Spring開發的,那我們就先回顧一下,以SpringMVC開發為例

  1. 創建一個maven工程,并在pom.xml中導入所需依賴的坐標

    <dependencies>
    <dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.10.RELEASE</version>
    </dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.2.10.RELEASE</version>
    </dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.2.10.RELEASE</version>
    </dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.6</version>
    </dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.0</version>
    </dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.46</version>
    </dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.16</version>
    </dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope>
    </dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope>
    </dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.0</version>
    </dependency>
    </dependencies>
    
  2. 編寫web3.0的配置類

    public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    protected Class<?>[] getRootConfigClasses() {return new Class[]{SpringConfig.class};
    }protected Class<?>[] getServletConfigClasses() {return new Class[]{SpringMvcConfig.class};
    }protected String[] getServletMappings() {return new String[]{"/"};
    }@Override
    protected Filter[] getServletFilters() {CharacterEncodingFilter filter = new CharacterEncodingFilter();filter.setEncoding("utf-8");return new Filter[]{filter};
    }
    }
    
  3. 編寫SpringMvc配置類

    @Configuration
    @ComponentScan("com.blog.controller")
    @EnableWebMvc
    public class SpringMvcConfig implements WebMvcConfigurer {}
    
  4. 編寫Controller類

    @RestController
    @RequestMapping("/books")
    public class BookController {
    @Autowired
    private BookService bookService;@PostMapping
    public boolean save(@RequestBody Book book) {return bookService.save(book);
    }@PutMapping
    public boolean update(@RequestBody Book book) {return bookService.update(book);
    }@DeleteMapping("/{id}")
    public boolean delete(@PathVariable Integer id) {return bookService.delete(id);
    }@GetMapping("/{id}")
    public Book getById(@PathVariable Integer id) {return bookService.getById(id);
    }@GetMapping
    public List<Book> getAll() {return bookService.getAll();
    }
    }
    

從上面的 SpringMVC 程序開發可以看到,前三步都是在搭建環境,而且這三步基本都是固定的。SpringBoot 就是對這三步進行簡化了。接下來我們通過一個入門案例來體現 SpingBoot 簡化 Spring 開發。

1.1 springBoot快速入門

1.1.1 開發步驟

SpringBoot 開發起來特別簡單,分為如下幾步:

  • 創建新模塊,選擇Spring初始化,并配置模塊相關基礎信息
  • 選擇當前模塊需要使用的技術集
  • 開發控制器類
  • 運行自動生成的Application類

知道了 SpringBoot 的開發步驟后,下面我們進行具體的操作:
創建一個springboot2.0的項目,本地安裝的是1.8,但是在使用Spring Initializr創建項目時,發現版本只有17和21。在JDK為1.8的情況下,無論選擇Java17版本或者21版本時,都會報錯。要么選擇更低的Java版本或者更換更高的SDK版本即跟換JDK版本

  1. 步驟一:創建新模塊
    在IDEA下創建一個新模塊,選擇Spring Initializr,用來創建SpringBoot工程
    在這里插入圖片描述
    https://start.aliyun.com/
    在這里插入圖片描述
    選中 Web,然后勾選 Spring Web,由于我們需要開發一個 web 程序,使用到了 SpringMVC 技術,所以按照下圖紅框進行勾選
    在這里插入圖片描述
    最后點擊創建,就大功告成了,經過以上步驟后就創建了如下結構的模塊,它會幫我們自動生成一個 Application 類,而該類一會再啟動服務器時會用到

    注意:

    • 在創建好的工程中不需要創建配置類
    • 創建好的項目會自動生成其他的一些文件,而這些文件目前對我們來說沒有任何作用,所以可以將這些文件刪除。
    • 可以刪除的目錄和文件如下:
      • .mvn
      • .gitignore
      • HELP.md
      • mvnw
      • mvnw.cmd
  2. 步驟二:創建Controller
    在com.itheima.controller包下創建BookController,代碼如下:

    @RestController
    @RequestMapping("/books")
    public class BookController {@GetMapping("/{id}")
    public String getById(@PathVariable Integer id){System.out.println("id="+id);return "hello world";}
    }
    
  3. 步驟三:啟動服務器
    運行 SpringBoot 工程不需要使用本地的 Tomcat 和 插件,只運行項目 com.itheima 包下的 Application 類,我們就可以在控制臺看出如下信息
    在這里插入圖片描述

  4. 步驟四:進行測試
    依舊是使用PostMan來測試,發送GET請求訪問localhost:8080/books/1
    可以看到響應回來的結果hello world!
    同時控制臺也輸出了get id = 1


1.1.2 對比

通過上面的入門案例我們可以看到使用 SpringBoot 進行開發,使整個開發變得很簡單,那它是如何做到的呢?

  • 要研究這個問題,我們需要看看 Application 類和 pom.xml 都書寫了什么。先看看 Applicaion 類,該類內容如下:

    @SpringBootApplication
    public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
    }
    

這個類中的東西很簡單,就在類上添加了一個 @SpringBootApplication 注解,而在主方法中就一行代碼。我們在啟動服務器時就是執行的該類中的主方法。

  • 再看看 pom.xml 配置文件中的內容
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <!--指定了一個父工程,父工程中的東西在該工程中可以繼承過來使用-->
    <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.3</version><relativePath/> <!-- lookup parent from repository -->
    </parent><groupId>com.blog</groupId>
    <artifactId>springboot_01_quickstart</artifactId>
    <version>0.0.1-SNAPSHOT</version><!--JDK 的版本-->
    <properties><java.version>1.8</java.version>
    </properties>
    <dependencies><!--該依賴就是我們在創建 SpringBoot 工程勾選的那個 Spring Web 產生的--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--這個是單元測試的依賴,我們現在沒有進行單元測試,所以這個依賴現在可以沒有--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
    </dependencies><build><plugins><!--這個插件是在打包時需要的,而這里暫時還沒有用到--><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
    

我們代碼之所以能簡化,就是因為指定的父工程和 Spring Web 依賴實現的

在這里插入圖片描述

  • 坐標
    Spring 程序中的坐標需要自己編寫,而且坐標非常多
    SpringBoot 程序中的坐標是我們在創建工程時進行勾選自動生成的
  • web3.0配置類
    Spring 程序需要自己編寫這個配置類。這個配置類我們之前編寫過,肯定感覺很復雜
    SpringBoot 程序不需要我們自己書寫
  • 配置類
    Spring/SpringMVC 程序的配置類需要自己書寫。而 SpringBoot 程序則不需要書寫。

注意:基于Idea的 Spring Initializr 快速構建 SpringBoot 工程時需要聯網。

1.1.3 官網構建工程

在入門案例中之所以能快速構建 SpringBoot 工程,是因為 Idea 使用了官網提供了快速構建 SpringBoot 工程的組件實現的。
首先進入SpringBoot官網 ,拉到頁面最下方,會有一個Quickstart your project
然后點擊Spring Initializr超鏈接,就會跳轉到如下頁面,構建工程的步驟與我們在IDEA中幾乎沒什么區別
在這里插入圖片描述
點擊GENERATE,就可以生成工程并下載到本地了,打開下載好的壓縮包,可以看到工程的內容與IDEA生成的一模一樣。

通過上面官網的操作,我們知道 Idea 中快速構建 SpringBoot 工程其實就是使用的官網的快速構建組件,那以后即使沒有 Idea 也可以使用官網的方式構建 SpringBoot 工程。

1.1.3 SpringBoot工程快速啟動

  • 問題引入
    以后我們和前端開發人員協同開發,而前端開發人員需要測試前端程序就需要后端開啟服務器,這就受制于后端開發人員。為了擺脫這個受制,前端開發人員嘗試著在自己電腦上安裝 TomcatIdea ,在自己電腦上啟動后端程序,這顯然不現實。
    我們后端可以將 SpringBoot 工程打成 jar 包,該 jar 包運行不依賴于 TomcatIdea 這些工具也可以正常運行,只是這個 jar 包在運行過程中連接和我們自己程序相同的 Mysql 數據庫即可,這樣就可以解決這個問題。
    在這里插入圖片描述

  • 那現在問題就是如何打包
    由于我們在構建 SpringBoot 工程時已經在 pom.xml 中配置了如下插件

<plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

所以我們只需要使用 Maven 的 package 指令打包就會在 target 目錄下生成對應的 Jar 包。
在這里插入圖片描述

注意:該插件必須配置,不然打好的 jar 包也是有問題的。

在這里插入圖片描述

在這里插入圖片描述

  • 啟動
    進入 jar 包所在位置,在 命令提示符 中輸入如下命令
java -jar springboot_01_quickstart-0.0.1-SNAPSHOT.jar

在這里插入圖片描述

執行上述命令就可以看到 SpringBoot 運行的日志信息,同時使用PostMan發送GET請求訪問localhost:8080/books/9527,也可以正常輸出get id ==> 9527
在這里插入圖片描述

在這里插入圖片描述

1.2 springBoot概述

SpringBoot 是由Pivotal團隊提供的全新框架,其設計目的是用來簡化Spring應用的初始搭建以及開發過程。

原始 Spring 環境搭建和開發存在以下問題:

  • 配置繁瑣
  • 依賴設置繁瑣 SpringBoot 程序優點恰巧就是針對 Spring 的缺點

springBoot程序優點:

  • 自動配置。這個是用來解決 Spring 程序配置繁瑣的問題
  • 起步依賴。這個是用來解決 Spring 程序依賴設置繁瑣的問題
  • 輔助功能(內置服務器,…)。我們在啟動 SpringBoot 程序時既沒有使用本地的 tomcat 也沒有使用 tomcat 插件,而是使用 SpringBoot 內置的服務器。

接下來我們來說一下 SpringBoot 的起步依賴

1.2.1 起步依賴

我們使用 Spring Initializr 方式創建的 Maven 工程的的 pom.xml 配置文件中自動生成了很多包含 starter 的依賴

<parent><groupId>org.springframework.boot</groupId><!--                      ↓↓↓              --><artifactId>spring-boot-starter-parent</artifactId><version>2.7.3</version><relativePath/> 
</parent>
<groupId>com.blog</groupId>
<artifactId>springboot_01_quickstart</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties><java.version>1.8</java.version>
</properties>
<dependencies><dependency><groupId>org.springframework.boot</groupId><!--                      ↓↓↓              --><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><!--                      ↓↓↓              --><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
</dependencies>

這些依賴就是啟動依賴,接下來探究一下它是如何實現的。

I. 探索父工程

從上面的文件中可以看到指定了一個父工程

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.3</version><relativePath/>
</parent>

我們進入到父工程,發現父工程中又指定了一個父工程

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.7.3</version>
</parent>

再進入到該父工程中,在該工程中我們可以看到配置內容結構如下:
在這里插入圖片描述

  • properties
    properties 標簽中定義了各個技術軟件依賴的版本,避免了我們在使用不同軟件技術時考慮版本的兼容問題。|dependencyManagement 標簽是進行依賴版本鎖定,但是并沒有導入對應的依賴;如果我們工程需要那個依賴只需要引入依賴的 groupid 和 artifactId 不需要定義 version。|而 build 標簽中也對插件的版本進行了鎖定

    <activemq.version>5.16.5</activemq.version>
    <antlr2.version>2.7.7</antlr2.version>
    <appengine-sdk.version>1.9.98</appengine-sdk.version>
    <artemis.version>2.19.1</artemis.version>
    <aspectj.version>1.9.7</aspectj.version>
    <assertj.version>3.22.0</assertj.version>
    <atomikos.version>4.0.6</atomikos.version>
    <awaitility.version>4.2.0</awaitility.version>
    <build-helper-maven-plugin.version>3.3.0</build-helper-maven-plugin.version>
    <byte-buddy.version>1.12.13</byte-buddy.version>
    ···
    
  • dependencManagement
    dependencyManagement 標簽是進行依賴版本鎖定,但是并沒有導入對應的依賴;如果我們工程需要那個依賴只需要引入依賴的 groupid 和 artifactId 不需要定義 version。

    <dependency><groupId>org.apache.activemq</groupId><artifactId>activemq-amqp</artifactId><version>${activemq.version}</version>
    </dependency>
    <dependency><groupId>org.apache.activemq</groupId><artifactId>activemq-blueprint</artifactId><version>${activemq.version}</version>
    </dependency>
    <dependency><groupId>org.apache.activemq</groupId><artifactId>activemq-broker</artifactId><version>${activemq.version}</version>
    </dependency>···
    
  • pluginManagement
    而 build 標簽中也對插件的版本進行了鎖定

    <plugin><groupId>org.codehaus.mojo</groupId><artifactId>build-helper-maven-plugin</artifactId>
    <version>${build-helper-maven-plugin.version}	</version>
    </plugin>
    <plugin><groupId>org.flywaydb</groupId><artifactId>flyway-maven-plugin</artifactId><version>${flyway.version}</version>
    </plugin>
    <plugin>
    <groupId>pl.project13.maven</groupId>
    <artifactId>git-commit-id-plugin</artifactId>
    <version>${git-commit-id-plugin.version}			</version>
    </plugin>···
    

看完了父工程中 pom.xml 的配置后不難理解我們工程的的依賴為什么都沒有配置 version。

II. 探索依賴

在創建的工程中的pom.xml中配置了如下依賴:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

進入到該依賴,查看pom.xml的依賴,會發現它引入了如下依賴

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><version>2.7.3</version><scope>compile</scope>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>5.3.22</version><scope>compile</scope>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.22</version><scope>compile</scope>
</dependency>

里面的引入了 spring-web 和 spring-webmvc 的依賴,這就是為什么我們的工程中沒有依賴這兩個包還能正常使用 springMVC 中的注解的原因。
而依賴 spring-boot-starter-tomcat ,從名字基本能確認內部依賴了 tomcat,所以我們的工程才能正常啟動。

結論:以后需要使用技術,只需要引入該技術對應的起步依賴即可

III. 小結

starter

  • SpringBoot 中常見項目名稱,定義了當前項目使用的所有項目坐標,以達到減少依賴配置的目的

parent

  • 所有 SpringBoot 項目要繼承的項目,定義了若干個坐標版本號(依賴管理,而非依賴),以達到減少依賴沖突的目的

實際開發

  • 使用任意坐標時,僅書寫GAV中的G和A,V由SpringBoot提供
    • G:groupid
    • A:artifactId
    • V:version
  • 如發生坐標錯誤,再指定version(要小心版本沖突)

1.2.2 程序啟動

創建的每一個 SpringBoot 程序時都包含一個類似于下面的類,我們將這個類稱作引導類

@SpringBootApplication
public class Springboot01QuickstartApplication {public static void main(String[] args) {SpringApplication.run(Springboot01QuickstartApplication.class, args);}
}

注意:

  • SpringBoot 在創建項目時,采用jar的打包方式
  • SpringBoot 的引導類是項目的入口,運行 main 方法就可以啟動項目 因為我們在 pom.xml 中配置了 spring-boot-starter-web 依賴,而該依賴通過前面的學習知道它依賴 tomcat ,所以運行 main 方法就可以使用
    tomcat 啟動咱們的工程。

1.2.3 切換web服務器-jetty

現在我們啟動工程使用的是 tomcat 服務器,那能不能不使用 tomcat 而使用 jetty 服務器。而要切換 web 服務器就需要將默認的 tomcat 服務器給排除掉,怎么排除呢?需要用到我們前面學的知識排除依賴,使用 exclusion 標簽

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><artifactId>spring-boot-starter-tomcat</artifactId><groupId>org.springframework.boot</groupId></exclusion></exclusions>
</dependency>

然后還要引入 jetty 服務器。

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

接下來再次運行引導類,在日志信息中就可以看到使用的是jetty服務器
在這里插入圖片描述

  • jetty比tomcat更輕量級,可擴展性更強,谷歌應用引擎(GAE)已經全面切換成jetty

小結:通過切換服務器,我們不難發現在使用 SpringBoot 換技術時只需要導入該技術的起步依賴即可。

二、配置文件

2.1 配置文件格式

2.1.1 不同配置文件演示

我們現在啟動服務器默認的端口號是 8080,訪問路徑可以書寫為
http://localhost:8080/books/1

在線上環境我們還是希望將端口號改為 80,這樣在訪問的時候就可以不寫端口號了,如下
在這里插入圖片描述

而 SpringBoot 程序如何修改呢?SpringBoot 提供了多種屬性配置方式

  • application.properties
    在這里插入圖片描述

    server.port=80
    
  • application.yml
    在這里插入圖片描述

    server:port: 81
    
  • application.yaml
    在這里插入圖片描述

    server:port: 82
    

注意:SpringBoot 程序的配置文件名必須是 application ,只是后綴名不同而已。

  1. application.properties配置文件
    • 配置文件必須放在 resources 目錄下,而該目錄下有一個名為 application.properties 的配置文件(SpringBoot已經為我們提供好了),我們就可以在該配置文件中修改端口號,在該配置文件中書寫 portIdea 就會補全提示

    • application.properties 配置文件內容如下:

      server.port=80
      
    • 啟動服務,會在控制臺打印出日志信息,從日志信息中可以看到綁定的端口號已經修改了

Tomcat initialized with port(s): 80 (http)

  1. application.yml配置文件

    • 刪除 application.properties 配置文件中的內容。在 resources 下創建一個名為 application.yml 的配置文件,在該文件中書寫端口號的配置項,格式如下:

      server:
      port: 81
      

      注意: 在:后,數據前一定要加空格。

    • 啟動服務,可以在控制臺看到綁定的端口號是 81

      Tomcat initialized with port(s): 81 (http)

  2. application.yaml配置文件

    • 刪除 application.yml 配置文件和 application.properties 配置文件內容,然后在 resources 下創建名為 application.yaml 的配置文件,配置內容和后綴名為 yml 的配置文件中的內容相同,只是使用了不同的后綴名而已

    • application.yaml 配置文件內容如下:

      server:
      port: 82
      
    • 啟動服務,在控制臺可以看到綁定的端口號

      Tomcat initialized with port(s): 82 (http)

如果想要在IDEA的這些有提示輸入,可進行如下操作:
在這里插入圖片描述

2.1.2 三種配合文件的優先級

在三種配合文件中分別配置不同的端口號,啟動服務查看綁定的端口號。用這種方式就可以看到哪個配置文件的優先級更高一些

  • application.properties 文件內容如下:

    server.port=80
    
  • application.yml 文件內容如下:

    server:
    port: 81
    
  • application.yaml 文件內容如下:

    server:
    port: 82
    
    • 啟動服務,在控制臺可以看到使用的端口號是 80。說明 application.properties 的優先級最高
    • 注釋掉 application.properties 配置文件內容。再次啟動服務,在控制臺可以看到使用的端口號是 81,說明 application.yml 配置文件為第二優先級。
    • 從上述的驗證結果可以確定三種配置文件的優先級是:application.properties > application.yml > application.yaml

以后開發主寫:yml格式的

注意:

  • SpringBoot 核心配置文件名為 application
  • SpringBoot 內置屬性過多,且所有屬性集中在一起修改,在使用時,通過代碼補全+關鍵字修改屬性
  • 例如要設置日志的級別時,可以在配置文件中書寫 logging,就會提示出來。配置內容如下

    logging:level:root: info
    

2.2 yaml

上面講了三種不同類型的配置文件,而 properties 類型的配合文件之前我們學習過,接下來我們重點學習 yaml 類型的配置文件。
YAML(YAML Ain’t Markup Language),一種數據序列化格式。這種格式的配置文件在近些年已經占有主導地位,那么這種配置文件和前期使用的配置文件是有一些優勢的,我們先看之前使用的配置文件。

  • 最開始我們使用的是 xml ,格式如下:

    <enterprise><name>Helsing</name><age>16</age><tel>400-957-241</tel>
    </enterprise>
    
  • 而 properties 類型的配置文件如下

    enterprise.name=Helsing
    enterprise.age=16
    enterprise.tel=400-957-241
    
  • yaml 類型的配置文件內容如下

    enterprise:name: Helsingage: 16tel: 400-957-241
    

在這里插入圖片描述

通過對比,我們得出yaml的優點有:

  • 容易閱讀
    • yaml 類型的配置文件比 xml 類型的配置文件更容易閱讀,結構更加清晰
  • 容易與腳本語言交互(暫時還體會不到,后面會了解)
  • 以數據為核心,重數據輕格式
    • yaml 更注重數據,而 xml 更注重格式

YAML 文件擴展名:

  • .yml (主流)
  • .yaml

上面兩種后綴名都可以,以后使用更多的還是 yml 的。


yml語法規則

  • 大小寫敏感
  • 屬性層級關系使用多行描述,每行結尾使用冒號結束
  • 使用縮進表示層級關系,同層級左側對齊,只允許使用空格(不允許使用Tab鍵)
    • 空格的個數并不重要,只要保證同層級的左側對齊即可。
  • 屬性值前面添加空格(屬性名與屬性值之間使用冒號+空格作為分隔)
  • ## 表示注釋

核心規則:數據前面要加空格與冒號隔開

  • 數組數據在數據書寫位置的下方使用減號作為數據開始符號,每行書寫一個數據,減號與數據間空格分隔,例如:
enterprise:name: itcastage: 16tel: 400-957-241subject:- Java- Python- C#

2.2.1 yaml配置文件格式讀取

基本語法

  • key: value -> value 前面一定要有空格
  • 大小寫敏感
  • 屬性層級關系使用多行描述,每行結尾使用冒號結束
  • 使用縮進表示層級關系,同層級左側對齊,只允許使用空格(不允許使用Tab鍵)
  • 屬性值前面添加空格(屬性名與屬性值之間使用冒號+空格作為分隔)
  • # 表示注釋
    核心規則:數據前面要加空格與冒號隔開

字面值表示方式
在這里插入圖片描述

數組表示方式:在屬性名書寫位置的下方使用減號作為數據開始符號,每行書寫一個數據,減號與數據間空格分隔
在這里插入圖片描述

I. 環境準備

修改resource目錄下的application.yml配置文件:

lesson: SpringBootserver:port: 8080enterprise:name: itcastage: 16tel: 400-957-241subject:- Java- Python- C#

在com.itheima.domain包下新建一個Enterprise類,用來封裝數據

package com.itheima.domain;import java.util.Arrays;public class Enterprise {private String name;private int age;private String tel;private String[] subject;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getTel() {return tel;}public void setTel(String tel) {this.tel = tel;}public String[] getSubject() {return subject;}public void setSubject(String[] subject) {this.subject = subject;}@Overridepublic String toString() {return "Enterprise{" +"name='" + name + '\'' +", age=" + age +", tel='" + tel + '\'' +", subject=" + Arrays.toString(subject) +'}';}
}
II. 讀取配置文件
  • 方式一:使用 @Value注解
    在這里插入圖片描述

    • 使用 @Value(“表達式”) 注解可以從配合文件中讀取數據,注解中用于讀取屬性名引用方式是:${一級屬性名.二級屬性名……}
    • 我們可以在 BookController 中使用 @Value 注解讀取配合文件數據,如下
    @RestController
    @RequestMapping("/books")
    public class BookController {
    @Value("${lesson}")
    private String lesson;
    @Value("${server.port}")
    private Integer port;
    @Value("${enterprise.subject[0]}")
    private String subject_0;@GetMapping("/{id}")
    public String getById(@PathVariable Integer id) {System.out.println(lesson);System.out.println(port);System.out.println(subject_0);return "hello , spring boot!";}
    }
    
    • 使用PostMan發送請求,控制臺輸出如下,成功獲取到了數據
    SpringBoot
    8080
    Java
    

在這里插入圖片描述

  • 方式二:使用Environment對象
    在這里插入圖片描述

    • 上面方式讀取到的數據特別零散,SpringBoot 還可以使用 @Autowired 注解注入 Environment 對象的方式讀取數據。這種方式 SpringBoot 會將配置文件中所有的數據封裝到 Environment 對象中,如果需要使用哪個數據只需要通過調用 Environment 對象的 getProperty(String name) 方法獲取。具體代碼如下:
      在這里插入圖片描述

      @RestController
      @RequestMapping("/books")
      public class BookController {
      @Autowired
      private Environment environment;@GetMapping("/{id}")
      public String getById(@PathVariable Integer id) {System.out.println(environment.getProperty("lesson"));System.out.println(environment.getProperty("enterprise.name"));System.out.println(environment.getProperty("enterprise.subject[1]"));return "hello , spring boot!";}
      }
      
    • 使用PostMan發送請求,控制臺輸出如下,成功獲取到了數據
      在這里插入圖片描述

      SpringBoot
      itcast
      Python
      

      注意:這種方式在開發中很少用,因為框架內含大量數據

  • 方式三:使用自定義對象(開發常用的)
    在這里插入圖片描述

    • SpringBoot 還提供了將配置文件中的數據封裝到我們自定義的實體類對象中的方式。具體操作如下:
    • 將實體類 bean 的創建交給 Spring 管理。
      • 在類上添加 @Component 注解
    • 使用 @ConfigurationProperties 注解表示加載配置文件
      • 在該注解中也可以使用 prefix 屬性指定只加載指定前綴的數據
    • BookController 中進行注入

具體代碼如下

  • Enterprise 實體類內容如下:

    @Component
    @ConfigurationProperties(prefix = "enterprise")
    public class Enterprise {
    private String name;
    private int age;
    private String tel;
    private String[] subject;public String getName() {return name;
    }public void setName(String name) {this.name = name;
    }public int getAge() {return age;
    }public void setAge(int age) {this.age = age;
    }public String getTel() {return tel;
    }public void setTel(String tel) {this.tel = tel;
    }public String[] getSubject() {return subject;
    }public void setSubject(String[] subject) {this.subject = subject;
    }@Override
    public String toString() {return "Enterprise{" +"name='" + name + '\'' +", age=" + age +", tel='" + tel + '\'' +", subject=" + Arrays.toString(subject) +'}';}
    }
    
  • BooKController內容如下

    @RestController
    @RequestMapping("/books")
    public class BookController {
    @Autowired
    private Enterprise enterprise;@GetMapping("/{id}")
    public String getById(@PathVariable Integer id) {System.out.println(enterprise);System.out.println(enterprise.getAge());System.out.println(enterprise.getName());System.out.println(enterprise.getTel());return "hello , spring boot!";}
    }
    
  • 使用PostMan發送請求,控制臺輸出如下,成功獲取到了數據

    Enterprise{name='Helsing', age=16, tel='400-957-241', subject=[Java, Python, C#]}
    16
    itcast
    400-957-241
    

在這里插入圖片描述

自定義對象封裝數據警告可能遇到的問題:

  • 在Enterprise實體類上遇到Spring Boot Configuration Annotation Processor not configured警告提示

解決方案

  • 在pom.xml中添加如下依賴即可:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>

2.3 多環境啟動

在這里插入圖片描述

以后在工作中,對于開發環境、測試環境、生產環境的配置肯定都不相同,比如我們開發階段會在自己的電腦上安裝 mysql ,連接自己電腦上的 mysql 即可,但是項目開發完畢后要上線就需要該配置,將環境的配置改為線上環境的。
來回的修改配置會很麻煩,而 SpringBoot 給開發者提供了多環境的快捷配置,需要切換環境時只需要改一個配置即可。不同類型的配置文件多環境開發的配置都不相同,接下來對不同類型的配置文件進行說明

2.3.1 yaml文件

application.yml 中使用 --- 來分割不同的配置,內容如下:

## 開發環境
spring:profiles: dev ## 給開發環境取的名
server:port: 80
---
## 生產環境
spring:profiles: pro ## 給生產環境取的名
server:port: 81
---
## 測試環境
spring:profiles: test ## 給測試環境起的名
server:port: 82

上面配置中 spring.profiles 是用來給不同的配置起名字的。而如何告知 SpringBoot 使用哪段配置呢?可以使用如下配置來啟用都一段配置

## 設置啟用的環境
spring:profiles:active: dev  ## 表示使用的是開發環境的配置

綜上所述,application.yml 配置文件內容如下

spring:profiles:active: dev
---
## 開發環境
spring:profiles: dev ## 給開發環境取的名
server:port: 80
---
## 生產環境
spring:profiles: pro ## 給生產環境取的名
server:port: 81
---
## 測試環境
spring:profiles: test ## 給測試環境起的名
server:port: 82
  • 注意:在上面配置中給不同配置起名字的 spring.profiles 配置項已經過時。最新用來起名字的配置項是

    ## 開發環境
    spring:
    config:activate:on-profile: dev ## 給開發環境取的名
    

那現在我們就可以嘗試啟用不同的環境,來觀察啟用端口號,證明是否真的啟用了不同的環境

在這里插入圖片描述
在這里插入圖片描述

2.3.2 properties文件

properties 類型的配置文件配置多環境需要定義不同的配置文件

  • application-dev.properties 是開發環境的配置文件。我們在該文件中配置端口號為 80

    server.port=80
    
  • application-dev.properties 是測試環境的配置文件。我們在該文件中配置端口號為 81

    server.port=81
    
  • application-pro.properties 是生產環境的配置文件。我們在該文件中配置端口號為 82

    server.port=82
    
  • SpringBoot 只會默認加載名為 application.properties 的配置文件,所以需要在 application.properties 配置文件中設置啟用哪個配置文件,配置如下:

    server.port=82
    

2.3.3 命令行啟動參數設置

使用 SpringBoot 開發的程序以后都是打成 jar 包,通過 java -jar xxx.jar 的方式啟動服務的。那么就存在一個問題,如何切換環境呢?因為配置文件打到的jar包中了。

  • 我們知道 jar 包其實就是一個壓縮包,可以解壓縮,然后修改配置,最后再打成jar包就可以了。這種方式顯然有點麻煩,而 SpringBoot 提供了在運行 jar 時設置開啟指定的環境的方式,如下:

    java -jar xxx.jar --spring.profiles.active=test
    
  • 那么這種方式能不能臨時修改端口號呢?也是可以的,可以通過如下方式:

    java -jar xxx.jar --server.port=9421
    
  • 當然也可以同時設置多個配置,比如即指定啟用哪個環境配置,又臨時指定端口,如下:

    java -jar xxx.jar -server.port=9421 --spring.profiles.active=pro
    

那現在命令行配置的端口號是9421,配置文件中的端口號為82,那么結果將會是多少呢?
測試后就會發現命令行設置的端口號優先級高(也就是使用的是命令行設置的端口號),配置的優先級其實 SpringBoot 官網已經進行了說明,詳情參見
如果使用了多種方式配合同一個配置項,優先級高的生效。

在這里插入圖片描述

2.3.4 maven與springboot多環境兼容問題

maven的優先級高
在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
第一次打包失敗了的原因是:
在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述

2.4 配置文件分類

有這樣的場景,我們開發完畢后需要測試人員進行測試,由于測試環境和開發環境的很多配置都不相同,所以測試人員在運行我們的工程時需要臨時修改很多配置,如下:

java –jar springboot.jar –-spring.profiles.active=test --server.port=85 --server.servlet.context-path=/heima --server.tomcat.connection-timeout=-1 …… …… …… …… ……

在這里插入圖片描述

針對這種情況,SpringBoot 定義了配置文件不同的放置的位置;而放在不同位置的優先級時不同的

  • springBoot 中4級配置文件放置位置:

    • 1級:classpath:application.yml
    • 2級:classpath:config/application.yml
    • 3級:file :application.yml
    • 4級:file :config/application.yml

    說明:級別越高的優先級越高

  • 1級和2級

    • 1級就是resource目錄下的application.yml

      server:port: 80
      
    • 2級是在resource目錄下新建一個config文件,在其中新建application.yml

      server:
      port: 81
      

啟動引導類,控制臺輸出的為81端口

Tomcat initialized with port(s): 81 (http)

  • 3級和4級
    • 先將工程打成一個jar包,進入到jar包的目錄下,創建application.yml 配置文件,而在該配合文件中將端口號設置為 82

      server:port: 82
      
    • 在 jar 包所在位置創建 config 文件夾,在該文件夾下創建 application.yml 配置文件,而在該配合文件中將端口號設置為 83

      server:port: 82
      

在命令行使用以下命令運行程序

java -jar springboot_06_config_file-0.0.1-SNAPSHOT.jar

運行后日志信息如下,端口為83

Tomcat initialized with port(s): 83 (http)

通過這個結果可以得出一個結論 config下的配置文件優先于類路徑下的配置文件。
IDEA的類路徑下的文件,是最低級的

在這里插入圖片描述

三、SpringBoot整合Junit

先來回顧一下 Spring 整合 junit
在這里插入圖片描述
使用 @RunWith 注解指定運行器,使用 @ContextConfiguration 注解來指定配置類或者配置文件。

而 SpringBoot 整合 junit 特別簡單,分為以下三步完成

  • 在測試類上添加 SpringBootTest 注解
  • 使用 @Autowired 注入要測試的資源
  • 定義測試方法進行測試

3.1 環境準備

  • 建一個新的SpringBoot工程

  • 在com.itheima.service包下創建BookService接口

    public interface BookService {void save();}
    
  • 在com.itheima.service.impl包下創建BookService接口的實現類,并重寫其方法

    @Service
    public class BookServiceImpl implements BookService {
    @Override
    public void save() {System.out.println("book service is running ..");}
    }
    

3.2 編寫測試類

test/java 下創建 com.itheima 包,在該包下創建測試類,將 BookService 注入到該測試類中

@SpringBootTest
class Springboot02JunitApplicationTests {@Autowiredprivate BookService bookService;@Testvoid contextLoads() {bookService.save();}}

運行測試方法,控制臺成功輸出
在這里插入圖片描述

在這里插入圖片描述

注意:這里的引導類所在包必須是測試類所在包及其子包。

例如:

  • 引導類所在包是 com.itheima
  • 測試類所在包是 com.itheima

如果不滿足這個要求的話,就需要在使用 @SpringBootTest 注解時,使用 classes 屬性指定引導類的字節碼對象。如
@SpringBootTest(classes = XxxApplication.class)

四、SpringBoot整合Mybatis

4.1 回顧Spring整合MyBatis

之前Spring整合MyBatis時,需要定義很多配置類
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

4.2 SpringBoot整合MyBatis

創建一個新的模塊
注意選擇技術集的時候,要勾選MyBatis Framework和MySQL Driver

  • 建庫建表

    CREATE DATABASE springboot_db;
    USE spring_db;CREATE TABLE tb1_book
    (
    id          INT PRIMARY KEY AUTO_INCREMENT,
    `type`      VARCHAR(20),
    `name`      VARCHAR(50),
    description VARCHAR(255)
    );INSERT INTO `tb1_book`(`id`, `type`, `name`, `description`)
    VALUES (1, '計算機理論', 'Spring實戰 第五版', 'Spring入門經典教程,深入理解Spring原理技術內幕'),(2, '計算機理論', 'Spring 5核心原理與30個類手寫實踐', '十年沉淀之作,手寫Spring精華思想'),(3, '計算機理論', 'Spring 5設計模式', '深入Spring源碼刨析Spring源碼中蘊含的10大設計模式'),(4, '計算機理論', 'Spring MVC+Mybatis開發從入門到項目實戰','全方位解析面向Web應用的輕量級框架,帶你成為Spring MVC開發高手'),(5, '計算機理論', '輕量級Java Web企業應用實戰', '源碼級刨析Spring框架,適合已掌握Java基礎的讀者'),(6, '計算機理論', 'Java核心技術 卷Ⅰ 基礎知識(原書第11版)','Core Java第11版,Jolt大獎獲獎作品,針對Java SE9、10、11全面更新'),(7, '計算機理論', '深入理解Java虛擬機', '5個緯度全面刨析JVM,大廠面試知識點全覆蓋'),(8, '計算機理論', 'Java編程思想(第4版)', 'Java學習必讀經典,殿堂級著作!贏得了全球程序員的廣泛贊譽'),(9, '計算機理論', '零基礎學Java(全彩版)', '零基礎自學編程的入門圖書,由淺入深,詳解Java語言的編程思想和核心技術'),(10, '市場營銷', '直播就這么做:主播高效溝通實戰指南', '李子柒、李佳奇、薇婭成長為網紅的秘密都在書中'),(11, '市場營銷', '直播銷講實戰一本通', '和秋葉一起學系列網絡營銷書籍'),(12, '市場營銷', '直播帶貨:淘寶、天貓直播從	新手到高手', '一本教你如何玩轉直播的書,10堂	課輕松實現帶貨月入3W+');
    
  • 定義實體類

    public class Book {
    private Integer id;
    private String type;
    private String name;
    private String description;public Integer getId() {return id;
    }public void setId(Integer id) {this.id = id;
    }public String getType() {return type;
    }public void setType(String type) {this.type = type;
    }public String getName() {return name;
    }public void setName(String name) {this.name = name;
    }public String getDescription() {return description;
    }public void setDescription(String description) {this.description = description;
    }@Override
    public String toString() {return "Book{" +"id=" + id +", type='" + type + '\'' +", name='" + name + '\'' +", description='" + description + '\'' +'}';}
    }
    
  • 定義dao接口
    在com.itheima.dao包下定義BookDao接口

    public interface BookDao {@Select("select * from tb1_book where id = #{id}")Book getById(Integer id);
    }
    
  • 定義測試類

    @SpringBootTest
    class Springboot03MybatisApplicationTests {@Autowiredprivate BookDao bookDao;@Testvoid contextLoads() {Book book = bookDao.getById(1);System.out.println(book);}}
    
  • 編寫配置

    spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/springboot_db?serverTimezone=UTCusername: rootpassword: root
    
  • 測試
    運行測試方法,會報錯No qualifying bean of type ‘com.itheima.dao.BookDao’,沒有類型為“com.itheima.dao.BookDao”的限定bean
    為什么會出現這種情況呢?之前我們在配置MyBatis時,配置了如下內容

    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
    MapperScannerConfigurer msc = new 	MapperScannerConfigurer();msc.setBasePackage("com.blog.dao");return msc;
    }
    

Mybatis 會掃描接口并創建接口的代碼對象交給 Spring 管理,但是現在并沒有告訴 Mybatis 哪個是 dao 接口。
而我們要解決這個問題需要在BookDao 接口上使用 @Mapper ,BookDao 接口修改為

@Mapper
public interface BookDao {@Select("select * from tb1_book where id = #{id}")Book getById(Integer id);
}

在這里插入圖片描述

注意: SpringBoot 版本低于2.4.3(不含),Mysql驅動版本大于8.0時,需要在url連接串中配置時區
jdbc:mysql://localhost:3306/springboot_db?serverTimezone=UTC,或在MySQL數據庫端配置時區解決此問題

4.3 SpringBoot整合Druid

  • 使用Druid數據源
    現在我們并沒有指定數據源,SpringBoot 有默認的數據源,我們也可以指定使用 Druid 數據源,按照以下步驟實現

    <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.12</version>
    </dependency>
    
  • 在 application.yml 修改配置文件配置
    可以通過 spring.datasource.type 來配置使用什么數據源。配置文件內容可以改進為

    spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/springboot_db?serverTimezone=UTCusername: rootpassword: PASSWORD.type: com.alibaba.druid.pool.DruidDataSource
    

五、案例

接下來將學習 SSM 時做的三大框架整合的案例用 SpringBoot 來實現一下。先將之前做的SSM整合的代碼拷貝過來,修改成SpringBoot的,之后再自己手動敲一遍SpringBoot的全流程,就當復盤了。

5.1 創建工程

創建一個新的SpringBoot工程,注意要勾選Spring Web,MyBatis Framework和MySQL Driver
由于我們工程中使用到了 Druid ,所以需要導入 Druid 的坐標

<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.12</version>
</dependency>

5.2 代碼拷貝

將之前的ssm整合工程的代碼拷貝過來,將com.itheima包下的所有內容拷貝過來,放在對應的位置即可。
需要修改的內容如下:

  • com.itheima.config包直接刪掉,SpringBoot并不需要這些配置類

  • 在dao包下的接口上,加上@Mapper注解

    @Mapper
    public interface BookDao {
    @Insert("insert into tb1_book values (null, #{type}, #{name}, #{description})")
    int save(Book book);@Update("update tb1_book set type=#{type}, `name`=#{name}, `description`=#{description} where id=#{id}")
    int update(Book book);@Delete("delete from tb1_book where id=#{id}")
    int delete(Integer id);@Select("select * from tb1_book where id=#{id}")
    Book getById(Integer id);@Select("select * from tb1_book")
    List<Book> getAll();
    }
    
  • 將測試類也修改為SpringBoot的

    @SpringBootTest
    public class BookServiceTest {@Autowired
    private BookService bookService;@Test
    public void testGetById() {Book book = bookService.getById(1);System.out.println(book);
    }@Test
    public void testGetAll() {for (Book book : bookService.getAll()) {System.out.println(book);}}
    }
    

5.3 配置文件

在application.yml配置文件中配置如下內容

  • 服務的端口號(設為80,這樣我們就不用寫了)
  • 連接數據庫的信息(數據庫連接四要素)
  • 數據源(德魯伊)
server:port: 80
spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/springboot_db?serverTimezone=UTCusername: rootpassword: root.

5.4 靜態資源

在 SpringBoot 程序中是沒有 webapp 目錄的,那么在 SpringBoot 程序中靜態資源需要放在什么位置呢?
靜態資源需要放在 resources 下的 static 下
那我們再配置一個默認頁面,跳轉到我們的增刪改頁面,新建index.html,寫入以下內容

<script>document.location.href="/pages/books.html"
</script>

這樣當我們在瀏覽器輸入localhost,然后直接按回車,就能直接跳轉到增刪改的頁面了,如果以后我們需要頻繁測試某一個頁面,也可以將上述代碼中的地址換為我們要測試的地址,這樣就不用老手敲地址了

那么至此,將之前的ssm整合,改為springboot的工作,就完成了

在這里插入圖片描述

六、總結

6.1 流程分析

  1. 創建工程
    • 創建一個SpringBoot工程
    • 需要勾選Spring WebMyBatis Framework和MySQL Driver
  2. SpringBoot整合
    • 整合MyBatis
      • 添加Druid數據源依賴
      • 編寫數據庫配置文件(application.yml),配置數據庫連接四要素
      • 對于Dao層的包掃描,使用@Mapper注解
    • 整合Junit
      • 使用@SpringBootTest注解
  3. 功能模塊
    • 創建數據庫和表
    • 根據數據表來創建對應的模型類
    • 通過Dao層完成數據庫的增刪改
    • 編寫Service層(Service接口+實現類)
    • 編寫Controller層
      • 接收請求 @RequestMapping@GetMapping@PostMapping@PutMapping@DeleteMapping
      • 接收數據 簡單類型、POJO類型、嵌套POJO類型、數組類型、JSON數據類型
      • @RequestParam
      • @PathVariable
      • @RequestBody
    • 轉發業務層
      • 使用@Autowired自動裝配
    • 響應結果
      • @ResponseBody

6.2 整合配置

  1. 步驟一:創建一個SpringBoot工程
    注意要勾選Spring Web,MyBatis Framework和MySQL Driver
  2. 步驟二:創建項目包結構
    • com.itheima.controller 編寫Controller類
    • com.itheima.dao 存放的是Dao層的接口,注意要使用@Mapper注解
    • com.itheima.service 存放的是Service層接口,
    • com.itheima.service.impl 存放的是Service的實現類
    • com.itheima.domain 存放的是pojo類
    • resources/static 存放靜態資源HTML,CSS,JS等
    • test/java 存放測試類
  3. 步驟三:編寫application.yml
    導入Druid的坐標,并在配置文件中編寫數據庫連接四要素
server:port: 80
spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/spring_db?serverTimezone=UTCusername: rootpassword: root.

6.3 功能模塊開發

  • 步驟一:創建數據庫和表

    create database spring_db;
    use spring_db;
    create table tb1_book
    (
    id          int primary key auto_increment,
    type        varchar(20),
    `name`      varchar(50),
    description varchar(255)
    );insert into `tb1_book`(`id`, `type`, `name`, `description`)
    values (1, '計算機理論', 'Spring實戰 第五版', 'Spring入門經典教程,深入理解Spring原理技術內幕'),(2, '計算機理論', 'Spring 5核心原理與30個類手寫實踐', '十年沉淀之作,手寫Spring精華思想'),(3, '計算機理論', 'Spring 5設計模式', '深入Spring源碼刨析Spring源碼中蘊含的10大設計模式'),(4, '計算機理論', 'Spring MVC+Mybatis開發從入門到項目實戰','全方位解析面向Web應用的輕量級框架,帶你成為Spring MVC開發高手'),(5, '計算機理論', '輕量級Java Web企業應用實戰', '源碼級刨析Spring框架,適合已掌握Java基礎的讀者'),(6, '計算機理論', 'Java核心技術 卷Ⅰ 基礎知識(原書第11版)','Core Java第11版,Jolt大獎獲獎作品,針對Java SE9、10、11全面更新'),(7, '計算機理論', '深入理解Java虛擬機', '5個緯度全面刨析JVM,大廠面試知識點全覆蓋'),(8, '計算機理論', 'Java編程思想(第4版)', 'Java學習必讀經典,殿堂級著作!贏得了全球程序員的廣泛贊譽'),(9, '計算機理論', '零基礎學Java(全彩版)', '零基礎自學編程的入門圖書,由淺入深,詳解Java語言的編程思想和核心技術'),(10, '市場營銷', '直播就這么做:主播高效溝通實戰指南', '李子柒、李佳奇、薇婭成長為網紅的秘密都在書中'),(11, '市場營銷', '直播銷講實戰一本通', '和秋葉一起學系列網絡營銷書籍'),(12, '市場營銷', '直播帶貨:淘寶、天貓直播從新手到高手', '一本教你如何玩轉直播的書,10堂課輕松實現帶貨月入3W+');
    
  • 步驟二:編寫實體類

    public class Book {
    private Integer id;
    private String type;
    private String name;
    private String description;public Integer getId() {return id;
    }public void setId(Integer id) {this.id = id;
    }public String getType() {return type;
    }public void setType(String type) {this.type = type;
    }public String getName() {return name;
    }public void setName(String name) {this.name = name;
    }public String getDescription() {return description;
    }public void setDescription(String description) {this.description = description;
    }@Override
    public String toString() {return "Book{" +"id=" + id +", type='" + type + '\'' +", name='" + name + '\'' +", description='" + description + '\'' +'}';}
    }
    
  • 步驟三:編寫dao接口
    注意使用@Mapper注解

    @Mapper
    public interface BookDao {
    @Select("select * from tbl_book where id=#{id}")
    Book getById(Integer id);@Select("select * from tbl_book")
    List<Book> getAll();@Update("update tbl_book set type=#{type}, `name`=#{name}, `description`=#{description} where id=#{id}")
    int update(Book book);@Delete("delete from tbl_book where id=#{id}")
    int delete(Integer id);@Insert("insert into tbl_book values (null, #{type}, #{name}, #{description})")
    int save(Book book);
    }
    
  • 步驟四:編寫service接口及其實現類

    public interface BookService {
    boolean save(Book book);boolean update(Book book);boolean delete(Integer id);Book getById(Integer id);List<Book> getAll();
    }
    
    @Service
    public class BookServiceImpl implements BookService {@Autowired
    private BookDao bookDao;@Override
    public boolean save( Book book) {int cnt = bookDao.save(book);return cnt > 0;
    }@Override
    public boolean update(Book book) {int cnt = bookDao.update(book);return cnt>0;
    }@Override
    public boolean delete(Integer id) {return bookDao.delete(id) > 0;
    }@Override
    public Book getById(Integer id) {return bookDao.getById(id);
    }@Override
    public List<Book> getAll() {return bookDao.getAll();}
    }
    
  • 步驟五:編寫Controller類
    注意響應pojo類型加@RequestBody注解

    @RestController
    @RequestMapping("/books")
    public class BookController {
    @Autowired
    private BookService bookService;@GetMapping("/{id}")
    public Book getById(@PathVariable Integer id) {return bookService.getById(id);
    }@GetMapping
    public List<Book> getAll() {return bookService.getAll();
    }@PostMapping
    public boolean save(@RequestBody Book book) {return bookService.save(book);
    }@PutMapping
    public boolean update(@RequestBody Book book) {return bookService.update(book);
    }@DeleteMapping("/{id}")
    public boolean delete(@PathVariable Integer id) {return bookService.delete(id);}
    }
    
  • 步驟六:使用PostMan進行測試
    將增刪改查全部測試完畢之后,就可以繼續往下做了

6.4 統一結果封裝

  • 創建一個返回結果類
    我這里暫時只需要返回的結果,狀態碼和異常信息,如果還有別的需求,可以自行刪改

    public class Result {
    private Object data;
    private Integer code;
    private String msg;public Object getData() {return data;
    }public void setData(Object data) {this.data = data;
    }public Integer getCode() {return code;
    }public void setCode(Integer code) {this.code = code;
    }public String getMsg() {return msg;
    }public void setMsg(String msg) {this.msg = msg;
    }@Override
    public String toString() {return "Result{" +"data=" + data +", code=" + code +", msg='" + msg + '\'' +'}';}
    }
    
  • 定義狀態碼Code類
    狀態碼也可以根據自己的需求來自定義

    public class Code {
    public static final Integer SAVE_OK = 20011;
    public static final Integer SAVE_ERR = 20010;public static final Integer UPDATE_OK = 20021;
    public static final Integer UPDATE_ERR = 20020;public static final Integer DELETE_OK = 20031;
    public static final Integer DELETE_ERR = 20030;public static final Integer GET_OK = 20041;
    public static final Integer GET_ERR = 20040;public static final Integer SYSTEM_ERR = 50001;
    public static final Integer SYSTEM_TIMEOUT_ERR = 50002;
    public static final Integer SYSTEM_UNKNOW_ERR = 59999;public static final Integer BUSINESS_ERR = 60001;
    }
    
  • 修改Controller類的返回值

    @RestController
    @RequestMapping("/books")
    public class BookController {
    @Autowired
    private BookService bookService;@GetMapping("/{id}")
    public Result getById(@PathVariable Integer id) {Book book = bookService.getById(id);Integer code = book == null ? Code.GET_ERR : Code.GET_OK;String msg = book == null ? "數據查詢失敗,請重試!" : "";return new Result(code, book, msg);
    }@GetMapping
    public Result getAll() {List<Book> books = bookService.getAll();Integer code = books == null ? Code.GET_ERR : Code.GET_OK;String msg = books == null ? "數據查詢失敗,請重試!" : "";return new Result(code, books, msg);
    }@PostMapping
    public Result save(@RequestBody Book book) {boolean flag = bookService.save(book);return new Result(flag ? Code.SAVE_OK : Code.SAVE_ERR, flag);
    }@PutMapping
    public Result update(@RequestBody Book book) {boolean flag = bookService.update(book);return new Result(flag ? Code.UPDATE_OK : Code.UPDATE_ERR, flag);
    }@DeleteMapping("/{id}")
    public Result delete(@PathVariable Integer id) {boolean flag = bookService.delete(id);return new Result(flag ? Code.DELETE_OK : Code.DELETE_ERR, flag);
    }
    }
    

6.5 統一異常處理

  • 將異常進行分類
    這里只將其劃分為了業務異常和系統異常
    在com.itheima.exception包下新建兩個異常類

    public class BusinessException extends 	RuntimeException {
    private Integer code;public Integer getCode() {return code;
    }public void setCode(Integer code) {this.code = code;
    }public BusinessException(Integer code) {super();this.code = code;
    }public BusinessException(Integer code, String message) {super(message);this.code = code;
    }public BusinessException(Integer code, String message, Throwable cause) {super(message, cause);this.code = code;}
    }
    
    public class SystemException extends RuntimeException {
    private Integer code;public Integer getCode() {return code;
    }public void setCode(Integer code) {this.code = code;
    }public SystemException(Integer code) {this.code = code;
    }public SystemException(Integer code, String message) {super(message);this.code = code;
    }public SystemException(Integer code, String message, Throwable cause) {super(message, cause);this.code = code;}
    }
    
  • 同時再增加幾個狀態碼

    public static final Integer SYSTEM_ERR = 50001;
    public static final Integer SYSTEM_TIMEOUT_ERR = 50002;
    public static final Integer SYSTEM_UNKNOW_ERR = 59999;
    public static final Integer BUSINESS_ERR = 60001;
    
  • 測試異常
    可以getById方法中來進行測試,當id為1時,錯誤碼為BUSINESS_ERR,當查詢其他id時,均為SYSTEM_UNKNOW_ERR,錯誤提示信息為服務器訪問超時,請稍后再試

@Service
public class BookServiceImpl implements BookService {@Autowiredprivate BookDao bookDao;@Overridepublic boolean save(Book book) {int cnt = bookDao.save(book);return cnt > 0;}@Overridepublic boolean update(Book book) {int cnt = bookDao.update(book);return cnt > 0;}@Overridepublic boolean delete(Integer id) {return bookDao.delete(id) > 0;}@Overridepublic Book getById(Integer id) {if (id == 1){throw new BusinessException(Code.BUSINESS_ERR,"不讓你瞅");}try {int a = 1 / 0;} catch (Exception e) {throw new SystemException(Code.SYSTEM_UNKNOW_ERR, "服務器訪問超時,請稍后再試");}return bookDao.getById(id);}@Overridepublic List<Book> getAll() {return bookDao.getAll();}
}

6.6 前端內容

前端內容同上一章的一樣,沒有變

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/212101.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/212101.shtml
英文地址,請注明出處:http://en.pswp.cn/news/212101.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C語言精選——選擇題Day43

第一題 1. 使用malloc系統調用分配的內存是在什么上分配的&#xff1f; A&#xff1a;棧 B&#xff1a;堆 答案及解析 B malloc開辟的空間都是在堆上申請的內存空間&#xff0c;但是我們平常定義的定長數組之類的&#xff0c;都是在棧上開辟的空間&#xff1b; 第二題 2. C語言…

scala變量與變量類型

1.6 變量與類型&#xff08;重點&#xff09;1.6.1 變量推斷1.6.2 多變量定義1.6.3 var和val的區別 1.6.3.1 是否可變 1.6.3.2 延遲加載 1.6 變量與類型&#xff08;重點&#xff09; val修飾的變量&#xff0c;相當于Java中final修飾的變量; // 定義常量s1&#xff0c;使用…

[每周一更]-(第76期):Go源碼閱讀與分析的方式

讀源碼可以深層理解Go的編寫方式&#xff0c;理解作者們的思維方式&#xff1b;也有助于對Go語法用法深刻的理解&#xff0c;我們從這一篇說一下如何讀源碼&#xff0c;從哪些源碼著手&#xff0c;從 簡單到深入的方式學習源碼&#xff1b; 學習源碼也是一個修煉過程&#xff0…

「斗破年番」卡點俠蕭炎又卡點救人,四長老毒氣攻心,黑皇城尋寶

Hello,小伙伴們&#xff0c;我是拾荒君。 《斗破蒼穹年番》第74集如約而至&#xff0c;帶給觀眾們更多的驚喜與感動。這一集中&#xff0c;蕭炎的體內魔毒斑暫時被厄難毒體所壓制&#xff0c;他決定回到迦南學院&#xff0c;尋求斗尊強者的幫助解決這個問題。然而&#xff0c;…

深入理解 Flask 中的 Session 和 Cookies

在構建 web 應用時,管理用戶的狀態和數據是至關重要的。Flask,作為一個靈活的微型 web 框架,提供了會話(Session)和 Cookies 管理的能力。本文將深入探討 Flask 中的會話和 Cookies 的概念、工作機制以及應用實例,為讀者提供全面而詳細的理解。 會話和 Cookies 的基本概…

【LeetCode熱題100】【滑動窗口】找到字符串中所有字母異位詞

給定兩個字符串 s 和 p&#xff0c;找到 s 中所有 p 的 異位詞 的子串&#xff0c;返回這些子串的起始索引。不考慮答案輸出的順序。 異位詞 指由相同字母重排列形成的字符串&#xff08;包括相同的字符串&#xff09;。 示例 1: 輸入: s "cbaebabacd", p "…

611.有效的三角形個數

1.題目解析 給定一個包含非負整數的數組 nums &#xff0c;返回其中可以組成三角形三條邊的三元組個數。 補充&#xff1a; 1.三角形的判斷&#xff1a;假設有三條邊按大小排序&#xff1a; 2.題目示例 示例 1: 輸入: nums [2,2,3,4] 輸出: 3 解釋:有效的組合是: 2,3,4 (使用…

P1161 開燈題解

題目 在一條無限長的路上&#xff0c;有一排無限長的路燈&#xff0c;編號為1,2,3,4,…。 每一盞燈只有兩種可能的狀態&#xff0c;開或者關。如果按一下某一盞燈的開關&#xff0c;那么這盞燈的狀態將發生改變。如果原來是開&#xff0c;將變成關。如果原來是關&#xff0c;…

C現代方法(第27章)筆記——C99對數學計算的新增支持

文章目錄 第27章 C99對數學計算的新增支持27.1 <stdint.h>: 整數類型(C99)27.1.1 <stdint.h>類型27.1.2 對指定寬度整數類型的限制27.1.3 對其他整數類型的限制27.1.4 用于整型常量的宏 27.2 <inttype.h>: 整數類型的格式轉換(C99)27.2.1 用于格式指定符的宏…

人工智能與自然語言處理

人工智能&#xff08;AI&#xff09;與自然語言處理&#xff08;NLP&#xff09;是當前科技領域的兩大熱門話題。人工智能通過模擬人類的思維過程和智能行為&#xff0c;使計算機具備了一定的智能和自學能力。而自然語言處理則是指計算機對人類語言進行理解、處理和生成的技術。…

PCIe MPS參數介紹及如何更改

目錄 1.簡介 2.主要功能作用 3.MPS控制策略 4.如何更改 1.簡介 MPS 該參數含義是一個TLP包里攜帶的有效凈荷的最大值是多少字節&#xff08;該限制條件同時適用于寫操作和讀操作&#xff09;。 MRRS 該參數含義是一個TLP讀請求包&#xff0c;一次最多能向接收端請求讀出…

計算機畢業設計JAVA+SSM+springboot養老院管理系統

設計了養老院管理系統&#xff0c;該系統包括管理員&#xff0c;醫護人員和老人三部分。同時還能為用戶提供一個方便實用的養老院管理系統&#xff0c;管理員在使用本系統時&#xff0c;可以通過系統管理員界面管理用戶的信息&#xff0c;也可以進行個人中心&#xff0c;醫護等…

LeetCode 108. 將有序數組轉換為二叉搜索樹

對于算法題&#xff0c;按題型類別刷題才會更有成效&#xff0c;因此我這里在網上搜索并參考了下 “&#x1f525; LeetCode 熱題 HOT 100” 的題型歸類&#xff0c;并在其基礎上做了一定的完善&#xff0c;希望能夠記錄自己的刷題歷程&#xff0c;有所收獲&#xff01;點擊下發…

點滴生活記錄2

我從小跟著我爺爺奶奶&#xff0c;小學六年級轉到縣城上小學&#xff0c;就沒跟我奶奶他們住一起了。十一回家&#xff0c;把奶奶接到我這住&#xff0c;細想&#xff0c;自六年級之后&#xff0c;就很少跟奶奶住一起了。 奶奶&#xff08;間歇性&#xff09;耳聾&#xff0c;為…

104. 二叉樹的最大深度

給定一個二叉樹 root &#xff0c;返回其最大深度。二叉樹的最大深度 是指從根節點到最遠葉子節點的最長路徑上的節點數。 深度就是在層序遍歷的基礎上&#xff0c;每層遍歷一次&#xff0c;就增加一次深度&#xff01; import java.util.ArrayList; import java.util.LinkedL…

軟件測試相關

軟件測試是什么&#xff1f; 使用人工和自動手段來運行或測試某個系統的過程&#xff0c;其目的在于驗證它是否滿足規定的需求或弄清預期結果與實際結果的差別。 為什么做軟件測試&#xff1f;目的是什么&#xff1f; 發現軟件存在的代碼或業務邏輯錯誤 檢驗產品是否符合用戶需…

堅鵬:中國郵政儲蓄銀行數字化轉型戰略、方法與案例培訓

中國郵政儲蓄銀行擁有優良的資產質量和顯著的成長潛力&#xff0c;是中國領先的大型零售銀行。2016年9月在香港聯交所掛牌上市&#xff0c;2019年12月在上交所掛牌上市。中國郵政儲蓄銀行擁有近4萬個營業網點&#xff0c;服務個人客戶超6.5億戶。2022年&#xff0c;在《銀行家》…

算法Day24 不專心開車

不專心開車 Description 小碩開車經過一條公路&#xff0c;這條路線總共由n 1個不同海拔的點組成。小碩從海拔為0的點0開始騎行。 給小碩一個長度為n的整數數組arr&#xff0c;其中arr[i]是點i和點i 1的凈海拔高度差&#xff08;0≤i < n&#xff09;。請你返回最高點的海…

【LeetCode刷題-二叉樹】--110.平衡二叉樹

110.平衡二叉樹 方法一&#xff1a;自頂向下遞歸 對于當前遍歷到的節點&#xff0c;首先計算左右子樹的高度&#xff0c;如果左右子樹的高度差是否不超過 111&#xff0c;再分別遞歸地遍歷左右子節點&#xff0c;并判斷左子樹和右子樹是否平衡。這是一個自頂向下的遞歸的過程。…

力扣:197. 上升的溫度(Python3)

題目&#xff1a; 表&#xff1a; Weather ------------------------ | Column Name | Type | ------------------------ | id | int | | recordDate | date | | temperature | int | ------------------------ id 是該表具有唯一值的列。 該表…