0%

Springboot基础篇

  • Springboot基础篇
    • 快速上手 Springboot
    • Springboot入门程序分析
    • SpringBoot基础配置
    • 整合第三方技术
    • 基于Springboot的SSMP整合

一、基础篇

  • 基础篇的目标是上手,能够使用 springboot 搭建基于 springboot 的 web 项目进行开发。

1.1 快速上手 Springboot

  • SpringBoot 技术由 Pivotal 团队研发制作,功能的话简单概括就是加速 Spring 程序的开发,这个加速要从以下两个方面来说:
    • Spring 程序初始搭建过程
    • Spring 程序的开发过程
  • Spring 程序缺点:
    • 依赖设置繁琐:需要在 pom.xml 文件中设置相关依赖,相关依赖项很多。
    • 配置繁琐:对每个 SSM 项目,都需要配置 spring.xmlspringmvc.xmlmybatis-config.xml 文件。
  • Springboot 程序优点:
    • 起步依赖:简化依赖配置。
    • 自动配置:简化常用工程相关配置。
    • 辅助功能:内置服务器等…

1.1.1 Springboot入门程序

  • 下面使用 SpringBoot 技术快速构建一个 SpringMVC 的程序,通过这个过程体会简化二字的含义:

    1. 创建新模块 springboot_01_01_quickstart,选择 Spring Initializr,并配置模块相关基础信息:

      • 注意:在 idea 中使用 springboot 时,是需要联网的,如果不能正常联网,就会显示一直在加载中。
    2. 选择当前模块需要使用的技术集:

    3. 开发控制器类。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      package com.f.springboot.controller;

      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;

      /**
      * @author fzy
      * @date 2024/2/21 14:30
      */
      // Rest模式
      @RestController
      @RequestMapping("/books")
      public class BookController {
      @GetMapping
      public String get() {
      System.out.println("Springboot is running...");
      return "springboot";
      }
      }
      • 入门案例制作的 SpringMVC 的控制器是基于 Restful 风格开发的,当然此处使用原始格式制作 SpringMVC 的程序也是没有问题的,上例中的 @RestController@GetMapping 注解是基于 Restful 开发的典型注解
    4. 运行自动生成的 Application 类:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      package com.f.springboot;

      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;

      @SpringBootApplication
      public class Application {
      public static void main(String[] args) {
      SpringApplication.run(Application.class, args);
      }
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
          .   ____          _            __ _ _
      /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
      ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
      \\/ ___)| |_)| | | | | || (_| | ) ) ) )
      ' |____| .__|_| |_|_| |_\__, | / / / /
      =========|_|==============|___/=/_/_/_/
      :: Spring Boot :: (v3.2.2)

      2024-02-21T14:42:52.528+08:00 INFO 11528 --- [ main] com.f.springboot.Application : Starting Application using Java 17.0.8 with PID 11528 (C:\Users\Running Noob\Code Project\Springboot-learning-code\springboot_01_01_quickstart\target\classes started by Running Noob in C:\Users\Running Noob\Code Project\Springboot-learning-code)
      2024-02-21T14:42:52.532+08:00 INFO 11528 --- [ main] com.f.springboot.Application : No active profile set, falling back to 1 default profile: "default"
      2024-02-21T14:42:53.227+08:00 INFO 11528 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
      2024-02-21T14:42:53.230+08:00 INFO 11528 --- [ main] o.a.catalina.core.AprLifecycleListener : Loaded Apache Tomcat Native library [2.0.6] using APR version [1.7.4].
      2024-02-21T14:42:53.246+08:00 INFO 11528 --- [ main] o.a.catalina.core.AprLifecycleListener : OpenSSL successfully initialized [OpenSSL 3.0.11 19 Sep 2023]
      2024-02-21T14:42:53.254+08:00 INFO 11528 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
      2024-02-21T14:42:53.254+08:00 INFO 11528 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.18]
      2024-02-21T14:42:53.291+08:00 INFO 11528 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
      2024-02-21T14:42:53.291+08:00 INFO 11528 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 713 ms
      2024-02-21T14:42:53.576+08:00 INFO 11528 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path ''
      2024-02-21T14:42:53.581+08:00 INFO 11528 --- [ main] com.f.springboot.Application : Started Application in 1.371 seconds (process running for 1.928)
      2024-02-21T14:43:57.706+08:00 INFO 11528 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
      2024-02-21T14:43:57.706+08:00 INFO 11528 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
      2024-02-21T14:43:57.707+08:00 INFO 11528 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
      • 从上面控制台的信息可以看到,jdk 版本是 17.0.8,tomcat 端口是 8080,版本是 10.1.18,应用程序根路径为 ‘’。
    5. 在浏览器上通过 localhost:8080/books 进行测试。

  • 下面是入门程序的 pom.xml 文件,是自动生成的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    <?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>3.2.2</version>
    <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.f</groupId>
    <artifactId>springboot_01_01_quickstart</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_01_01_quickstart</name>
    <description>springboot_01_01_quickstart</description>
    <properties>
    <java.version>17</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>

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

    </project>
    • 注意:最简单的 Springboot 项目至少要包含两个基础文件:
      • 上面的 pom.xml 文件。
      • 自动生成的 Application 类。
  • 通过上面的入门程序,我们不难发现,SpringBoot 程序简直太好写了,几乎什么都没写,功能就有了,这也是 SpringBoot 技术为什么现在这么火的原因,和 Spirng 程序相比,SpringBoot 程序在开发的过程中各个层面均具有优势。

    类配置文件SpringSpringBoot
    pom文件中的坐标手工添加勾选添加
    web3.0配置类手工制作
    Spring/SpringMVC配置类手工制作
    控制器手工制作手工制作

    一句话总结一下就是能少写就少写能不写就不写,这就是 SpringBoot 技术给我们带来的好处。

1.1.2 小结

  1. 开发 SpringBoot 程序可以根据向导进行联网快速制作。
  2. SpringBoot 程序需要基于 JDK8 以上版本进行制作。
  3. SpringBoot 程序中需要使用何种功能通过勾选选择技术,也可以手工添加对应的要使用的技术。
  4. 运行 SpringBoot 程序通过运行自动生成的 Application 程序进行。

1.1.3 ★修改联网URL

  • Spring Initializr 的默认 URL 为 start.spring.io,是国外的网址,速度较慢,我们可以将其更改为阿里云的地址 Cloud Native App Initializer (aliyun.com) ,加载就会更快。

    • 阿里为了便于自己开发使用,因此在依赖坐标中添加了一些阿里相关的技术,也是为了推广自己的技术吧,所以在依赖选择列表中,你有了更多的选择。

1.2 ★★★Springboot入门程序分析

1.2.1 parent

  • 对于多个项目,例如 project-aproject-b,它们的依赖有可能是重合的,在这种情况下,为了提高依赖的复用性,可以将重合的依赖抽取出来,形成 parent,然后 project-aproject-b 只要使用 <parent><parent/> 标签引用 parent,就不需要在引入依赖的时候指定依赖版本号了。

    • parent 中,通过 <properties><properties/> 标签将依赖版本统一管理

    • 注意:使用 <parent><parent/> 标签只是表示在项目中引入依赖时不需要指定依赖版本号了(因为在 parent 中统一指定了),但不代表在项目中不需要引入依赖。

      • 例如,在 parent 中指定了 aspectj 依赖的版本号:

        1
        2
        3
        4
        5
        6
        7
        8
        9
        ...
        <aspectj.version>1.9.21</aspectj.version>
        ...
        <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>${aspectj.version}</version>
        </dependency>
        ...

        那么,在项目中引入 aspectj 依赖时,就不需要指定版本号:

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        ...
        <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.2</version>
        <relativePath/> <!-- lookup parent from repository -->
        </parent>
        ...
        <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <!--没有指定version-->
        </dependency>
        ...

        因为在 parent 中已经指定了。

        但这并不代表你的项目要引入 aspectj 依赖的时候,只需要 <parent><parent/> 中的内容,而不需要 <dependency><dependency/> 中的内容

      总之:**parent 是用来统一依赖版本号,避免出现版本冲突的**。

  • 开发 Springboot 项目需要继承 spring-boot-starter-parent

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?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>3.2.2</version>
    <relativePath/> <!-- lookup parent from repository -->
    </parent>
    ......

    spring-boot-starter-parent 中定义了若干个依赖管理(坐标版本号),继承 parent 模块可以避免多个依赖使用相同技术时出现依赖版本冲突。

1.2.2 starter

  • SpringBoot 中常见项目名称,定义了当前项目使用的所有依赖坐标,以达到减少依赖配置的目的。

    例如,在 spring-boot-starter-web 中,引入了一系列的依赖:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    <?xml version="1.0" encoding="UTF-8"?>
    <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>3.0.2</version>
    ......
    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>3.0.2</version>
    <scope>compile</scope>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-json</artifactId>
    <version>3.0.2</version>
    <scope>compile</scope>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <version>3.0.2</version>
    <scope>compile</scope>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>6.0.4</version>
    <scope>compile</scope>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>6.0.4</version>
    <scope>compile</scope>
    </dependency>
    </dependencies>
    </project>

    这些依赖是我们开发 JavaWeb 项目所需要的,我们现在只要引入 spring-boot-starter-web 依赖,就能使用这些依赖了,就是 maven 中依赖传递的概念。

  • Springboot 中有一系列含有 starter 名称的依赖,每个 starter 根据功能不同,通常包含多个依赖坐标,用于简化配置

1.2.3 parent和starter的区别

  • parent 是用来统一依赖版本号,避免出现版本冲突的,它只是指定了依赖版本号,到底要不要使用依赖,是要在项目的 pom.xml 中配置的。

  • starter 是预先引入了一些依赖,只要项目的 pom.xml 中引入了该 starter 依赖,就等于引入了该 starter 中预先引入的依赖,就等于是在项目中一定会有这些依赖,是依赖传递的概念。

  • 在实际开发中:

    • 使用任意坐标时,仅书写 GAV 中的 G 和 A,V 由 SpringBoot 提供(即前面所说的 parent),除非 SpringBoot 未提供对应版本 V。
    • 如果发生坐标错误,再指定 Version (要小心版本冲突)。

1.2.4 引导类

  • 引导类是 springboot 自动生成的:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    package com.f.springboot;

    import com.f.springboot.controller.BookController;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.ConfigurableApplicationContext;

    @SpringBootApplication
    public class Springboot0102QuickstartApplication {
    public static void main(String[] args) {
    // SpringApplication.run的返回值就是ApplicationContext,就是一个spring容器
    // 所以下面这行代码就是启动了一个spring容器
    ConfigurableApplicationContext context = SpringApplication.run(Springboot0102QuickstartApplication.class, args);
    BookController bookController = context.getBean(BookController.class);
    System.out.println(bookController);
    }
    }

    引导类是整个 springboot 程序的入口,运行 main 方法就可以启动项目。

1.2.5 内嵌tomcat

  • springboot 是如何内嵌 tomcat 的?

    • spring-boot-starter-web 依赖中,有一个 spring-boot-starter-tomcat 依赖,该依赖含有 tomcat 核心依赖 tomcat-embed-core,因此,当启动项目时,相当于在 spring 容器中托管了 tomcat 服务器对象,然后该 tomcat 服务器对象提供 web 服务。

      内嵌 Tomcat 的工作原理是将 Tomcat 服务器作为对象运行,并将该对象交给 Spring 容器管理

      • 1.2.2 starter 小节的配置文件中可以看到,spring-boot-starter-web 依赖中有一个 spring-boot-starter-tomcat 依赖。

      • 然后,在 spring-boot-starter-tomcat 依赖中,含有 tomcat-embed-core 依赖。

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        <?xml version="1.0" encoding="UTF-8"?>
        <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <modelVersion>4.0.0</modelVersion>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <version>3.0.2</version>
        ......
        <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-core</artifactId>
        <version>10.1.5</version>
        <scope>compile</scope>
        <exclusions>
        <exclusion>
        <artifactId>tomcat-annotations-api</artifactId>
        <groupId>org.apache.tomcat</groupId>
        </exclusion>
        </exclusions>
        </dependency>
        ......

1.3 ★SpringBoot基础配置

1.3.1 属性配置

  • springboot 项目的默认配置文件就是 resources 目录下的 application.properties,是自动生成的。

    • 通过配置文件 application.properties 就可以修改默认的配置,先找个简单的配置下手:

      当前访问 tomcat 的默认端口是 8080,将其修改为 80 端口:

      1
      2
      # 应用服务 WEB 访问端口
      server.port=80
      • 运行发现没问题。

    事实上,springboot 所有的配置都可以写在这一个文件中,但那样会使得 application.properties 文件变得臃肿,而且也不利于维护,所以我们会使用多个配置文件来对 springboot 项目进行配置。

  • springboot 项目的一些其他配置:

    1
    2
    # 日志级别
    logging.level.root=debug

1.3.2 配置文件分类

  • 为了避免将 springboot 项目所有的配置都写在同一个文件中,SpringBoot 除了支持 properties 格式的配置文件,还支持另外两种格式的配置文件。分别如下:
    • yml 格式(主流格式)
    • yaml 格式
1.3.2.1 properties格式(传统格式)
1
server.port=80
1.3.2.2 yml格式(主流格式)
1
2
server:
port: 81
1.3.2.3 yaml格式
1
2
server:
port: 81
  • 仔细看会发现 yml 格式和 yaml 格式除了文件名后缀不一样,格式是完全一样的,其实 ymlyaml 文件格式就是一模一样的,只是文件后缀不同,所以可以合并成一种格式来看。

    以后基本上都是用 yml 格式的,本课程后面的所有知识都是基于 yml 格式来制作的,以后在企业开发过程中用这个格式的机会也最多,一定要重点掌握。

  • 另外:配置文件的优先级为 properties(最高)> yml > yaml(最低)

    不同配置文件中的相同配置,按照加载优先级相互覆盖,不同配置文件中不同配置全部保留。

1.3.3 ★yaml文件

  • yaml 是一个可读性高,用来表达数据序列化的格式。其具有容易阅读、容易与脚本语言交互、以数据为核心,重数据轻格式的特点。
    • yaml 常见的文件扩展名有两种:
      • .yml (主流)
      • .yaml
1.3.3.1 yaml语法规则
  • yaml 语法规则:

    1. 大小写敏感
    2. 属性层级关系使用多行描述,属性结尾使用冒号结束
    3. 使用缩进表示层级关系,同层级左侧对齐,只允许使用空格(不允许使用 Tab 键)
    4. 属性值前面添加空格(属性名与属性值之间使用 “冒号 + 空格” 作为分隔)
    5. #号表示注释

    核心的一条规则要记住,数据前面要加空格,与冒号隔开

    1
    2
    3
    4
    5
    6
    7
    boolean: TRUE                          # TRUE,true,True,FALSE,false,False均可
    float: 3.14 # 6.8523015e+5 #支持科学计数法
    int: 123 # 0b1010_0111_0100_1010_1110 #支持二进制、八进制、十六进制
    string: HelloWorld # 字符串可以直接书写
    string2: "Hello World" # 可以使用双引号包裹特殊字符,在双引号中的转义字符是会被解析的
    date: 2018-02-17 # 日期必须使用yyyy-MM-dd格式
    datetime: 2018-02-17T15:02:31+08:00 # 时间和日期之间使用T连接,最后使用+代表时区
    • 此外,yaml 格式中也可以表示数组,在属性名书写位置的下方使用减号作为数据开始符号,每行书写一个数据,减号与数据间空格分隔:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      subject:
      - Java
      - 前端
      - 大数据
      enterprise:
      name: itcast
      age: 16
      subject:
      - Java
      - 前端
      - 大数据
      likes1: [sing,dance] #数组书写缩略格式
      likes2:
      - sing
      - dance
      users1: #对象数组格式一
      - name: Tom
      age: 4
      - name: Jerry
      age: 5
      users2: #对象数组格式二
      -
      name: Tom
      age: 4
      -
      name: Jerry
      age: 5
      users3: [{ name:Tom , age:4 },{ name:Jerry , age:5 }] #对象数组缩略格式
1.3.3.2 读取yaml单一属性数据
  • yaml 中保存的单个数据,可以使用 Spring 中的注解直接读取,使用 @Value 可以读取单个数据。

    • 属性名引用方式:@Value("${一级属性名.二级属性名......}")
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    package com.f.springboot.controller;

    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;

    /**
    * @author fzy
    * @date 2024/2/21 22:11
    */
    @RestController
    @RequestMapping("/books")
    public class BookController {
    // 读取单一属性
    // string: HelloWorld
    @Value("${string}")
    private String str;

    /**
    * 读取属性的属性
    * enterprise:
    * name: itcast
    * age: 16
    * subject:
    * - Java
    * - 前端
    * - 大数据
    */
    @Value("${enterprise.name}")
    private String enterpriseName;

    /**
    * 读取数组数据
    * likes2:
    * - sing
    * - dance
    */
    @Value("${likes2[0]}")
    private String like;

    @GetMapping
    public String get() {
    return "springboot...";
    }

    // 读取yaml数据中的单一数据
    @GetMapping("/yaml/single")
    public String getYamlSingle() {
    return str + "<br/>" + enterpriseName + "<br/>" + like;
    }
    }
    • 注意:使用 @Value 注解时,要将该注解写在某一个指定的 Spring 管理的 bean 的属性名上方。
  • yaml 文件中还可以引用变量,例如:

    1
    2
    3
    4
    5
    center:
    dataDir: /usr/local/fire/data
    tmpDir: /usr/local/fire/tmp
    logDir: /usr/local/fire/log
    msgDir: /usr/local/fire/msgDir

    中有重合部分:/usr/local/fire

    • 可以修改为下面的表示形式:

      1
      2
      3
      4
      5
      6
      baseDir: /usr/local/fire
      center:
      dataDir: ${baseDir}/data # 使用${变量名}的形式引用变量
      tmpDir: ${baseDir}/tmp
      logDir: ${baseDir}/log
      msgDir: ${baseDir}/msgDir
1.3.3.3 读取yaml全部属性数据
  • 读取单一数据可以解决读取数据的问题,但是如果在 yaml 文件中的数据量过大,那在 java 文件中要定义的变量将会很多。

    为此,SpringBoot 提供了一个对象,能够把所有的数据都封装到这一个对象中,这个对象叫做 Environment,使用自动装配注解 @Autowired 可以将 yaml 文件中所有的数据封装到这个对象中:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    package com.f.springboot.controller;

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.core.env.Environment;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;

    /**
    * @author fzy
    * @date 2024/2/21 22:11
    */
    @RestController
    @RequestMapping("/books")
    public class BookController {
    ......

    // 使用自动装配将所有的数据封装到一个Environment对象中
    @Autowired
    private Environment env;

    @GetMapping
    public String get() {
    return "springboot...";
    }

    // 读取yaml数据中的单一数据
    @GetMapping("/yaml/single")
    public String getYamlSingle() {
    return str + "<br/>" + enterpriseName + "<br/>" + like + "<br/>" + dir;
    }

    // 读取yaml数据中的所有数据
    @GetMapping("/yaml/all")
    public String getYamlAll() {
    // 使用getProperty方法获取数据
    return env.getProperty("enterprise.name");
    }
    }
    • 数据封装到了 Environment 对象中,获取属性时,通过 Environment 的接口方法进行,具体方法为 getProperties(String),参数填写属性名即可。
1.3.3.4 读取yaml对象数据(主流)
  • 读取单一属性数据过于繁琐,需要定义对应数量的变量;读取全部数据又过于封装,要将所有数据封装在 Environment 对象中,每次取数据都需要调用 getProperties()方法。

    由于 Java 是一个面向对象的语言,很多情况下,我们会将一组数据封装成一个对象。因此,SpringBoot 也提供了可以将一组 yaml 数据封装在一个 Java 对象中的操作。例如,如果我们要将下面的配置数据封装到一个 Java 对象中:

    1
    2
    3
    4
    5
    datasource:
    driver: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springboot
    username: root
    password: root
    • 首先创建一个对象类,将对象类实例化,并将该对象纳入 Spring 容器管理,也就是定义一个 bean。

    • 然后使用注解 @ConfigurationProperties 指定该对象加载 yaml 中哪一组配置信息。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      package com.f.springboot.pojo;

      /**
      * @author fzy
      * @date 2024/2/22 15:44
      */

      import org.springframework.boot.context.properties.ConfigurationProperties;
      import org.springframework.stereotype.Component;

      /**
      * 1. 定义数据模型封装yaml文件中对应的数据
      * 2. 将其定义为spring容器管理的bean
      * 3. 指定要加载yaml文件中的什么数据 @ConfigurationProperties
      */
      @Component
      @ConfigurationProperties(prefix = "datasource")
      public class DataSource {
      private String driver;
      private String url;
      private String username;
      private String password;

      public DataSource() {
      }

      public DataSource(String driver, String url, String username, String password) {
      this.driver = driver;
      this.url = url;
      this.username = username;
      this.password = password;
      }

      @Override
      public String toString() {
      return "DataSource{" +
      "driver='" + driver + '\'' +
      ", url='" + url + '\'' +
      ", username='" + username + '\'' +
      ", password='" + password + '\'' +
      '}';
      }

      public String getDriver() {
      return driver;
      }

      public void setDriver(String driver) {
      this.driver = driver;
      }

      public String getUrl() {
      return url;
      }

      public void setUrl(String url) {
      this.url = url;
      }

      public String getUsername() {
      return username;
      }

      public void setUsername(String username) {
      this.username = username;
      }

      public String getPassword() {
      return password;
      }

      public void setPassword(String password) {
      this.password = password;
      }
      }
      • @ConfigurationProperties 必须指明数据前缀是什么,这样该前缀下的所有属性就封装到这个对象中。

        注意:数据属性名要与对象的变量名一一对应,否则无法封装

    • 最后使用 @Autowired 自动装配对象:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      package com.f.springboot.controller;

      import com.f.springboot.pojo.DataSource;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;

      /**
      * @author fzy
      * @date 2024/2/22 15:53
      */
      @RestController
      @RequestMapping("/yaml")
      public class YamlController {
      // 4. 使用@Autowired自动装配
      @Autowired
      private DataSource dataSource;

      @GetMapping("/datasource")
      public DataSource getDataSource() {
      return dataSource;
      }
      }

1.4 整合第三方技术

  • springboot 整合第三方技术的流程都大同小异,主要包括以下几步:
    1. 在 Spring Initializr 中选择要整合的第三方技术的技术集。
      • 如果没有可勾选的第三方技术集,可以在项目初始化后,在 pom.xml 文件中手工引入 dependency
      • 主要是导入对应的 “starter”。
    2. 对技术集进行相应的配置,设置配置文件,例如 application.yml
    3. 进行功能开发和测试。

1.4.1 整合Junit

  • springboot 整合 junit 的核心注解:@SpringBootTest

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package com.f.springboot;

    import com.f.springboot.dao.BookDao;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;

    @SpringBootTest
    class Springboot03JunitApplicationTests {
    // 1.注入要测试的对象
    @Autowired
    private BookDao bookDao;

    @Test
    void contextLoads() {
    // 2.执行要测试的对象的对应方法
    bookDao.save();
    }
    }
  • @SpringBootTest 有一个 classes 属性,用于设置 springboot 启动类。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    package com.f.springboot;

    import com.f.springboot.dao.BookDao;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;

    // 通过classes属性指定要测试的springboot启动类
    @SpringBootTest(classes = Springboot03JunitApplication.class)
    class Springboot03JunitApplicationTests {
    ......
    }
    • 如果测试类在 SpringBoot 启动类的包或子包中,则可以省略启动类的设置,也就是省略 classes 的设定。

1.4.2 整合Mybatis

  • springboot 整合 Mybatis 的步骤:

    1. 创建新模块 springboot_04_mybatis,选择 Spring 初始化,并配置模块相关基础信息:

    2. 选择当前模块需要使用的技术集,既然是整合 Mybatis,那就选择 Mybatis 相关的技术集(MyBatis、MySQL):

      • 观察项目的 pom.xml 文件,可以发现有 mybatis 和 MySQL 的相关依赖:

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        <?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>
        <groupId>com.f</groupId>
        <artifactId>springboot_04_mybatis</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>springboot_04_mybatis</name>
        <description>springboot_04_mybatis</description>
        <properties>
        <java.version>17</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>3.0.2</spring-boot.version>
        </properties>
        <dependencies>
        <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>3.0.0</version>
        </dependency>

        <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
        </dependency>
        <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        </dependency>
        </dependencies>
        ......
        </project>
    3. application.yml 文件中设置数据源参数:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      mybatis:
      #指定Mybatis的Mapper文件
      mapper-locations: classpath:com/f/springboot/mapper/*.xml
      #指定Mybatis的实体目录
      type-aliases-package: com.f.springboot.pojo

      # 配置数据库信息
      spring:
      datasource:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/springboot
      username: root
      password: root
    4. 在 springboot 数据库中创建 t_book 表。

    5. 创建实体 Bean:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      package com.f.springboot.pojo;

      /**
      * @author fzy
      * @date 2024/2/22 21:41
      */
      public class Book {
      private Integer id;
      private String type;
      private String name;
      private String description;

      public Book() {
      }

      public Book(Integer id, String type, String name, String description) {
      this.id = id;
      this.type = type;
      this.name = name;
      this.description = description;
      }

      @Override
      public String toString() {
      return "Book{" +
      "id=" + id +
      ", type='" + type + '\'' +
      ", name='" + name + '\'' +
      ", description='" + 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;
      }
      }
    6. 定义数据访问层接口与映射配置:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      package com.f.springboot.mapper;

      import com.f.springboot.pojo.Book;
      import org.springframework.stereotype.Repository;

      /**
      * @author fzy
      * @date 2024/2/22 21:43
      */
      @Repository
      public interface BookMapper {
      // 根据id查询图书信息
      Book getById(Integer id);
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE mapper
      PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
      "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
      <mapper namespace="com.f.springboot.mapper.BookMapper">
      <select id="getById" resultType="Book">
      SELECT id, type, name, description
      FROM t_book
      <where>
      id = #{id}
      </where>
      </select>
      </mapper>
    7. 在引导类中添加 @MapperScan 注解,指定要变成实现类的接口所在的包,然后包下面的所有接口在编译之后都会生成相应的实现类:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      package com.f.springboot;

      import org.mybatis.spring.annotation.MapperScan;
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;

      @SpringBootApplication
      @MapperScan("com.f.springboot.mapper")
      public class Springboot04MybatisApplication {
      public static void main(String[] args) {
      SpringApplication.run(Springboot04MybatisApplication.class, args);
      }
      }
    8. 在测试类中注入 mapper 接口,测试功能:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      package com.f.springboot;

      import com.f.springboot.mapper.BookMapper;
      import com.f.springboot.pojo.Book;
      import org.junit.jupiter.api.Test;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.boot.test.context.SpringBootTest;

      @SpringBootTest
      class Springboot04MybatisApplicationTests {
      @Autowired
      private BookMapper bookMapper;

      @Test
      void contextLoads() {
      Book book = bookMapper.getById(1);
      System.out.println(book);
      }
      }
★@Mapper、@MapperScan、@Repository
  • 在上面整合 Mybatis 的例子中,需要用到 @MapperScan@Repository 注解,才能动态生成 Mapper 接口的实现类,但其实只用一个 @Mapper 注解也能达到类似的效果,其中的区别如下:

    • @Repository 是标注在 mapper 包的接口上,作用是将接口的一个实现类交给 Spring 管理,但是使用这个注解的前提是必须在引导类上添加 @MapperScan("Mapper接口层路径") 的注解

      这个 @Repository 完全可以省略不写,也可以实现自动注入,但是在 IDEA 中会存在一个红色的波浪线。所以最好还是在接口上加上这个注解,例如上面例子中的:

      1
      2
      3
      4
      5
      @Repository
      public interface BookMapper {
      // 根据id查询图书信息
      Book getById(Integer id);
      }
      1
      2
      3
      4
      5
      6
      7
      @SpringBootApplication
      @MapperScan("com.f.springboot.mapper")
      public class Springboot04MybatisApplication {
      public static void main(String[] args) {
      SpringApplication.run(Springboot04MybatisApplication.class, args);
      }
      }
    • @Mapper 这个注解一般也是使用在 mapper 层的接口上,相当于一个 mapper.xml 文件,它的作用就是将接口生成一个动态代理类。加入 @Mapper 注解的目的就是为了不再写 mapper.xml 映射文件。这个注解就是用来代替 mapper.xml 文件的(Mybatis 的全注解式开发)。

      使用 @mapper 后,不需要在 spring 配置中设置扫描地址,通过 mapper.xml 里面的 namespace 属性对应相关的 mapper 类,spring 就可以动态的生成动态代理类。

      1
      2
      3
      4
      5
      @Mapper
      public interface BookMapper {
      // 根据id查询图书信息
      Book getById(Integer id);
      }
      • 当我们的一个项目中存在多个 mapper 层接口的时候,我们需要对每个接口类都写上 @Mapper 注解,非常的麻烦,此时可以使用 @MapperScan 注解来解决这个问题。让这个接口进行一次性的注入,不需要再写 @Mapper 注解。
  • 总之,@Mapper 注解相当于是 @Reponsitory 注解和 @MapperScan 注解的和,会自动的进行配置加载。

    @MapperScan 注解多个包,@Mapper 只能把当前接口类进行动态代理。

    • 在实际开发中,如何使用 @Mapper@MapperSacn@Repository 注解:

      • 在 SpringBoot 的引导类上给定 @MapperSacn 注解,此时 mapper 层的接口可以省略 @Mapper 注解,@Repository 注解可写可不写,最好还是写上。
      • 当使用 @Mapper 注解的时候,可以省略 @MapperSacn 以及 @Repository

      建议以后在使用的时候,在启动类上给定 @MapperScan("mapper层接口所在的包路径")。在 mapper层接口上不写 @Mapper 注解,写上 @Repository 即可。

1.4.3 整合Druid

  • springboot 整合 Druid 的步骤:

    1. 创建新模块 springboot_05_druid,选择 Spring 初始化,并配置模块相关基础信息:

    2. 选择当前模块需要使用的技术集,既然是整合 Druid,那就选择 Druid 相关的技术集(MyBatis、MySQL、Druid),但是发现没有 Druid 相关的技术集可以勾选,那就在项目初始化后,在 pom.xml 文件中手动引入 Druid 相关依赖 druid-spring-boot-starter

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      <?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>
      <groupId>com.f</groupId>
      <artifactId>springboot_05_druid</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <name>springboot_05_druid</name>
      <description>springboot_05_druid</description>
      <properties>
      <java.version>17</java.version>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
      <spring-boot.version>3.0.2</spring-boot.version>
      </properties>
      <dependencies>
      <dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>3.0.0</version>
      </dependency>

      <!--druid-spring-boot-starter依赖-->
      <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid-spring-boot-starter</artifactId>
      <version>1.2.19</version>
      </dependency>

      <dependency>
      <groupId>com.mysql</groupId>
      <artifactId>mysql-connector-j</artifactId>
      <scope>runtime</scope>
      </dependency>
      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
      </dependency>
      </dependencies>
      ......
      </project>
    3. application.yml 文件中进行相应配置:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      mybatis:
      #指定Mybatis的Mapper文件
      mapper-locations: classpath:com/f/springboot/mapper/*.xml
      #指定Mybatis的实体目录
      type-aliases-package: com.f.springboot.pojo

      # 配置数据库信息

      # 配法1
      #spring:
      # datasource:
      # driver-class-name: com.mysql.cj.jdbc.Driver
      # url: jdbc:mysql://localhost:3306/springboot
      # username: root
      # password: root
      # type: com.alibaba.druid.pool.DruidDataSource

      # 配法2(更推荐)
      spring:
      datasource:
      druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/springboot
      username: root
      password: root
    4. 接下来的步骤类似于 1.4.2 整合Mybatis 小节,就不做过多赘述了。

1.5 ★★★基于Springboot的SSMP整合

  1. 案例实现方案分析
    实体类开发————使用Lombok快速制作实体类
    Dao开发————整合MyBatisPlus,制作数据层测试类
    Service开发————基于MyBatisPlus进行增量开发,制作业务层测试类
    Controller开发————基于Restful开发,使用PostMan测试接口功能
    Controller开发————前后端开发协议制作
    页面开发————基于VUE+ElementUI制作,前后端联调,页面数据处理,页面消息处理
    列表、新增、修改、删除、分页、查询
    项目异常处理
    按条件查询————页面功能调整、Controller修正功能、Service修正功能
  2. SSMP案例制作流程解析
    先开发基础CRUD功能,做一层测一层
    调通页面,确认异步提交成功后,制作所有功能
    添加分页功能与查询功能

1.5.1 前期准备

  1. 创建新模块 springboot_06_ssmp,选择 Spring 初始化,并配置模块相关基础信息:

  2. 选择当前模块需要使用的技术集,包括 Spring Web、MySQL Driver,在项目初始化后配置 pom.xml 文件,手动添加 mybatis-plusdruidboot-starter 依赖:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    <?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>
    <groupId>com.f</groupId>
    <artifactId>springboot_06_ssmp</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_06_ssmp</name>
    <description>springboot_06_ssmp</description>

    <properties>
    <java.version>17</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <spring-boot.version>3.0.2</spring-boot.version>
    </properties>

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

    <dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
    </dependency>

    <dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3</version>
    </dependency>

    <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.19</version>
    </dependency>

    <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    </dependency>

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    </dependency>
    </dependencies>
    <dependencyManagement>
    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>${spring-boot.version}</version>
    <type>pom</type>
    <scope>import</scope>
    </dependency>
    </dependencies>
    </dependencyManagement>

    <build>
    <plugins>
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.1</version>
    <configuration>
    <source>17</source>
    <target>17</target>
    <encoding>UTF-8</encoding>
    </configuration>
    </plugin>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>${spring-boot.version}</version>
    <configuration>
    <mainClass>com.f.springboot.Springboot06SsmpApplication</mainClass>
    <skip>true</skip>
    </configuration>
    <executions>
    <execution>
    <id>repackage</id>
    <goals>
    <goal>repackage</goal>
    </goals>
    </execution>
    </executions>
    </plugin>
    </plugins>
    </build>

    </project>
    • 手动添加依赖的原因是:在 spring-boot-dependencies 中没有对 mybatis-plusdruidboot-starter 依赖的版本号进行维护。
  3. application.properties 配置文件改为 application.yml 格式,配置端口号:

    1
    2
    3
    # 应用服务 WEB 访问端口
    server:
    port: 80
  4. 在 springboot 数据库中创建 t_book 表:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    DROP TABLE IF EXISTS `t_book`;
    CREATE TABLE `t_book` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `type` varchar(20) DEFAULT NULL,
    `name` varchar(50) DEFAULT NULL,
    `description` varchar(255) DEFAULT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

    -- ----------------------------
    -- Records of t_book
    -- ----------------------------
    INSERT INTO `t_book` VALUES ('1', '计算机理论', 'Spring实战第5版', 'Spring入门经典教程,深入理解Spring原理技术内幕');
    INSERT INTO `t_book` VALUES ('2', '计算机理论', 'Spring 5核心原理与30个类手写实战', '十年沉淀之作,写Spring精华思想');
    INSERT INTO `t_book` VALUES ('3', '计算机理论', 'Spring 5设计模式', '深入Spring源码剖析Spring源码中蕴含的10大设计模式');
    INSERT INTO `t_book` VALUES ('4', '计算机理论', 'Spring MVC+ MyBatis开发从入门到项目实战', '全方位解析面向Web应用的轻量级框架,带你成为Spring MVC开发高手');
    INSERT INTO `t_book` VALUES ('5', '计算机理论', '轻量级Java Web企业应用实战', '源码级剖析Spring框架,适合已掌握Java基础的读者');
    INSERT INTO `t_book` VALUES ('6', '计算机理论', 'Java核心技术卷|基础知识(原书第11版)', 'Core Java第11版,Jolt大奖获奖作品,针对Java SE9、10、 11全面更新');
    INSERT INTO `t_book` VALUES ('7', '计算机理论', '深入理解Java虚拟机', '5个维度全面剖析JVM,面试知识点全覆盖');
    INSERT INTO `t_book` VALUES ('8', '计算机理论', 'Java编程思想(第4版)', 'Java学习必读经典殿堂级著作!赢得了全球程序员的广泛赞誉');
    INSERT INTO `t_book` VALUES ('9', '计算机理论', '零基础学Java (全彩版)', '零基础自学编程的入门]图书,由浅入深,详解Java语言的编程思想和核心技术');
    INSERT INTO `t_book` VALUES ('10', '市场营销', '直播就该这么做:主播高效沟通实战指南', '李子柒、李佳琦、薇娅成长为网红的秘密都在书中');
    INSERT INTO `t_book` VALUES ('11', '市场营销', '直播销讲实战一本通', '和秋叶一起学系列网络营销书籍');
    INSERT INTO `t_book` VALUES ('12', '市场营销', '直播带货:淘宝、天猫直播从新手到高手', '一本教你如何玩转直播的书, 10堂课轻松实现带货月入3W+');

1.5.2 开发实体类(使用Lombok)

  1. 对实体类进行开发,但是我们可以使用 Lombok 快速制作实体类

    • Lombok 是一个 Java 类库,提供了一组注解,用于简化 pojo 实体类开发。

      • 使用 Lombok 之前,需要引入它的依赖:

        1
        2
        3
        4
        <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        </dependency>

        spring-boot-dependencies 中,已经维护了 lombok 的版本号。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    package com.f.springboot.pojo;

    import lombok.*;

    /**
    * @author fzy
    * @date 2024/2/27 20:30
    */
    @NoArgsConstructor
    @AllArgsConstructor
    @Getter
    @Setter
    @ToString
    @EqualsAndHashCode
    public class Book {
    private Integer id;
    private String type;
    private String name;
    private String description;
    }

    其实还有一种更简便的写法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    package com.f.springboot.pojo;

    import lombok.*;

    /**
    * @author fzy
    * @date 2024/2/27 20:30
    */
    @Data
    public class Book {
    private Integer id;
    private String type;
    private String name;
    private String description;
    }
    • @Data 为当前实体类在编译期设置对应的 get/set 方法,toString 方法,hashCode 方法,equals 方法等

1.5.3 数据层DAO开发

  1. application.yml 配置文件中对数据源和 mybatis-plus 进行配置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # 应用服务 WEB 访问端口
    server:
    port: 80

    # 数据源配置
    spring:
    datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springboot
    username: root
    password: root
    type: com.alibaba.druid.pool.DruidDataSource

    # mybatis-plus配置
    mybatis-plus:
    global-config:
    db-config:
    table-prefix: t_
    id-type: auto # 使用数据库默认的自增策略
  2. 定义数据访问层接口,继承 BaseMapper 接口:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    package com.f.springboot.mapper;

    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.f.springboot.pojo.Book;
    import org.springframework.stereotype.Repository;

    /**
    * @author fzy
    * @date 2024/2/27 20:46
    */
    @Repository
    public interface BookMapper extends BaseMapper<Book> {
    // 可以根据需要自己再添加复杂的sql语句接口,复杂的sql语句写在xml文件中
    }
  3. mybatis-plus 已经预置了一些 sql 语句,进行测试:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    package com.f.springboot.mapper;

    import com.f.springboot.pojo.Book;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;

    import java.util.List;

    /**
    * @author fzy
    * @date 2024/2/27 20:50
    */
    @SpringBootTest
    public class BookMapperTest {
    @Autowired
    private BookMapper bookMapper;

    @Test
    public void testGetById() {
    Book book = bookMapper.selectById(1);
    System.out.println(book);
    }

    @Test
    public void testGetAll() {
    List<Book> books = bookMapper.selectList(null);
    books.forEach(book -> {
    System.out.println(book);
    });
    }

    @Test
    public void testInsert() {
    Book book = new Book();
    book.setType("测试");
    book.setName("测试");
    book.setDescription("测试");
    bookMapper.insert(book);
    }

    @Test
    public void testDeleteById() {
    bookMapper.deleteById(1);
    }

    @Test
    public void testUpdate() {
    Book book = new Book();
    book.setId(2);
    book.setType("测试");
    book.setName("测试");
    book.setDescription("测试");
    bookMapper.updateById(book);
    }
    }
  4. 为了看到 mybatis-plus 的执行过程,要开启 Mybatis-Plus 运行日志,在 application.yml 文件中进行配置(只需要在最后加一行配置 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    # 应用服务 WEB 访问端口
    server:
    port: 80

    # 数据源配置
    spring:
    datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springboot
    username: root
    password: root
    type: com.alibaba.druid.pool.DruidDataSource

    # mybatis-plus配置
    mybatis-plus:
    global-config:
    db-config:
    table-prefix: t_
    id-type: auto # 使用数据库默认的自增策略
    configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  5. mybatis-plus 还具有分页功能,使用分页功能需要设定分页对象 IPage 以及使用 MyBatis-Plus 拦截器,这里不做详细描述,看视频 P37

  6. mybatis-plus 还具有条件查询功能,需要在 QueryWrapper 类中指定条件,然后将 QueryWrapper 对象作为参数传给 select 方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @Test
    public void testGetByCondition() {
    QueryWrapper<Book> wrapper = new QueryWrapper<>();
    // 按条件查询,在wrapper中给定条件
    // 查询那些name列中含有Spring的数据
    String name = "Spring";
    wrapper.like(name != null, "name", name); // 只有当"name != null"时才会带上这个条件
    List<Book> books = bookMapper.selectList(wrapper);
    books.forEach(book -> {
    System.out.println(book);
    });
    }

1.5.4 业务层Service开发

  • Service 层接口定义与 DAO 层接口定义具有较大区别,不要混用:
    • 业务层接口定义关注的是业务的名称。
    • 数据层接口定义关注的是数据库相关的操作。
  1. 定义业务层接口:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package com.f.springboot.service;

    import com.baomidou.mybatisplus.core.metadata.IPage;
    import com.f.springboot.pojo.Book;

    import java.util.List;

    /**
    * @author fzy
    * @date 2024/2/27 22:25
    */
    public interface BookService {
    Boolean save(Book book);
    Boolean update(Book book);
    Boolean delete(Integer id);
    Book getById(Integer id);
    List<Book> getAll();
    IPage<Book> getPage(Integer currentPage, Integer pageSize);
    }
    • 数据层考虑影响了多少条数据,业务层考虑业务是否完成。
      • 所以 dml 操作的返回值都是 Boolean 类型,而不是 Integer 类型。
  2. 业务层接口实现类:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    package com.f.springboot.service.impl;

    import com.baomidou.mybatisplus.core.metadata.IPage;
    import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
    import com.f.springboot.mapper.BookMapper;
    import com.f.springboot.pojo.Book;
    import com.f.springboot.service.BookService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;

    import java.util.List;

    /**
    * @author fzy
    * @date 2024/2/27 22:26
    */
    @Service
    public class BookServiceImpl implements BookService {
    @Autowired
    private BookMapper bookMapper;

    @Override
    public Boolean save(Book book) {
    return bookMapper.insert(book) > 0;
    }

    @Override
    public Boolean update(Book book) {
    return bookMapper.updateById(book) > 0;
    }

    @Override
    public Boolean delete(Integer id) {
    return bookMapper.deleteById(id) > 0;
    }

    @Override
    public Book getById(Integer id) {
    return bookMapper.selectById(id);
    }

    @Override
    public List<Book> getAll() {
    return bookMapper.selectList(null);
    }

    @Override
    public IPage<Book> getPage(Integer currentPage, Integer pageSize) {
    IPage page = new Page(currentPage, pageSize);
    return bookMapper.selectPage(page, null);
    }
    }
  3. 业务层测试类:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    package com.f.springboot.service;

    import com.baomidou.mybatisplus.core.metadata.IPage;
    import com.f.springboot.pojo.Book;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;

    import java.util.List;

    /**
    * @author fzy
    * @date 2024/2/28 9:41
    */
    @SpringBootTest
    public class BookServiceTest {
    @Autowired
    private BookService bookService;

    @Test
    public void testGetById() {
    Book book = bookService.getById(2);
    System.out.println(book);
    }

    @Test
    public void testGetAll() {
    List<Book> books = bookService.getAll();
    books.forEach(book -> {
    System.out.println(book);
    });
    }

    @Test
    public void testSave() {
    Book book = new Book();
    book.setType("测试");
    book.setName("测试");
    book.setDescription("测试");
    bookService.save(book);
    }

    @Test
    public void testDeleteById() {
    bookService.delete(1);
    }

    @Test
    public void testUpdate() {
    Book book = new Book();
    book.setId(2);
    book.setType("测试");
    book.setName("测试");
    book.setDescription("测试");
    bookService.update(book);
    }

    @Test
    public void testGetPage() {
    IPage<Book> page = bookService.getPage(2, 5);
    System.out.println(page.getCurrent());
    System.out.println(page.getSize());
    System.out.println(page.getPages());
    System.out.println(page.getTotal());
    System.out.println(page.getRecords());
    }
    }
  4. 如果对项目中的另外一张表 t_user 进行操作,操作方法和 t_book 基本相同,那就意味着新建的 UserService 接口和已有的 BookService 接口重合度很大,等于是在写重复的代码。

    为此,MyBatis-Plus 提供有业务层通用接口(ISerivce<T>)与业务层通用实现类(ServiceImpl<M,T>),来帮助我们简化开发,减少重复代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    package com.f.springboot.service;

    import com.baomidou.mybatisplus.extension.service.IService;
    import com.f.springboot.pojo.Book;

    /**
    * @author fzy
    * @date 2024/2/28 10:06
    */
    public interface IBookService extends IService<Book> {
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package com.f.springboot.service.impl;

    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.f.springboot.mapper.BookMapper;
    import com.f.springboot.pojo.Book;
    import com.f.springboot.service.IBookService;
    import org.springframework.stereotype.Service;

    /**
    * @author fzy
    * @date 2024/2/28 10:09
    */
    @Service
    public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements IBookService {
    // 可以根据需要自己再添加业务方法
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    package com.f.springboot.service;

    import com.baomidou.mybatisplus.core.metadata.IPage;
    import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
    import com.f.springboot.pojo.Book;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;

    import java.util.List;

    /**
    * @author fzy
    * @date 2024/2/28 10:12
    */
    @SpringBootTest
    public class IBookServiceTest {
    @Autowired
    private IBookService bookService;

    @Test
    public void testGetById() {
    Book book = bookService.getById(2);
    System.out.println(book);
    }

    @Test
    public void testGetAll() {
    List<Book> books = bookService.list();
    books.forEach(book -> {
    System.out.println(book);
    });
    }

    @Test
    public void testSave() {
    Book book = new Book();
    book.setType("测试");
    book.setName("测试");
    book.setDescription("测试");
    bookService.save(book);
    }

    @Test
    public void testDeleteById() {
    bookService.removeById(13);
    }

    @Test
    public void testUpdate() {
    Book book = new Book();
    book.setId(3);
    book.setType("测试");
    book.setName("测试");
    book.setDescription("测试");
    bookService.updateById(book);
    }

    @Test
    public void testGetPage() {
    IPage<Book> p = new Page<>(2,5);
    IPage<Book> page = bookService.page(p);
    System.out.println(page.getCurrent());
    System.out.println(page.getSize());
    System.out.println(page.getPages());
    System.out.println(page.getTotal());
    System.out.println(page.getRecords());
    }
    }
    • 注意:在通用类基础上做功能重载或功能追加,重载时不要覆盖原始操作,避免原始提供的功能丢失

1.5.5 表现层Controller开发

  • 基于 Restful 风格进行开发,并使用 PostMan 测试接口功能。
  1. 表现层实现类 BookController

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    package com.f.springboot.controller;

    import com.baomidou.mybatisplus.core.metadata.IPage;
    import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
    import com.f.springboot.pojo.Book;
    import com.f.springboot.service.IBookService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;

    import java.util.List;

    /**
    * @author fzy
    * @date 2024/2/28 10:32
    */
    @RestController
    @RequestMapping("/books")
    public class BookController {
    @Autowired
    private IBookService bookService;

    // 查所有
    @GetMapping
    public List<Book> getAll() {
    return bookService.list();
    }

    // 根据id查询
    @GetMapping("/{id}")
    public Book getById(@PathVariable Integer id) {
    return bookService.getById(id);
    }

    // 分页查询
    @GetMapping("/{currentPage}/{pageSize}")
    public List<Book> getByPage(@PathVariable Integer currentPage,
    @PathVariable Integer pageSize) {
    IPage page = new Page(currentPage, pageSize);
    bookService.page(page);
    return page.getRecords();
    }

    @PostMapping
    public Boolean save(@RequestBody Book book) {
    return bookService.save(book);
    }

    @DeleteMapping("/{id}")
    public Boolean delete(@PathVariable Integer id) {
    return bookService.removeById(id);
    }

    @PutMapping
    public Boolean update(@RequestBody Book book) {
    return bookService.updateById(book);
    }
    }
  2. 运行自动生成的 Application 类,启动服务器:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    package com.f.springboot;

    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;

    @SpringBootApplication
    @MapperScan("com.f.springboot.mapper")
    public class Springboot06SsmpApplication {

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

    }
  3. 使用 PostMan 进行测试,这里以保存业务为例:

  4. 目前来看,BookController 中方法的返回结果有以下几种:

    • Boolean 类型、单条 json 数据、多条 json 数据,json 数组:

    那在数据返回前端时,前端程序员要对不同的类型做不同的操作,是比较麻烦的,所以我们要统一数据格式。

    • 我们希望后端返回给前端的数据类型统一为:

      • flag 表示此次操作是否成功。
      • dataBookController 中方法的返回结果。

      所以我们要设计表现层返回结果的模型类,用于后端与前端进行数据格式统一,也称为“前后端数据协议”

  5. 表现层返回结果的模型类:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    package com.f.springboot.controller.utils;

    import lombok.Data;

    /**
    * @author fzy
    * @date 2024/2/28 14:09
    */
    @Data
    public class Result {
    private Boolean flag; // 表示操作是否成功
    private Object data; // 后端返回的数据

    public Result() {
    }

    public Result(Boolean flag) {
    this.flag = flag;
    }

    public Result(Boolean flag, Object data) {
    this.flag = flag;
    this.data = data;
    }
    }
    • 有了这个类,我们就可以对 BookController 进行修改:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      package com.f.springboot.controller;

      import com.baomidou.mybatisplus.core.metadata.IPage;
      import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
      import com.f.springboot.controller.utils.Result;
      import com.f.springboot.pojo.Book;
      import com.f.springboot.service.IBookService;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.web.bind.annotation.*;

      /**
      * @author fzy
      * @date 2024/2/28 14:12
      */
      @RestController
      @RequestMapping("/books")
      public class BookController2 {
      @Autowired
      private IBookService bookService;

      // 查所有
      @GetMapping
      public Result getAll() {
      return new Result(true, bookService.list());
      }

      // 根据id查询
      @GetMapping("/{id}")
      public Result getById(@PathVariable Integer id) {
      return new Result(true, bookService.getById(id));
      }

      // 分页查询
      @GetMapping("/{currentPage}/{pageSize}")
      public Result getByPage(@PathVariable Integer currentPage,
      @PathVariable Integer pageSize) {
      IPage page = new Page(currentPage, pageSize);
      bookService.page(page);
      return new Result(true, page.getRecords());
      }

      @PostMapping
      public Result save(@RequestBody Book book) {
      // Result result = new Result();
      // boolean flag = bookService.save(book);
      // result.setFlag(flag);
      // return result;
      return new Result(bookService.save(book));
      }

      @DeleteMapping("/{id}")
      public Result delete(@PathVariable Integer id) {
      return new Result(bookService.removeById(id));
      }

      @PutMapping
      public Result update(@RequestBody Book book) {
      return new Result(bookService.updateById(book));
      }
      }

      让所有方法的返回结果都是 Result 类型。

★前后端数据协议
  1. 设计统一的返回值结果类型便于前端开发读取数据。
  2. 返回值结果类型可以根据需求自行设定,没有固定格式。
  3. “返回值结果模型类” 用于后端与前端进行数据格式统一,也称为前后端数据协议。

1.5.6 表现层Web开发

  • 在前后端分离结构设计中,页面归属前端服务器。

    在单体工程中,页面放置在 resources 目录下的 static 目录中

  • 前端开发部分就不写笔记了,对应视频为 P43-P49

---------------The End---------------