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開發為例
-
創建一個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>
-
編寫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}; } }
-
編寫SpringMvc配置類
@Configuration @ComponentScan("com.blog.controller") @EnableWebMvc public class SpringMvcConfig implements WebMvcConfigurer {}
-
編寫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版本
-
步驟一:創建新模塊
在IDEA下創建一個新模塊,選擇Spring Initializr
,用來創建SpringBoot工程
https://start.aliyun.com/
選中Web
,然后勾選Spring Web
,由于我們需要開發一個web
程序,使用到了SpringMVC
技術,所以按照下圖紅框進行勾選
最后點擊創建,就大功告成了,經過以上步驟后就創建了如下結構的模塊,它會幫我們自動生成一個Application
類,而該類一會再啟動服務器時會用到注意:
- 在創建好的工程中不需要創建配置類
- 創建好的項目會自動生成其他的一些文件,而這些文件目前對我們來說沒有任何作用,所以可以將這些文件刪除。
- 可以刪除的目錄和文件如下:
- .mvn
- .gitignore
- HELP.md
- mvnw
- mvnw.cmd
-
步驟二:創建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";} }
-
步驟三:啟動服務器
運行 SpringBoot 工程不需要使用本地的 Tomcat 和 插件,只運行項目 com.itheima 包下的 Application 類,我們就可以在控制臺看出如下信息
-
步驟四:進行測試
依舊是使用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工程快速啟動
-
問題引入
以后我們和前端開發人員協同開發,而前端開發人員需要測試前端程序就需要后端開啟服務器,這就受制于后端開發人員。為了擺脫這個受制,前端開發人員嘗試著在自己電腦上安裝Tomcat
和Idea
,在自己電腦上啟動后端程序,這顯然不現實。
我們后端可以將SpringBoot
工程打成jar
包,該jar
包運行不依賴于Tomcat
和Idea
這些工具也可以正常運行,只是這個 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 ,只是后綴名不同而已。
application.properties
配置文件-
配置文件必須放在
resources
目錄下,而該目錄下有一個名為application.properties
的配置文件(SpringBoot已經為我們提供好了),我們就可以在該配置文件中修改端口號,在該配置文件中書寫port
,Idea
就會補全提示 -
application.properties
配置文件內容如下:server.port=80
-
啟動服務,會在控制臺打印出日志信息,從日志信息中可以看到綁定的端口號已經修改了
-
Tomcat initialized with port(s): 80 (http)
-
application.yml配置文件
-
刪除 application.properties 配置文件中的內容。在 resources 下創建一個名為 application.yml 的配置文件,在該文件中書寫端口號的配置項,格式如下:
server: port: 81
注意: 在:后,數據前一定要加空格。
-
啟動服務,可以在控制臺看到綁定的端口號是 81
Tomcat initialized with port(s): 81 (http)
-
-
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
是開發環境的配置文件。我們在該文件中配置端口號為 80server.port=80
-
application-dev.properties
是測試環境的配置文件。我們在該文件中配置端口號為 81server.port=81
-
application-pro.properties
是生產環境的配置文件。我們在該文件中配置端口號為 82server.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 流程分析
- 創建工程
- 創建一個SpringBoot工程
- 需要勾選
Spring Web
,MyBatis
Framework
和MySQL Driver
- SpringBoot整合
- 整合MyBatis
- 添加Druid數據源依賴
- 編寫數據庫配置文件(
application.yml
),配置數據庫連接四要素 - 對于Dao層的包掃描,使用
@Mapper
注解
- 整合
Junit
- 使用
@SpringBootTest
注解
- 使用
- 整合MyBatis
- 功能模塊
- 創建數據庫和表
- 根據數據表來創建對應的模型類
- 通過
Dao層
完成數據庫的增刪改 - 編寫
Service層
(Service接口+實現類) - 編寫
Controller層
- 接收請求
@RequestMapping
、@GetMapping
、@PostMapping
、@PutMapping
、@DeleteMapping
- 接收數據 簡單類型、POJO類型、嵌套POJO類型、數組類型、JSON數據類型
@RequestParam
@PathVariable
@RequestBody
- 接收請求
- 轉發業務層
- 使用
@Autowired
自動裝配
- 使用
- 響應結果
@ResponseBody
6.2 整合配置
- 步驟一:創建一個SpringBoot工程
注意要勾選Spring Web,MyBatis Framework和MySQL Driver - 步驟二:創建項目包結構
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
存放測試類
- 步驟三:編寫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 前端內容
前端內容同上一章的一樣,沒有變