SpringBoot簡明教程

HuskySir發表於2021-05-19

一、SpringBoot簡介

1、什麼是SpringBoot

SpringBoot用來簡化spring應用開發,約定大於配置,去繁從簡,是J2EE一站式解決方案

2、SpringBoot的優點

  1. 快速建立獨立執行的Spring專案以及主流框架的整合

  2. 使用嵌入式的Servlet容器,應用無需打成WAR包

  3. starts自動依賴與版本控制

  4. 大量的自動配置,簡化開發,也可修改預設值

  5. 無需配置XML,無程式碼生成,開箱即用

  6. 準生成環境的執行時應用監控

  7. 與雲端計算天然整合

3、Spring Boot Flow體系結構

 

4、SpringBoot專案

1.SpringBoot專案常見目錄結構

2.SpringBoot專案分層

(1)Controller層:控制層

Controller層負責具體的業務模組流程的控制。Controller層負責前後端互動,接受前端請求,呼叫Service層,接收Service層返回的資料,最後返回具體的頁面和資料到客戶端。

(2)Service層:業務層

Service層負責業務模組的邏輯應用設計。先設計放介面的類,再建立實現的類,然後在配置檔案中進行配置其實現的關聯。Service層呼叫Dao層介面,接收Dao層返回的資料,完成專案的基本功能設計。封裝Service層的業務邏輯有利於業務邏輯的獨立性和重複利用性。

(3)Dao層:資料訪問層

Dao層負責與資料庫進行互動。Dao層封裝對於資料庫的增刪改查,不涉及業務邏輯,只是達到按某個條件對資料庫中的資料進行某一具體操作的要求。(有的專案中也將Dao層寫為Mapper層)

(4)Domain層:資料表物件層

Domain層定義資料庫中儲存的實體類。(有的專案也將Domain層寫為Entity層或Model層)

(5)Config層:配置類層

Config層定義一些與配置有關的類。

3.工作流程

二、Controller層(demo1_controller專案)

1、新建專案

安裝IDEA:JAVA語言開發的整合環境

安裝JDK:JAVA開發工具包

安裝Maven:專案包管理工具,在pom.xml中寫要使用的庫,maven可自動下載

1.專案建立過程

1.點開File-New-Project,在左側欄中找到Spring Initializr,在Project SDK欄中選擇JDK版本(8),然後點選Next

2.填完資訊後,點選Next

此處的組織名和專案名由自己命名,僅是一個專案識別符號,沒有特別的規則

3.此介面可以選擇需要的依賴於選擇SpringBoot的版本。此時我們只需要用到spring Web依賴,點選Next。如果後續需求有所變化,可以在pom.xml檔案進行修改

4.檢查當前頁面,點選Finish,此時已經成功新建一個SpringBoot專案

2.新建專案的目錄結構

  • /src/main/java/com/example/demo1_controller/Demo1ControllerApplication:啟動類

  • /src/main/resources目錄下目錄結構

    • static:儲存所有的靜態資源 js css images

    • templates:儲存所有的模板頁面(SpringBoot預設jar包使用嵌入式的Tomcat,預設不支援jsp頁面,可以使用模板引擎freemarker、thyleaf),由於現在傾向前後端開發的模式(後臺springboot,前端採用vue,react等),因此模板引擎逐漸在被主流技術淘汰。

    • application.properties:SpringBoot應用配置檔案,可以修改一些預設設定。(springboot支援properties和yaml兩種格式的配置檔案,只要檔名是application,springboot均可識別。)

  • /src/test/java/com/example/demo1_controller/Demo1ControllerApplicationTests:測試類


專案使用的JDK版本可以在File->Project Structure資料夾下的內容進行修改

專案使用的Maven版本可以在File->Settings->Build,Execution,Deployment->Build Toos->Maven下修改

3.部分檔案內容

  • pom.xml檔案

檢視目前pom.xml的依賴模組

 1 <!-- web模組 -->
 2 <dependency>
 3     <groupId>org.springframework.boot</groupId>
 4     <artifactId>spring-boot-starter-web</artifactId>
 5 </dependency>
 6 <!-- test模組 -->
 7 <dependency>
 8     <groupId>org.springframework.boot</groupId>
 9     <artifactId>spring-boot-starter-test</artifactId>
10     <scope>test</scope>
11 </dependency>

新增maven-compiler-plugin外掛指定jdk版本(根據實際情況(就是有沒有報錯)看是否要加,有的人不加也沒有問題)。

 1 <build>
 2     <plugins>
 3         <plugin>
 4             <groupId>org.springframework.boot</groupId>
 5             <artifactId>spring-boot-maven-plugin</artifactId>
 6         </plugin>
 7  8         <!-- maven-compiler-plugin外掛 指定專案原始碼及編譯後的Jdk版本 -->
 9         <plugin>
10             <groupId>org.apache.maven.plugins</groupId>
11             <artifactId>maven-compiler-plugin</artifactId>
12             <version>3.8.1</version>
13             <configuration>
14                 <source>1.8</source>
15                 <target>1.8</target>
16             </configuration>
17         </plugin>
18     </plugins>
19 </build>
  • application.properties檔案內容為空

2、Controller類

1.新建Controller類

  1. 在/src/main/java/com/example/demo1_controller目錄下新建資料夾controller(右鍵demo1_controller資料夾->New->Package:controller

  2. controller資料夾下新建類StudentController(右鍵controller資料夾->New->Java Class:StudentController

  3. StudentController類上添上註解@Controller,表明這是一個controller類(可以在裡面定義一些路由函式)

    此時StudentController.java檔案全部內容為

    1 package com.example.demo1_controller.Controller;
    2 3 import org.springframework.stereotype.Controller;
    4 5 @Controller
    6 public class StudentController {
    7 }

2.嘗試後端給前端返回一個Hello World內容

在StudentController方法類寫HelloWorld()方法

1 @ResponseBody
2 @RequestMapping(value = "/helloworld")
3 public String HelloWorld() {
4     return "Hello World";
5 }

(1)@RequestMapping("url")是處理請求地址對映,url是請求路徑的一部分。(@RequestMapping表明這是一個路由函式)

此時前端請求路徑為:http://localhost:8080/helloworld,專案執行結果

@RequestMapping("url")也可以用在controller類上,此時controller類中的方法的請求路徑後部分內容為類的url拼接上方法的url

如在controller類上新增@RequestMapping("/student")

 1 @Controller
 2 @RequestMapping(value = "/student")
 3 public class StudentController {
 4  5     @ResponseBody
 6     @RequestMapping(value = "/helloworld")
 7     public String HelloWorld() {
 8         return "Hello World";
 9     }
10 }

此時前端請求路徑為http://localhost:8080/student/helloworld,專案執行結果


(2)@ResponseBody註解的作用是將controller的方法返回的物件通過適當的轉換器轉換為指定的格式之後,寫入到response物件的body區,通常用來返回JSON資料或者是XML資料

controller類的方法可以通過返回值進行頁面跳轉,如果採用@ResponseBody則使該方法直接返回資料給前端

@ResponseBody註解可以直接放在controller類上,則表示該類所有方法返回值都是給前端的資料

 1 @Controller
 2 @ResponseBody
 3 @RequestMapping(value = "/student")
 4 public class StudentController {
 5  6     @RequestMapping(value = "/helloworld")
 7     public String HelloWorld() {
 8         return "Hello World";
 9     }
10 }

此時專案執行結果與(1)相同


(3)@RestController相當於@ResponseBody + @Controller合在一起的作用,是一種簡潔寫法。

1 @RestController
2 @RequestMapping(value = "/student")
3 public class StudentController {
4 5     @RequestMapping(value = "/helloworld")
6     public String HelloWorld() {
7         return "Hello World";
8     }
9 }

此時專案執行結果與(1)相同

3.初始頁面

SpringBoot預設的頁面對映路徑(即模板檔案存放的位置)為“classpath:/templates/*.html”。靜態檔案路徑為“classpath:/static/”,其中可以存放JS、CSS等模板共用的靜態檔案

SpringBoot整合了springmvc的攔截功能,攔截了所有的請求。預設放行的資源是:resources/static/ 目錄下所有靜態資源。(不走controller控制器就能直接訪問到資源)html頁面如果放在resources/templates目錄下,則需要走controller控制器,controller放行,允許該資源訪問,該資源才能被訪問到。否則就會報404錯誤

此時resources/staticresources/templates 目錄下都為空

我們在resources/static目錄下新建HTML檔案index.html,此時目錄結構

index.html檔案內容

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>初始頁面</title>
 6 </head>
 7 <body>
 8 歡迎來到SpringBoot
 9 </body>
10 </html>

專案執行訪問初始頁面

如果我們想更換初始頁面,可以通過配置SpringMVC來實現(此處以thymeleaf模板引擎作為演示,知道thymeleaf的樣子是什麼即可,不用專門學,但實際使用static目錄下的html檔案也可以完成,配置類中的寫法略作修改即可。)

 

1 匯入thymeleaf依賴

在pom.xml檔案<dependencies></dependencies>標籤內新增thymeleaf模組

1 <!-- thymeleaf模組 -->
2 <dependency>
3     <groupId>org.springframework.boot</groupId>
4     <artifactId>spring-boot-starter-thymeleaf</artifactId>
5 </dependency>

在pom.xml檔案<properties></properties>標籤內設定thymeleaf模組版本

1 <!-- 設定thymeleaf模板引擎的模板 -->
2 <thymeleaf.version>3.0.11.RELEASE</thymeleaf.version>
3 <thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>

2 新建一個初始頁面studentlist.html

在resources/templates目錄下新建資料夾stduent,student資料夾下新建studentlist.html檔案

    

3 編寫一個配置類

(1)在/src/main/java/com/example/demo1_controller目錄下新建資料夾config

(2)在config資料夾下新建類MyMvcConfig

(3)MyMvcConfig實現WebMvcConfigurer介面與使用@Configuration表明為配置類

(4)新增檢視控制器

 1 package com.example.demo1_controller.config;
 2 
 3 import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
 4 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 5 
 6 @Configuration
 7 public class MyMvcConfig implements WebMvcConfigurer {
 8 
 9     /**
10      * 檢視控制器
11      * @param registry
12      */
13     @Override
14     public void addViewControllers(ViewControllerRegistry registry) {
15         //初始頁面設定為"student/studentlist"
16         //第一次引數為指定訪問路徑,第二個引數為指定訪問檢視名
17         registry.addViewController("/").setViewName("student/studentlist");
18     }
19 }

此時執行專案的初始頁面為

  

注意:不可在MyMvcConfig上註解@EnableWebMvc,若註解@EnableWebMvc,表明全面接管SpringMVC配置。不使用@EnableWebMvc註解,僅表示在SpringBoot預設配置上對SpringMVC進行擴充套件

更換初始頁面也可以不使用thymeleaf模板,直接在resources/static資料夾下新建html檔案,然後在配置類MyMvcConfig的檢視控制器方法中增加訪問路徑與檢視名的對映即可,實際專案中因為前後端分離,也不會使用thymeleaf模板進行開發


4.CRUD操作

(1)請求路徑

Restful風格

 普通CRUDRestfulCRUD
查詢 getStudent student---GET
新增 addStudent?xxx student---POST
修改 updateStudent?id=xxx&xxx=xxx student/{id}---PUT
刪除 deleteStduent?id=1 stduent/{id}---DELETE

普通的CRUD用的是易於理解的請求路徑,如getStudent(獲取學生,GET請求)、addStudent(新增學生,GET請求)?xxx

RestFul風格的CRUD可以使用同名的請求路徑,通過不同的請求方式來區分具體的請求:如查詢與新增請求路徑都是.../student,但GET方法是查詢,POST方法是新增。將url視為資源,根據HTTP請求方式(HTTP協議的內容)對資源產生不同的操作GET是查詢、POST是新增、PUT是更新、DELETE是刪除。

請求架構

 請求uri請求方式
查詢所有學生 students GET
查詢某個學生(來到修改頁面) student/{id} GET
來到新增頁面 student GET
新增學生 student POST
來到修改頁面(查詢某個學生) student/{id} GET
修改學生 student PUT
刪除學生 student/{id} DELETE

(2)學生實體類

  1. 在/src/main/java/com/example/demo1_controller目錄下新建資料夾domain

  2. domain資料夾下新建類Student

  3. 寫好屬性與方法

     1 package com.example.demo1_controller.domain;
     2  3 import org.springframework.format.annotation.DateTimeFormat;
     4  5 import java.io.Serializable;
     6 import java.util.Date;
     7  8 /**
     9  * Student類 學生實體類
    10  */
    11 public class Student implements Serializable {
    12 13     private Integer id;         //學號
    14     private String name;        //姓名
    15     private Integer score;      //成績
    16     private String birthplace;  //籍貫
    17     //日期的格式 年-月-日
    18     @DateTimeFormat(pattern = "yyyy-MM-dd")
    19     private Date birthday;      //生日
    20 21     public Integer getId() {
    22         return id;
    23     }
    24 25     public void setId(Integer id) {
    26         this.id = id;
    27     }
    28 29     public String getName() {
    30         return name;
    31     }
    32 33     public void setName(String name) {
    34         this.name = name;
    35     }
    36 37     public Integer getScore() {
    38         return score;
    39     }
    40 41     public void setScore(Integer score) {
    42         this.score = score;
    43     }
    44 45     public String getBirthplace() {
    46         return birthplace;
    47     }
    48 49     public void setBirthplace(String birthplace) {
    50         this.birthplace = birthplace;
    51     }
    52 53     public Date getBirthday() {
    54         return birthday;
    55     }
    56 57     public void setBirthday(Date birthday) {
    58         this.birthday = birthday;
    59     }
    60 61     @Override
    62     public String toString() {
    63         return "Student{" +
    64                 "id=" + id +
    65                 ", name='" + name + '\'' +
    66                 ", score=" + score +
    67                 ", birthplace='" + birthplace + '\'' +
    68                 ", birthday=" + birthday +
    69                 '}';
    70     }
    71 }

(3)新增學生

①在studentlist.html頁面新增新增按鈕

 1 <!DOCTYPE html>
 2 <html lang="en"xmlns:th="http://www.thymeleaf.org">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>學生列表</title>
 6 </head>
 7 <body>
 8     <div>
 9         <a th:href="@{/student}">
10             <button>新增學生</button>
11         </a>
12     </div>
13 </body>
14 </html>

<a></a>標籤裡的th:href就是請求路徑

注意:新建的html檔案沒有指定使用thymeleaf模板引擎,需要在<html></html>標籤裡新增xmlns:th="http://www.thymeleaf.org"

studentlist.html頁面


②編寫controller類的ToStudent()方法

使用者點選新增按鈕,我們需要能夠跳轉到學生資訊的新增頁面,故將/student路徑對映到一個可以跳轉至學生資訊新增頁面的方法上

 1 package com.example.demo1_controller.controller;
 2  3 import org.springframework.stereotype.Controller;
 4 import org.springframework.web.bind.annotation.GetMapping;
 5 import org.springframework.web.bind.annotation.RequestMapping;
 6 import org.springframework.web.bind.annotation.ResponseBody;
 7  8 @Controller
 9 public class StudentController {
10 11     @ResponseBody
12     @RequestMapping(value = "/helloworld")
13     public String HelloWorld() {
14         return "Hello World";
15     }
16 17     /**
18      * 來到學生資訊頁面
19      * @return
20      */
21     @GetMapping(value = "/student")
22     public String ToStudent() {
23 24         return "student/studentinfo";
25     }
26 }

因為需要用到頁面跳轉,所以該controller就不註解為@RestController,需要直接返回資料給前端的可以用@ResponseBody註解

@GetMapping("url")相當於@RequestMapping(valus = "url",method = RequestMethod.GET)也是一種簡潔寫法。


③新增studentinfo.html頁面

在resources/templates/student資料夾下新建studentinfo.html檔案,寫一個表單輸入需要新增的學生資訊

 1 <!DOCTYPE html>
 2 <html lang="en"xmlns:th="http://www.thymeleaf.org">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>學生資訊</title>
 6 </head>
 7 <body>
 8     <form th:action="@{/student}" method="post">
 9         <div>
10             <label>學號</label>
11             <input name="id">
12         </div>
13         <div>
14             <label>姓名</label>
15             <input name="name">
16         </div>
17         <div>
18             <label>成績</label>
19             <input name="score">
20         </div>
21         <div>
22             <label>籍貫</label>
23             <input name="birthplace">
24         </div>
25         <div>
26             <label>生日</label>
27             <input name="birthday" type="date">
28         </div>
29         <button type="submit" th:text="新增"></button>
30     </form>
31 </body>
32 </html>
表單中th:action是請求路徑,method為請求方式,此處為POST請求

studentinfo.html頁面


④編寫controller類的AddStudent()方法

 1 /**
 2 * 新增學生資訊
 3 * @param student
 4 * @return
 5 */
 6 @PostMapping(value = "/student")
 7 public String AddStudent(Student student) {
 8 
 9     //執行新增學生資訊操作,本專案未連線資料庫,僅在控制檯輸出需要儲存的學生資料
10     System.out.println(student);
11     //跳轉至學生列表頁面
12     return "student/studentlist";
13 }

@PostMapping("url")相當於@RequestMapping(valus = "url",method = RequestMethod.POST)

因為SpringBoot專案中有Student類,會把前端輸入的資料自動封裝到Student類中,使用Student類裡的toString方法把資料輸出到控制檯。


⑤業務流程

  1. 來到初始介面:學生列表頁面(與①中頁面一樣)

  2. 點選新增學生按鈕來到學生資訊頁面,輸入資料

  3. 點選新增按鈕回到學生列表頁面(與①中頁面一樣),控制檯可以看到前端寫入的學生資料

(4)查詢學生

①在studentlist.html頁面新增學生學號輸入框及查詢按鈕

1     <div>
2         <form th:action="@{/student/{id}}" method="get">
3             <input name="id">
4             <button type="submit" th:text="查詢"></button>
5         </form>
6     </div>
此處請求路徑為xxx/studnet/{id},請求方式為GET

②編寫controller類的FindStudentById()方法

 1 /**
 2      * 查詢某個學生資訊
 3      * @param id
 4      * @return
 5      */
 6 @GetMapping(value = "/student/{id}")
 7 public String FindStudentById(Integer id) {
 8  9     //執行通過學生id從資料庫查詢學生資訊操作,本專案未連線資料庫,僅在控制檯輸出學生id
10     System.out.println("所查詢學生的學號"+id);
11     //跳轉至學生資訊頁面
12     return "student/studentinfo";
13 }

③業務流程

  1. 來到初始頁面

  2. 在輸入框輸入需要查詢的學生學號

  3. 點選查詢按鈕後來到學生資訊頁面,如果連線了資料庫執行了查詢操作後會在本頁面顯示該學生的資訊

  4. 控制檯輸出所查詢的學生學號


    因為新增學生和查詢學生用的同一個學生資訊頁面,即studentinfo.html,新增學生跳轉的學生資訊頁面下方按鈕應該為“新增”,而查詢學生跳轉的學生資訊頁面下方按鈕可以省略,或者下方變為兩個按鈕:修改與刪除。可以採用判斷是否有student值,如果為空則說明是新增學生跳轉過來的頁面,如果非空則說明是查詢學生跳轉過來的頁面,具體方法在此不詳談。

(5)修改學生

需要修改學生則應當首先查詢到學生,查詢過程與(4)查詢學生相同

此時查詢成功後跳轉至學生資訊頁面,下方有修改及刪除按鈕

由於本專案未連線資料庫,無法判斷學生資訊頁面是由新增學生按鈕還是查詢學生按鈕跳轉,所以不再實現功能

(6)刪除學生

(5)修改學生,此處不再實現

5、常用註解

  • RequestMapping
     1 public @interface RequestMapping {
     2     String name() default "";
     3 
     4     @AliasFor("path")
     5     String[] value() default {};
     6 
     7     @AliasFor("value")
     8     String[] path() default {};
     9 
    10     RequestMethod[] method() default {};
    11 
    12     String[] params() default {};
    13 
    14     String[] headers() default {};
    15 
    16     String[] consumes() default {};
    17 
    18     String[] produces() default {};
    19 }
    • value: 指定請求的實際地址,指定的地址可以是具體地址、可以RestFul動態獲取、也可以使用正則設定

    • method: 指定請求的method型別, 分為GET、POST、PUT、DELETE等

    • consumes: 指定處理請求的提交內容型別(Content-Type),例如application/json, text/html

    • produces: 指定返回的內容型別,僅當request請求頭中的(Accept)型別中包含該指定型別才返回

    • params: 指定request中必須包含某些引數值是,才讓該方法處理

    • headers: 指定request中必須包含某些指定的header值,才能讓該方法處理請求

    主要理解value及method,其餘引數一般不用。

三、Service層(demo2_service專案)

1、新建專案

新建專案過程與demo1_controller專案類似,不再贅述

2、Servie層處理前端請求並返回資料

1.環境準備

pom.xml檔案裡也要新增thymeleaf模組,指定thymeleaf版本,以及新增maven-compiler-plugin外掛指定jdk版本,具體方法demo1_controller已經展示過

2.新建StudentController類

在src/main/java/com/example/demo2_service目錄下新建controller資料夾,並在controller資料夾下新建StudentController類,StudentController上註解@RestController

3.新建Service介面及ServiceImpl類

在src/main/java/com/example/demo2_service目錄下新建service資料夾,在service資料夾下新建StudentService介面impl資料夾,在impl資料夾下再新建StudentServiceImpl類並實現StudentService介面,在StudentServiceImpl類上用@Service註解表明這是一個Service類

4.在Service介面及ServiceImpl類中宣告及實現方法

在StudentService介面中宣告getFibonacciResult(Integer number)方法

1 /**
2   * 通過前端傳入資料計算斐波那契數列值
3   * @param number
4   * @return
5   */
6 public Integer getFibonacciResult(Integer number);

在StduentServiceImpl類中實現getFibonacciResult(Integer number)方法

 1 /**
 2   * 通過前端傳入資料計算斐波那契數列值
 3   * @param number
 4   * @return
 5   */
 6 @Override
 7 public Integer getFibonacciResult(Integer number) {
 8 
 9     if (number == 1 || number == 2) {
10         return 1;
11     } else {
12         return getFibonacciResult(number - 1) + getFibonacciResult(number - 2);
13     }
14 }

5.編寫controller類

使用@Autowired自動注入StudentService,並編寫getFibonacciResult(Integer number)方法

 1 @Autowired
 2 StudentService studentService;
 3 
 4 /**
 5   * 前端輸入初始值,返回斐波那契數列值
 6   * @param number
 7   * @return
 8   */
 9 @RequestMapping("/getFibonacciResult")
10 public Integer getFibonacciResult(Integer number) {
11 
12     return studentService.getFibonacciResult(number);
13 }

通過@Autowired自動注入StudentService,就可以從controller層使用service層的類物件,並呼叫其方法,物件的建立、銷燬等生命週期由SpringBoot管理,開發者不用考慮

6.配置SpringMVC

(此步驟非必要,一般是在springboot專案中,修改預設啟動頁(預設啟動頁是static/index.html),修改@ResponseBody返回json轉換方式,新增資源過濾,配置跨域,新增攔截器等操作需要配置mvc。)

在src/main/java/com/example/demo2_service目錄下新建config資料夾,並在config資料夾下新建MyMvcConfig類

MyMvcConfig類

 1 package com.example.demo2_service.config;
 2 
 3 import org.springframework.context.annotation.Configuration;
 4 import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
 5 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 6 
 7 @Configuration
 8 public class MyMvcConfig implements WebMvcConfigurer {
 9 
10     /**
11      * 檢視控制器
12      * @param registry
13      */
14     @Override
15     public void addViewControllers(ViewControllerRegistry registry) {
16         //初始頁面設定為"student"
17         //第一次引數為指定訪問路徑,第二個引數為指定訪問檢視名
18         registry.addViewController("/").setViewName("student");
19     }
20 }

7.新建並編寫Student.html檔案

在resources/templates目錄下新建Student.html檔案,並編寫一個input輸入框與button按鈕,用於前端向後端提交資料

 1 <!DOCTYPE html>
 2 <html lang="en"xmlns:th="http://www.thymeleaf.org">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8     <div>
 9         <form th:action="@{/getFibonacciResult}" method="post">
10             <input name="number">
11             <button type="submit" th:text="提交"></button>
12         </form>
13     </div>
14 </body>
15 </html>

8.業務流程

  1. 來到初始頁面student.html,在input輸入框內輸入數字10

  2.  點選提交按鈕,即可得到經過Service層計算得到的返回值

3、Service層將Dao層的資料傳遞給前端

一般dao層是用於讀寫資料庫的層,此處使用程式碼中固定的資料來模擬資料庫讀寫,章節四中會連線資料庫,演示實際讀寫資料庫的操作。

1.新建StudentDao類

在src/main/java/com/example/demo2_service目錄下新建dao資料夾,並在dao資料夾下新建StudentDao類,StudentDao上註解@Repository表明這是一個Dao類

注意:正常SpringBoot專案開發中,Dao層一般設定為介面而非具體類

2.編寫StudentDao類

 1 package com.example.demo2_service.dao;
 2 
 3 import org.springframework.stereotype.Repository;
 4 
 5 /**
 6  * 資料訪問層
 7  */
 8 @Repository
 9 public class StudentDao {
10 
11     String studentDaoString = new String("from StudentDao");
12 
13     /**
14      * 得到Dao層資料
15      * @return
16      */
17     public String getStudentDaoString() {
18         return studentDaoString;
19     }
20 }

此處getStudentDaoString()方法為返回一個字串

3.編寫StudentService介面與StudentServiceImpl類

StduentService介面

 1 package com.example.demo2_service.service;
 2 
 3 /**
 4  * 業務層
 5  */
 6 public interface StudentService {
 7 
 8     /**
 9      * 通過前端傳入資料計算斐波那契數列值
10      * @param number
11      * @return
12      */
13     public Integer getFibonacciResult(Integer number);
14 
15     /**
16      * 得到Dao層資料
17      * @return
18      */
19     public String getStudentDaoString();
20 
21 }

StudentServiceImpl類

 1 package com.example.demo2_service.service.impl;
 2 
 3 import com.example.demo2_service.dao.StudentDao;
 4 import com.example.demo2_service.service.StudentService;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.stereotype.Service;
 7 
 8 /**
 9  * 業務層
10  */
11 @Service
12 public class StudentServiceImpl implements StudentService {
13 
14     @Autowired
15     StudentDao studentDao;
16 
17     /**
18      * 通過前端傳入資料計算斐波那契數列值
19      * @param number
20      * @return
21      */
22     @Override
23     public Integer getFibonacciResult(Integer number) {
24 
25         if (number == 1 || number == 2) {
26             return 1;
27         } else {
28             return getFibonacciResult(number - 1) + getFibonacciResult(number - 2);
29         }
30     }
31 
32     /**
33      * 得到Dao層資料
34      * @return
35      */
36     @Override
37     public String getStudentDaoString() {
38         return studentDao.getStudentDaoString();
39     }
40 }

4.編寫StduentController類

 1 package com.example.demo2_service.controller;
 2 
 3 import com.example.demo2_service.service.StudentService;
 4 import org.springframework.beans.factory.annotation.Autowired;
 5 import org.springframework.web.bind.annotation.RequestMapping;
 6 import org.springframework.web.bind.annotation.RestController;
 7 
 8 /**
 9  * 控制層
10  */
11 @RestController
12 public class StudentController {
13 
14     @Autowired
15     StudentService studentService;
16 
17     /**
18      * 前端輸入初始值,返回斐波那契數列值
19      * @param number
20      * @return
21      */
22     @RequestMapping("/getFibonacciResult")
23     public Integer getFibonacciResult(Integer number) {
24 
25         return studentService.getFibonacciResult(number);
26     }
27 
28     /**
29      * 通過Service層得到Dao層的資料
30      * @return
31      */
32     @RequestMapping("/getStudentDaoString")
33     public String getStudentDaoString() {
34         return studentService.getStudentDaoString();
35     }
36 }

5.業務流程

前端訪問http://localhost:8080/getStudentDaoString地址

 

四、Dao層(demo3_dao專案)

1、新建專案

新建專案過程與demo1_controller專案類似,不再贅述

2、環境準備

需要安裝

MySQL(建議安裝MySQL8版本)

Navicat for MySQL

1.pom.xml

jdbc模組、druid模組、log4j2模組、mysql驅動模組、mybatis模組

 1 <!-- jdbc模組 spring讀寫資料庫的庫 -->
 2 <dependency>
 3     <groupId>org.springframework.boot</groupId>
 4     <artifactId>spring-boot-starter-jdbc</artifactId>
 5 </dependency>
 6 
 7 <!-- druid模組 資料庫連線池(池子裡放一些連線,每次直接取,不用新建提升效能) -->
 8 <dependency>
 9     <groupId>com.alibaba</groupId>
10     <artifactId>druid</artifactId>
11     <version>1.1.20</version>
12 </dependency>
13 
14 <!-- log4j2模組 日誌 -->
15 <dependency>
16     <groupId>log4j</groupId>
17     <artifactId>log4j</artifactId>
18     <version>1.2.17</version>
19 </dependency>
20 
21 <!-- mysql驅動模組 連線mysql的驅動 -->
22 <dependency>
23     <groupId>mysql</groupId>
24     <artifactId>mysql-connector-java</artifactId>
25     <version>8.0.23</version>
26 </dependency>
27 
28 <!-- mybatis模組 spring讀寫資料庫的另一個庫 -->
29 <dependency>
30     <groupId>org.mybatis.spring.boot</groupId>
31     <artifactId>mybatis-spring-boot-starter</artifactId>
32     <version>2.1.4</version>
33 </dependency>

同樣使用maven-compiler-plugin外掛指定專案原始碼及編譯後的Jdk版本

 1 <!-- maven-compiler-plugin外掛 指定專案原始碼及編譯後的Jdk版本 -->
 2 <plugin>
 3     <groupId>org.apache.maven.plugins</groupId>
 4     <artifactId>maven-compiler-plugin</artifactId>
 5     <version>3.8.1</version>
 6     <configuration>
 7         <source>1.8</source>
 8         <target>1.8</target>
 9     </configuration>
10 </plugin>

2.application.yaml

預設配置檔案為application.properties,我們採用yaml格式的配置檔案,在resources資料夾下新建application.yaml檔案,原有的application.properties可以刪除

spring:
  datasource:
    #資料來源基本配置
    username: root
    password: 123
    url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    initialization-mode: always
    schema:
      - classpath:sql/student.sql   #資料庫建表語句
      
    #配置監控統計攔截的filters,去掉後監控介面sql無法統計,‘wall'用於防火牆
    filters: stat,wall,log4j
    #開啟PSCache,並且指定每個連線上PSCache的大小
    maxPoolPreparedStatementPerConnectionSize: 20
    #合併多個DruidDataSource的監控資料
    useGlobalDataSourceStat: true
    connectionProperties:
      #druid.stat.mergeSql合併執行的相同sql,避免因為引數不同而統計多條sql語句
      #druid.stat.slowSqlMillis用來配置SQL慢的標準,執行時間超過slowSqlMillis的就是慢
      druid.stat.mergeSql = true;druid.stat.slowSqlMillis = 500

  #使form表單可以傳送put請求
  mvc:
    hiddenmethod:
      filter:
        enabled: true

#mybatis配置
mybatis:
  #指定sql對映檔案路徑
  mapper-locations: classpath:mybatis/mapper/*.xml

配置檔案此處不進行詳細說明

3.Druid配置類

在src/main/java/com/example/demo3_dao目錄下新建config資料夾,並在config資料夾下新建DruidConfig類

 1 package com.example.demo3_dao.config;
 2 
 3 import com.alibaba.druid.pool.DruidDataSource;
 4 import com.alibaba.druid.support.http.StatViewServlet;
 5 import com.alibaba.druid.support.http.WebStatFilter;
 6 import org.springframework.boot.context.properties.ConfigurationProperties;
 7 import org.springframework.boot.web.servlet.FilterRegistrationBean;
 8 import org.springframework.boot.web.servlet.ServletRegistrationBean;
 9 import org.springframework.context.annotation.Bean;
10 import org.springframework.context.annotation.Configuration;
11 
12 import javax.sql.DataSource;
13 import java.util.Arrays;
14 import java.util.HashMap;
15 import java.util.Map;
16 
17 /**
18  * Druid配置類
19  */
20 @Configuration
21 public class DruidConfig {
22 
23     @Bean
24     @ConfigurationProperties(prefix = "spring.datasource")
25     public DataSource druid() {
26         return new DruidDataSource();
27     }
28 
29     /**
30      * 配置Druid監控
31      * @return
32      */
33     //配置一個管理後臺的Servlet
34     @Bean
35     public ServletRegistrationBean statViewServlet() {
36 
37         ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
38 
39         Map<String,String> initParams = new HashMap<>();
40         initParams.put("loginUsername","admin");
41         initParams.put("loginPassword","123456");
42         initParams.put("allow","");     //預設允許所有訪問
43         bean.setInitParameters(initParams);
44 
45         return bean;
46     }
47 
48     //配置一個web監控的filter
49     @Bean
50     public FilterRegistrationBean webStatFilter() {
51         FilterRegistrationBean bean = new FilterRegistrationBean();
52         bean.setFilter(new WebStatFilter());
53 
54         Map<String,String> initParams = new HashMap<>();
55         initParams.put("exclusions","*.js,*.css,/druid/*");
56         bean.setInitParameters(initParams);
57 
58         bean.setUrlPatterns(Arrays.asList("/*"));
59 
60         return bean;
61     }
62 }

4.log4j日誌

在resources目錄下新建log4j.properties檔案。

1 log4j.rootLogger=DEBUG, stdout
2 log4j.appender.stdout=org.apache.log4j.ConsoleAppender
3 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
4 log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

5.student.sql建表語句

在resources目錄下新建sql資料夾,將student.sql檔案匯入sql資料夾

 1 SET NAMES utf8;
 2 SET FOREIGN_KEY_CHECKS = 0;
 3 
 4 -- ----------------------------
 5 -- Table structure for student
 6 -- ----------------------------
 7 CREATE TABLE IF NOT EXISTS `student`  (
 8   `id` int NOT NULL COMMENT '學號',
 9   `name` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '姓名',
10   `score` int NOT NULL COMMENT '成績',
11   `birthplace` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '籍貫',
12   `birthday` date NOT NULL COMMENT '生日',
13   PRIMARY KEY (`id`) USING BTREE
14 ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
15 
16 SET FOREIGN_KEY_CHECKS = 1;

6.Student實體類

在src/main/java/com/example/demo3_dao目錄下新建domain資料夾,並在domain下新建Student

3、連線資料庫

此時可以在測試類中檢視資料來源

src/test/java/com/example/demo3_dao/Demo3DaoApplicationTests

 1 package com.example.demo3_dao;
 2 
 3 import org.junit.jupiter.api.Test;
 4 import org.springframework.beans.factory.annotation.Autowired;
 5 import org.springframework.boot.test.context.SpringBootTest;
 6 
 7 import javax.sql.DataSource;
 8 import java.sql.Connection;
 9 import java.sql.SQLException;
10 
11 @SpringBootTest
12 class Demo3DaoApplicationTests {
13 
14     @Autowired
15     DataSource dataSource;
16 
17     /**
18      * 測試檢視資料來源
19      * @throws SQLException
20      */
21     @Test
22     void contextLoads() throws SQLException {
23         System.out.println(dataSource.getClass());
24 
25         Connection connection = dataSource.getConnection();
26         System.out.println("資料來源:"+connection);
27         connection.close();
28     }
29 }

執行測試類的contextLoads()方法,可在控制檯看到druid資料來源

執行程式,控制檯可以發現資料庫建表語句

通過Navicat可以發現springboot下已經成功新建資料表

4、註解法進行CRUD

StduentDao

 1 package com.example.demo3_dao.dao;
 2 
 3 import com.example.demo3_dao.domain.Student;
 4 import org.apache.ibatis.annotations.*;
 5 import org.springframework.stereotype.Repository;
 6 
 7 import java.util.List;
 8 
 9 @Mapper
10 @Repository
11 public interface StudentDao {
12 
13     /**
14      * 新增學生資訊
15      * @param student
16      */
17     @Insert("INSERT INTO student(id,name,score,birthplace,birthday) VALUES (#{id},#{name},#{score},#{birthplace},#{birthday})")
18     public void AddStudent(Student student);
19 
20     /**
21      * 刪除學生資訊
22      * @param id
23      */
24     @Delete("DELETE FROM student WHERE id=#{id}")
25     public void DeleteStudentById(Integer id);
26 
27     /**
28      * 修改學生資訊
29      * @param student
30      */
31     @Update("UPDATE student SET name=#{name},score=#{score},birthplace=#{birthplace},birthday=#{birthday} WHERE id=#{id}")
32     public void UpdateStudent(Student student);
33 
34     /**
35      * 查詢某個學生資訊
36      * @param id
37      * @return
38      */
39     @Select("SELECT * FROM student WHERE id=#{id}")
40     public Student FindStudentById(Integer id);
41 
42     /**
43      * 查詢所有學生資訊
44      * @return
45      */
46     @Select("SELECT * FROM student")
47     public List<Student> FindAllStudent();
48 }

本專案未編寫controller層、service層等,就不具體實現其功能,可以通過使用測試類(Demo3DaoApplicationTests)檢視是否成功進行資料互動

1.測試新增學生功能

新增學生測試方法

 1 /**
 2   * 測試新增學生
 3   */
 4 @Test
 5 public void AddStudent() {
 6 
 7     //預設一個學生資訊
 8     Student student = new Student();
 9     student.setId(1);
10     student.setName("張三");
11     student.setScore(100);
12     student.setBirthplace("四川");
13     SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
14     Date date = new Date();
15     try {
16         date = simpleDateFormat.parse("2020-02-02");
17     } catch (ParseException e) {
18         e.printStackTrace();
19     }
20     student.setBirthday(date);
21 
22     //在控制檯輸出學生資訊
23     System.out.println("學生資訊:"+student);
24     //將學生資訊存入資料庫
25     studentDao.AddStudent(student);
26 }

執行測試方法

控制檯可以看到學生資訊

通過Navicat可以看到資料被寫入資料庫

2.測試查詢學生功能

通過Navicat在資料庫寫入幾條資料

 

查詢學生測試方法

 1 /**
 2   * 測試查詢學生
 3   * @return
 4   */
 5 @Test
 6 public void FindStudentById() {
 7 
 8     //從資料庫查詢學生
 9     Student student = studentDao.FindStudentById(2);
10     //在控制檯輸出學生資訊
11     System.out.println("查詢的學生資訊:"+student);
12 }

執行測試方法

可在控制檯看到查詢學生的資訊

 

3.測試修改學生功能

修改學生測試方法

 1 /**
 2   * 測試修改學生
 3   */
 4 @Test
 5 public void UpdateStudent() {
 6 
 7     //預設一個學生資訊
 8     Student student = new Student();
 9     //待修改學生的學號
10     student.setId(1);
11     //修改其他資訊
12     student.setName("張三");
13     student.setScore(60);
14     student.setBirthplace("新疆");
15     SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
16     Date date = new Date();
17     try {
18         date = simpleDateFormat.parse("2020-01-01");
19     } catch (ParseException e) {
20         e.printStackTrace();
21     }
22     student.setBirthday(date);
23 
24     //在控制檯輸出學生資訊
25     System.out.println("修改後的學生資訊:"+student);
26     //修改學生資訊
27     studentDao.UpdateStudent(student);
28 }

執行測試方法

可在控制檯看到修改後的學生的資訊

 

通過Navicat可以看到資料庫中的內容已經被修改

 

4.測試刪除學生功能

刪除學生測試方法

1 /**
2   * 測試刪除學生   */
3 @Test
4 public void DeleteStudentById() {
5     //刪除學號為2的學生
6     studentDao.DeleteStudentById(2);
7 }

執行測試方法

通過Navicat可以看到資料庫中的內容已經被修改

 

5、配置檔案法進行CRUD

1.新建並編寫StduentMapper.xml檔案

在resources目錄下新建mybatis資料夾,在mybatis資料夾下新建mapper資料夾,在mapper資料夾下新建StudentMapper.xml

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE mapper
 3         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 <mapper namespace="com.example.demo3_dao.dao.StudentDao">
 6 
 7     <!-- 新增學生 -->
 8     <insert id="AddStudent">
 9         INSERT INTO student(id,name,score,birthplace,birthday) VALUES (#{id},#{name},#{score},#{birthplace},#{birthday})
10     </insert>
11 
12     <!-- 刪除學生 -->
13     <delete id="DeleteStudentById">
14         DELETE FROM student WHERE id=#{id}
15     </delete>
16 
17     <!-- 更新學生 -->
18     <update id="UpdateStudent">
19         UPDATE student SET name=#{name},score=#{score},birthplace=#{birthplace},birthday=#{birthday} WHERE id=#{id}
20     </update>
21 
22     <!-- 查詢某個學生 -->
23     <select id="FindStudentById" resultType="com.example.demo.domain.Student">
24         SELECT * FROM student WHERE id=#{id}
25     </select>
26 
27     <!-- 查詢所有學生 -->
28     <select id="FindAllStudent" resultType="com.example.demo.domain.Student">
29         SELECT * FROM student
30     </select>
31 
32 </mapper>

2.在application.yaml檔案中配置mybatis資訊

1 #mybatis配置
2 mybatis:
3   #指定sql對映檔案路徑
4   mapper-locations: classpath:mybatis/mapper/*.xml

3.StudentDao.interface方法名與StduentMapper.xml中的id名要一一對應

如StduentDao.interface中新增學生

1 public void AddStudent(Student student);

StudentMapper.xml中新增學生

1 <!-- 新增學生 -->
2 <insert id="AddStudent">
3     INSERT INTO student(id,name,score,birthplace,birthday) VALUES (#{id},#{name},#{score},#{birthplace},#{birthday})
4 </insert>

此時StudentDao.interfeace內容為

 1 package com.example.demo3_dao.dao;
 2 
 3 import com.example.demo3_dao.domain.Student;
 4 import org.apache.ibatis.annotations.*;
 5 import org.springframework.stereotype.Repository;
 6 
 7 import java.util.List;
 8 
 9 @Mapper
10 @Repository
11 public interface StudentDao {
12 
13     /**
14      * 新增學生資訊
15      * @param student
16      */
17     public void AddStudent(Student student);
18 
19     /**
20      * 刪除學生資訊
21      * @param id
22      */
23     public void DeleteStudentById(Integer id);
24 
25     /**
26      * 修改學生資訊
27      * @param student
28      */
29     public void UpdateStudent(Student student);
30 
31     /**
32      * 查詢某個學生資訊
33      * @param id
34      * @return
35      */
36     public Student FindStudentById(Integer id);
37 
38     /**
39      * 查詢所有學生資訊
40      * @return
41      */
42     public List<Student> FindAllStudent();
43 }

本專案未編寫controller層、service層等,就不具體實現其功能

可以從測試類中驗證CRUD操作,與註解法類似,此處不再演示

五、Demo專案(整合了前面全部功能的一個演示專案)

1、目錄結構

見 一、SpringBoot簡介->4、SpringBoot專案->1.SpringBoot專案常見目錄結構

2、層級簡介

src/main/java/com/example/demo目錄下

config是配置資料夾

controller是控制層資料夾

dao是資料訪問層資料夾

domain是資料表物件層資料夾

service是業務層資料夾

src/main/resources資料夾下

mybatis是mybatis相關資料夾

sql是Mysql語句資料夾

static是靜態資原始檔夾

templates是模板資料夾

src/test目錄下與測試相關

pom.xml與配置依賴相關

3、CRUD演示

1.新增學生

初始頁面

進入新增頁面並填寫資訊

點選新增按鈕回到學生列表頁面

2.查詢學生

此專案僅做了查詢所有學生資訊,點選“查詢所有學生資訊”按鈕即可在學生列表頁面看到所有學生資訊

3.修改學生

點選需要修改的學生資訊右側的修改按鈕,此處選擇修改2號學生,進入修改頁面

點選修改按鈕返回至學生列表頁面

4.刪除學生

點選需要刪除的學生資訊右側的刪除按鈕,此處選擇刪除4號學生,重新整理學生列表頁面

 

文章理論部分主要來自B站 尚矽谷SpringBoot頂尖教程(springboot之idea版spring boot) 及數篇其他部落格 在此不一一說明出處

 

相關文章