一、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风格

  普通CRUD RestfulCRUD
查询 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(添加学生,POST请求)?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. 点击添加学生按钮来到学生信息页面,输入数据
    SpringBoot简明教程-小白菜博客

  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. 来到初始页面
    SpringBoot简明教程-小白菜博客

  2. 在输入框输入需要查询的学生学号

  3. 点击查找按钮后来到学生信息页面,如果连接了数据库执行了查找操作后会在本页面显示该学生的信息

  4. 控制台输出所查找的学生学号
    SpringBoot简明教程-小白菜博客
    因为添加学生和查找学生用的同一个学生信息页面,即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
    SpringBoot简明教程-小白菜博客

  2.  点击提交按钮,即可得到经过Service层计算得到的返回值
    SpringBoot简明教程-小白菜博客

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 }

注意:

@Repository需要在Spring中配置扫描地址,然后生成Dao层的Bean才能被注入到Service层中

@SpringBootApplication
@MapperScan("com.example.demo3_dao.dao")
public class Demo3DaoApplication {

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

}

@Mapper不需要配置扫描地址,通过xml里面的namespace里面的接口地址,生成了Bean后注入到Service层中

本项目未编写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) 及数篇其他博客 在此不一一说明出处

GitHub地址:https://github.com/HuskySir/JAVA/tree/master/SpringBoot_Demo