• SpringBoot 基础篇——基于SpringBoot实现ssm/ssmp整合


    📄个人主页:胖虎不秃头
    个人简介:Java领域新星创作者,随时准备跑路的大二学生
    🔥精品专栏:有这一个就够了
    🌈个人名言:知道的越多,不知道的越多
    💥刷题神器:推荐一款算法刷题网站Nowcoder👉点击跳转刷题网站进行注册学习

    文章目录

    01-开发环境

    学习要求

    • 熟悉Spring基础
    • 熟悉Maven使用

    环境要求

    • Java8及以上
    • Maven 3.5及以上:https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started.html#getting-started-system-requirements

    学习资料

    • Spring Boot官网:https://spring.io/projects/spring-boot

    • Spring Boot 官方文档:https://docs.spring.io/spring-boot/docs/current/reference/html/

    • Spring Boot 中文文档:http://felord.cn/_doc/_springboot/2.1.5.RELEASE/_book/

    • 视频地址:https://www.bilibili.com/video/BV15b4y1a7yG?p=24&share_source=copy_web

    • 源码地址:GitHub Gitee

    02-内容介绍

    • 基础篇
    Java基础语法
    SpringSpringMVC
    	知道Spring是用来管理bean,能够基于Restful实现页面请求交互功能
    MybatisMybatis-Plus
    	基于MybatisMybatisPlus能够开发出包含基础CRUD功能的标准Dao模块
    数据库MySQL
    	能够读懂基础CRUD功能的SQL语句
    服务器
    	知道服务器与web工程的关系,熟悉web服务器的基础配置
    maven
    	知道maven的依赖关系,知道什么是依赖范围,依赖传递,排除依赖,可选依赖,继承
    web技术(含vue,ElementUI)
    	知道vue如何发送ajax请求,如何获取响应数据,如何进行数据模型双向绑定
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    03-SpringBoot入门案例(Idea联网版)

    • SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化Spring应用的初始搭建以及开发过程

    ①:创建新模块,选择Spring Initializr,并配置模块相关基础信息
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IbzjXtdz-1662949981898)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16.png)]

    ②:选择当前模块需要使用的技术集
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yTC0ZZ8f-1662949981900)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298114.png)]

    ③:开发控制器类

    //Rest 模式
    @RestController
    @RequestMapping("/books")
    public class BookController {
        @GetMapping
        public String getById() {
            System.out.println("springboot is running...");
            return "springboot is running...";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    ④:运行自动生成的Application类
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ErPVEW0k-1662949981901)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298215.png)]

    ⑤:打开浏览器访问url地址为:http://localhost:8080/books

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cXRGOJiU-1662949981901)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298216.png)]

    • 最简SpringBoot程序所包含的基础文件 (pom.xml文件 和 Application类 )
      • pom.xml文件
    
    <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.0modelVersion>
        <parent>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-parentartifactId>
            <version>2.5.6version>
        parent>
        <groupId>com.examplegroupId>
        <artifactId>springboot-01-quickstartartifactId>
        <version>0.0.1-SNAPSHOTversion>
        <dependencies>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-testartifactId>
                <scope>testscope>
            dependency>
        dependencies>
    project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • Application类
    @SpringBootApplication
    public class Springboot0101QuickstartApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(Springboot0101QuickstartApplication.class, args);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • Spring程序与SpringBoot程序对比
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ujYsnLzO-1662949981901)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298217.png)]

      注意: 基于idea开发SpringBoot程序需要确保联网且能够加载到程序框架结构

    小结:

    1. 开发SpringBoot程序可以根据向导进行联网快速制作
    2. SpringBoot程序需要基于JDK8进行制作
    3. SpringBoot程序中需要使用何种功能通过勾选选择技术
    4. 运行SpringBoot程序通过运行Application程序入口进行

    04-SpringBoot入门案例(官网创建版)

    • 基于SpringBoot官网创建项目,地址:https://start.spring.io/
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vtkQ07DF-1662949981902)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298218.png)]

    小结:

    1. 打开SpringBoot官网,选择Quickstart Your Project
    2. 创建工程,并保存项目
    3. 解压项目,通过IDE导入项目

    05-SpringBoot入门案例(阿里云版)

    • 基于阿里云创建项目,地址:https://start.aliyun.com
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fwDpq6fY-1662949981902)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298219.png)]

    注意事项:

    • 阿里云提供的坐标版本较低,如果需要使用高版本,进入工程后手工切换SpringBoot版本

    • 阿里云提供的工程模板与Spring官网提供的工程模板略有不同

    小结:

    1. 选择start来源为自定义URL
    2. 输入阿里云start地址
    3. 创建项目

    06-SpringBoot入门案例(手工制作版)

    • 手工创建项目(手工导入坐标)
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zyN9pxoa-1662949981903)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298220.png)]
    
    <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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0modelVersion>
    
        <parent>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-parentartifactId>
            <version>2.5.6version>
        parent>
    
        <groupId>com.examplegroupId>
        <artifactId>springboot_01_04_quickstartartifactId>
        <version>1.0-SNAPSHOTversion>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
        dependencies>
    project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 手工创建项目(手工制作引导类)
    @SpringBootApplication
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    小结:

    1. 创建普通Maven工程
    2. 继承spring-boot-starter-parent
    3. 添加依赖spring-boot-starter-web
    4. 制作引导类Application

    总结:

    1. 创建SpringBoot工程的四种方式
      基于Idea创建SpringBoot工程
      基于官网创建SpringBoot工程
      基于阿里云创建SpringBoot工程
      手工创建Maven工程修改为SpringBoot工程

    07-教你一招:隐藏文件或文件夹

    • .mvn;.gitignore;HELP.md;mvnw;mvnw.cmd;*.iml;
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jf5PNB7d-1662949981903)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298221.png)]

    2018版的做法:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XiaE4Nd0-1662949981903)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298322.png)]

    较新版本的做法 :
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kBrvdoht-1662949981904)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298323.png)]

    小结:

    1. Idea中隐藏指定文件或指定类型文件
      Setting → File Types → Ignored Files and Folders
      输入要隐藏的文件名,支持*号通配符
      回车确认添加

    08-入门案例解析:parent

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rQ1GguUU-1662949981904)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298324.png)]

    • parent
    
    <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.0modelVersion>
        <parent>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-parentartifactId>
            <version>2.5.6version>
        parent>
        <groupId>com.examplegroupId>
        <artifactId>springboot-01-quickstartartifactId>
        <version>0.0.1-SNAPSHOTversion>
        <dependencies>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-testartifactId>
                <scope>testscope>
            dependency>
        dependencies>
    project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    按住Ctrl点击pom.xml中的spring-boot-starter-parent,跳转到了spring-boot-starter-parent的pom.xml,xml配置如下(只摘抄了部分重点配置):

      <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-dependenciesartifactId>
        <version>2.5.6version>
      parent>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    按住Ctrl点击pom.xml中的spring-boot-starter-dependencies,跳转到了spring-boot-starter-dependencies的pom.xml,xml配置如下(只摘抄了部分重点配置):

    <properties>
      	<activemq.version>5.15.3activemq.version>
      	<antlr2.version>2.7.7antlr2.version>
      	<appengine-sdk.version>1.9.63appengine-sdk.version>
      	<artemis.version>2.4.0artemis.version>
      	<aspectj.version>1.8.13aspectj.version>
      	<assertj.version>3.9.1assertj.version>
      	<atomikos.version>4.0.6atomikos.version>
      	<bitronix.version>2.1.4bitronix.version>
      	<build-helper-maven-plugin.version>3.0.0build-helper-maven-plugin.version>
      	<byte-buddy.version>1.7.11byte-buddy.version>
      	... ... ...
    properties>
    <dependencyManagement>
      	<dependencies>
          	<dependency>
            	<groupId>org.springframework.bootgroupId>
            	<artifactId>spring-bootartifactId>
            	<version>2.0.1.RELEASEversion>
          	dependency>
          	<dependency>
            	<groupId>org.springframework.bootgroupId>
            	<artifactId>spring-boot-testartifactId>
            	<version>2.0.1.RELEASEversion>
          	dependency>
          	... ... ...
    	dependencies>
    dependencyManagement>
    <build>
      	<pluginManagement>
        	<plugins>
          		<plugin>
            		<groupId>org.jetbrains.kotlingroupId>
            		<artifactId>kotlin-maven-pluginartifactId>
            		<version>${kotlin.version}version>
          		plugin>
          		<plugin>
            		<groupId>org.jooqgroupId>
            		<artifactId>jooq-codegen-mavenartifactId>
            		<version>${jooq.version}version>
          		plugin>
          		<plugin>
            		<groupId>org.springframework.bootgroupId>
            		<artifactId>spring-boot-maven-pluginartifactId>
            		<version>2.0.1.RELEASEversion>
          		plugin>
              	... ... ...
        	plugins>
      	pluginManagement>
    build>
    
    • 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

    从上面的spring-boot-starter-dependencies的pom.xml中我们可以发现,一部分坐标的版本、依赖管理、插件管理已经定义好,所以我们的SpringBoot工程继承spring-boot-starter-parent后已经具备版本锁定等配置了。所以起步依赖的作用就是进行依赖的传递。

    小结:

    1. 开发SpringBoot程序要继承spring-boot-starter-parent
    2. spring-boot-starter-parent中定义了若干个依赖管理
    3. 继承parent模块可以避免多个依赖使用相同技术时出现依赖版本冲突
    4. 继承parent的形式也可以采用引入依赖的形式实现效果

    09-入门案例解析:starter

    • spring-boot-starter-web.pom
      按住Ctrl点击pom.xml中的spring-boot-starter-web,跳转到了spring-boot-starter-web的pom.xml,xml配置如下(只摘抄了部分重点配置):
    
    <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://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.0modelVersion>
      	<parent>
        	<groupId>org.springframework.bootgroupId>
        	<artifactId>spring-boot-startersartifactId>
        	<version>2.0.1.RELEASEversion>
      	parent>
      	<groupId>org.springframework.bootgroupId>
      	<artifactId>spring-boot-starter-webartifactId>
      	<version>2.0.1.RELEASEversion>
      	<name>Spring Boot Web Startername>
      
      	<dependencies>
        	<dependency>
          		<groupId>org.springframework.bootgroupId>
          		<artifactId>spring-boot-starterartifactId>
          		<version>2.0.1.RELEASEversion>
          		<scope>compilescope>
        	dependency>
        	<dependency>
          		<groupId>org.springframework.bootgroupId>
          		<artifactId>spring-boot-starter-jsonartifactId>
          		<version>2.0.1.RELEASEversion>
          		<scope>compilescope>
        	dependency>
        	<dependency>
          		<groupId>org.springframework.bootgroupId>
          		<artifactId>spring-boot-starter-tomcatartifactId>
          		<version>2.0.1.RELEASEversion>
          		<scope>compilescope>
        	dependency>
        	<dependency>
          		<groupId>org.hibernate.validatorgroupId>
          		<artifactId>hibernate-validatorartifactId>
          		<version>6.0.9.Finalversion>
          		<scope>compilescope>
        	dependency>
        	<dependency>
          		<groupId>org.springframeworkgroupId>
          		<artifactId>spring-webartifactId>
          		<version>5.0.5.RELEASEversion>
          		<scope>compilescope>
        	dependency>
        	<dependency>
          		<groupId>org.springframeworkgroupId>
          		<artifactId>spring-webmvcartifactId>
          		<version>5.0.5.RELEASEversion>
          		<scope>compilescope>
        	dependency>
      	dependencies>
    project>
    
    • 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

    从上面的spring-boot-starter-web的pom.xml中我们可以发现,spring-boot-starter-web就是将web开发要使用的spring-web、spring-webmvc等坐标进行了“打包”,这样我们的工程只要引入spring-boot-starter-web起步依赖的坐标就可以进行web开发了,同样体现了依赖传递的作用。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jraxgb76-1662949981904)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298325.png)]

    • starter
      SpringBoot中常见项目名称,定义了当前项目使用的所有依赖坐标,以达到减少依赖配置的目的
    • parent
      所有SpringBoot项目要继承的项目,定义了若干个坐标版本号(依赖管理,而非依赖),以达到减少依赖冲突的目的
      spring-boot-starter-parent各版本间存在着诸多坐标版本不同
    • 实际开发
      使用任意坐标时,仅书写GAV(groupId, artifactId, version)中的G和A,V由SpringBoot提供,除非SpringBoot未提供对应版本V
      如发生坐标错误,再指定Version(要小心版本冲突)

    小结:

    1. 开发SpringBoot程序需要导入坐标时通常导入对应的starter
    2. 每个不同的starter根据功能不同,通常包含多个依赖坐标
    3. 使用starter可以实现快速配置的效果,达到简化配置的目的

    10-入门案例解析:引导类

    • 启动方式
    @SpringBootApplication
    public class Springboot0101QuickstartApplication {
    
        public static void main(String[] args) {
            ConfigurableApplicationContext ctx = SpringApplication.run(Springboot0101QuickstartApplication.class, args);
            //获取bean对象
            BookController bean = ctx.getBean(BookController.class);
            System.out.println("bean======>" + bean);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • SpringBoot的引导类是Boot工程的执行入口,运行main方法就可以启动项目
    • SpringBoot工程运行后初始化Spring容器,扫描引导类所在包加载bean

    小结:

    1. SpringBoot工程提供引导类用来启动程序
    2. SpringBoot工程启动后创建并初始化Spring容器

    11-入门案例:辅助功能

    • 辅助功能 内嵌tomcat
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nc8KovHo-1662949981905)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298326.png)]

    • 使用maven依赖管理变更起步依赖项

        <dependencies>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
                
                <exclusions>
                    <exclusion>
                        <groupId>org.springframework.bootgroupId>
                        <artifactId>spring-boot-starter-tomcatartifactId>
                    exclusion>
                exclusions>
            dependency>
            
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-jettyartifactId>
            dependency>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-testartifactId>
                <scope>testscope>
            dependency>
        dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • Jetty比Tomcat更轻量级,可扩展性更强(相较于Tomcat),谷歌应用引擎(GAE)已经全面切换为Jetty
    • 内置服务器
      tomcat(默认) apache出品,粉丝多,应用面广,负载了若干较重的组件
      jetty 更轻量级,负载性能远不及tomcat
      undertow undertow,负载性能勉强跑赢tomcat

    小结:

    1. 内嵌Tomcat服务器是SpringBoot辅助功能之一
    2. 内嵌Tomcat工作原理是将Tomcat服务器作为对象运行,并将该对象交给Spring容器管理
    3. 变更内嵌服务器思想是去除现有服务器,添加全新的服务器

    总结:

    1. 入门案例(4种方式)
    2. SpringBoot概述
      parent
      starter
      引导类
      辅助功能(内嵌tomcat)

    知识加油站-01-REST风格简介

    1. 什么是 rest :

      • REST(Representational State Transfer)表现形式状态转换

      • 传统风格资源描述形式
        http://localhost/user/getById?id=1 (得到id为1的用户)
        http://localhost/user/saveUser (保存用户)

      • REST风格描述形式
        http://localhost/user/1 (得到id为1的用户)
        http://localhost/user (保存用户)

    2. 优点:

      • 隐藏资源的访问行为, 无法通过地址得知对资源是何种操作
      • 书写简化
    3. 按照REST风格访问资源时使用行为动作区分对资源进行了何种操作

      GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源

      • http://localhost/users 查询全部用户信息 GET (查询)
      • http://localhost/users/1 查询指定用户信息 GET (查询)
      • http://localhost/users 添加用户信息 POST (新增/保存)
      • http://localhost/users 修改用户信息 PUT (修改/更新)
      • http://localhost/users/1 删除用户信息 DELETE (删除)

      注意:

      上述行为是约定方式,约定不是规范,可以打破,所以称REST风格,而不是REST规范
      描述模块的名称通常使用复数,也就是加s的格式描述,表示此类资源,而非单个资源,例如: users、 books、 accounts…

    4. 根据REST风格对资源进行访问称为RESTful

    5. 小结:

      1. REST
      2. 动作4个
      3. RESTful

    知识加油站-02-RESTful入门案例

    步骤:

    ①:设定http请求动作(动词)

    使用 @RequestMapping 注解的 method 属性声明请求的方式

    使用 @RequestBody 注解 获取请求体内容。直接使用得到是 key=value&key=value…结构的数据。get 请求方式不适用。

    使用@ResponseBody 注解实现将 controller 方法返回对象转换为 json 响应给客户端。

    @RequestMapping(value="/users",method=RequestMethod.POST)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HQbjY74G-1662950266886)(../../../Pictures/SpringBoot/8fc4afea23a513d605b885db910e2ac8.png)]

    ②:设定请求参数(路径变量)

    使用@PathVariable 用于绑定 url 中的占位符。例如:请求 url 中 /delete/{id},这个{id}就是 url 占位符。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4B40Q46Z-1662949981905)(../../../Pictures/SpringBoot/d35b1e484bae94e8f5b5c5804610afbe.png)]

    • @RequestMapping

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t6PtvKwb-1662949981906)(../../../Pictures/SpringBoot/1b6cff3e21c9f8f39d03609ca5549dc5.png)]

    • @PathVariable

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YSuDgzV5-1662949981906)(../../../Pictures/SpringBoot/70f82ea4f1c61a34eb68fda48cc9ada3.png)]

    • @RequestBody @RequestParam @PathVariable

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LHE7tNMw-1662949981906)(../../../Pictures/SpringBoot/9b9324456b495d978751d23ce868c101.png)]

    知识加油站-03-RESTful快速开发

    • 使用 @RestController 注解开发 RESTful 风格

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EkItUCZe-1662949981907)(../../../Pictures/SpringBoot/e7b67442721c662525b77651f8c60f11.png)]

    • 使用 @GetMapping @PostMapping @PutMapping @DeleteMapping 简化 @RequestMapping 注解开发

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K8UYO6aH-1662949981907)(../../../Pictures/SpringBoot/5c4f5989f8975d8c058a2038752b528b.png)]

    12-教你一招:复制模块

    • 原则
      保留工程基础结构
      抹掉原始工程痕迹
      在这里插入图片描述
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p366Nlo6-1662949981908)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298428.png)]
      在这里插入图片描述

    小结:

    1. 在工作空间中复制对应工程,并修改工程名称
    2. 删除与Idea相关配置文件,仅保留src目录与pom.xml文件
    3. 修改pom.xml文件中的artifactId与新工程/模块名相同
    4. 删除name标签(可选)
    5. 保留备份工程供后期使用

    13-属性配置方式

    • 修改服务器端口

    在这里插入图片描述

    • SpringBoot默认配置文件application.properties,通过键值对配置对应属性

    • 修改配置
      修改服务器端口

      # 服务器端口配制
      server.port=80
      
      • 1
      • 2

      小结:

    1. SpringBoot默认配置文件application.properties

    14-基础配置

    1. 修改配置
      修改服务器端口
      server.port=80
      关闭运行日志图标(banner)
      spring.main.banner-mode=off
      设置日志相关
      logging.level.root=debug
    # 服务器端口配置
    server.port=80
    
    # 修改banner
    # spring.main.banner-mode=off
    # spring.banner.image.location=logo.png
    
    # 日志
    logging.level.root=info
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. SpringBoot内置属性查询
      https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#application-properties
      官方文档中参考文档第一项:Application Propertie

    小结:

    1. SpringBoot中导入对应starter后,提供对应配置属性
    2. 书写SpringBoot配置采用关键字+提示形式书写

    15-3种配置文件类型

    • 配置文件格式
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GLmzaNHz-1662949981909)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298529.png)]

    • SpringBoot提供了多种属性配置方式

    1. application.properties
    server.port=80
    
    • 1
    1. application.yml
    server:
      port: 81
    
    • 1
    • 2
    1. application.yaml
    server:
      port: 82
    
    • 1
    • 2

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CJUXwuE1-1662949981909)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298530.png)]

    小结:

    1. SpringBoot提供了3种配置文件的格式
      properties(传统格式/默认格式)
      yml(主流格式)
      yaml

    16-配置文件加载优先级

    • SpringBoot配置文件加载顺序
      application.properties > application.yml > application.yaml
    • 常用配置文件种类
      application.yml

    小结:

    1. 配置文件间的加载优先级
      properties(最高)
      yml
      yaml(最低)
    2. 不同配置文件中相同配置按照加载优先级相互覆盖 (高优先级配置内容会覆盖低优先级配置内容),不同配置文件中不同配置全部保留

    17-教你一招:属性提示消失解决方案

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3aMCRCHl-1662949981909)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298531.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jc1ehBhE-1662949981909)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298632.png)]

    小结:

    1. 指定SpringBoot配置文件
      Setting → Project Structure → Facets
      选中对应项目/工程
      Customize Spring Boot
      选择配置文件

    18-yaml数据格式

    yaml

    • YAML(YAML Ain’t Markup Language),一种数据序列化格式
    1. 优点:

      • 容易阅读
      • 容易与脚本语言交互
      • 以数据为核心,重数据轻格式
    2. YAML文件扩展名

      • .yml(主流
      • .yaml

    yaml语法规则

    基本语法

    • key: value -> value 前面一定要有空格
    • 大小写敏感
    • 属性层级关系使用多行描述,每行结尾使用冒号结束
    • 使用缩进表示层级关系,同层级左侧对齐,只允许使用空格(不允许使用Tab键)
    • 属性值前面添加空格(属性名与属性值之间使用冒号+空格作为分隔)
    • # 表示注释
    • 核心规则:数据前面要加空格与冒号隔开
    server:
      servlet:
        context-path: /hello
      port: 82
    
    • 1
    • 2
    • 3
    • 4

    数据类型

    • 字面值表示方式
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JGA3Rnvp-1662949981910)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298633.png)]
    # 字面值表示方式
    
    boolean: TRUE       #TRUE,true,True,FALSE,false , False 均可
    float: 3.14         #6.8523015e+5 # 支持科学计数法
    int: 123            #0b1010_0111_0100_1010_1110 # 支持二进制、八进制、十六进制
    # null: ~             # 使用 ~ 表示 null
    string: HelloWorld  # 字符串可以直接书写
    string2: "Hello World"  # 可以使用双引号包裹特殊字符
    date: 2018-02-17        # 日期必须使用 yyyy-MM-dd 格式
    datetime: 2018-02-17T15:02:31+08:00   # 时间和日期之间使用 T 连接,最后使用 + 代表时区
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 数组表示方式:在属性名书写位置的下方使用减号作为数据开始符号,每行书写一个数据,减号与数据间空格分隔
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AXEnfjjo-1662949981910)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298634.png)]
    subject:
      - Java
      - 前端
      - 大数据
    
    enterprise:
      name: zhangsan
      age: 16
    
    subject2:
      - Java
      - 前端
      - 大数据
    likes: [王者荣耀,刺激战场] # 数组书写缩略格式
    
    
    users: # 对象数组格式
      - 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
    • 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

    小结:

    1. yaml语法规则
    	大小写敏感
    	属性层级关系使用多行描述,每行结尾使用冒号结束
    	使用缩进表示层级关系,同层级左侧对齐,只允许使用空格(不允许使用Tab键)
    	属性值前面添加空格(属性名与属性值之间使用冒号+空格作为分隔)
    	# 表示注释
    2. 注意属性名冒号后面与数据之间有一个空格
    3. 字面值、对象数据格式、数组数据格式(略)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    19-读取yaml单一属性数据

    • 使用@Value读取单个数据,属性名引用方式:${一级属性名.二级属性名……}
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PAYJK9Ch-1662949981911)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298635.png)]
        @Value("${country}")
        private String country1;
    
        @Value("${user.age}")
        private String age1;
    
        @Value("${likes[1]}")
        private String likes1;
    
        @Value("${users[1].name}")
        private String name1;
    
    
        @GetMapping
        public String getById() {
            System.out.println("springboot is running2...");
            System.out.println("country1=>" + country1);
            System.out.println("age1=>" + age1);
            System.out.println("likes1=>" + likes1);
            System.out.println("name1=>" + name1);
            return "springboot is running2...";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    小结:

    1. 使用@Value配合SpEL读取单个数据
    2. 如果数据存在多层级,依次书写层级名称即可

    20-yaml文件中的变量引用

    • 在配置文件中可以使用属性名引用方式引用属性[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wKFaZ39w-1662949981911)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298636.png)]

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-txPOaX9s-1662949981912)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298637.png)]

    • 属性值中如果出现转移字符,需要使用双引号包裹
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qkj7TvA6-1662949981912)(../../../Pictures/SpringBoot/4a17254ad96a454987f0c64223af554a.png)]

    小结:

    1. 在配置文件中可以使用${属性名}方式引用属性值
    2. 如果属性中出现特殊字符,可以使用双引号包裹起来作为字符解析

    21-读取yaml全部属性数据

    • 封装全部数据到Environment对象

    • 注意 要导这个 包

    • import org.springframework.core.env.Environment;
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JKTo2c2u-1662949981912)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298638.png)]

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BYLAA97M-1662949981912)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298639.png)]

    小结:

    1. 使用Environment对象封装全部配置信息
    2. 使用@Autowired自动装配数据到Environment对象中

    22-读取yaml引用类型属性数据

    • 自定义对象封装指定数据
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oYjgfwzC-1662949981913)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298740.png)]

    • 自定义对象封装指定数据的作用
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GgrVOwIA-1662949981913)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298741.png)]

    # 创建类,用于封装下面的数据
    # 由spring帮我们去加载数据到对象中,一定要告诉spring加载这组信息
    # 使用时候从spring中直接获取信息使用
    
    datasource:
      driver: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost/springboot_db
      username: root
      password: root666123
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    //1.定义数据模型封装yaml文件中对应的数据
    //2.定义为spring管控的bean
    @Component
    //3.指定加载的数据
    @ConfigurationProperties(prefix = "datasource")
    public class MyDataSource {
    
        private String driver;
        private String url;
        private String username;
        private String password;
    	
    	//省略get/set/tostring 方法
    }    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    使用自动装配封装指定数据

     @Autowired
     private MyDataSource myDataSource;
    
    • 1
    • 2

    输出查看

    System.out.println(myDataSource);
    
    • 1

    小结:

    1. 使用@ConfigurationProperties注解绑定配置信息到封装类中
    2. 封装类需要定义为Spring管理的bean,否则无法进行属性注入

    23-SpringBoot整合JUnit

    • 添加Junit的起步依赖 Spring Initializr 创建时自带
    
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-testartifactId>
        <scope>testscope>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • SpringBoot整合JUnit
    @SpringBootTest
    class Springboot07JunitApplicationTests {
    	@Autowired
    	private BookService bookService;
    	@Test
    	public void testSave(){
    		bookService.save();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • @SpringBootTest
      名称:@SpringBootTest
      类型:测试类注解
      位置:测试类定义上方
      作用:设置JUnit加载的SpringBoot启动类
      范例:
    @SpringBootTest
    class Springboot05JUnitApplicationTests {}
    
    • 1
    • 2

    小结:

    1. 导入测试对应的starter
    2. 测试类使用@SpringBootTest修饰
    3. 使用自动装配的形式添加要测试的对象

    24-整合JUnit——classes属性

    在这里插入图片描述

    @SpringBootTest(classes = Springboot04JunitApplication.class)
    //@ContextConfiguration(classes = Springboot04JunitApplication.class)
    class Springboot04JunitApplicationTests {
        //1.注入你要测试的对象
        @Autowired
        private BookDao bookDao;
    
        @Test
        void contextLoads() {
            //2.执行要测试的对象对应的方法
            bookDao.save();
            System.out.println("two...");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    注意:

    • 如果测试类在SpringBoot启动类的包或子包中,可以省略启动类的设置,也就是省略classes的设定

    小结:

    1. 测试类如果存在于引导类所在包或子包中无需指定引导类
    2. 测试类如果不存在于引导类所在的包或子包中需要通过 classes 属性指定引导类

    25-SpringBoot整合MyBatis

    ①:创建新模块,选择Spring初始化,并配置模块相关基础信息
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CI2DlskT-1662949981913)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298743.png)]

    ②:选择当前模块需要使用的技术集(MyBatis、MySQL)
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-34GK7syv-1662949981914)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298744.png)]

    ③:设置数据源参数

    #DB Configuration:
    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/springboot_db
        username: root
        password: 123456
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    ④:创建user表
    在 springboot_db 数据库中创建 user 表

    -- ----------------------------
    -- Table structure for `user`
    -- ----------------------------
    DROP TABLE IF EXISTS `user`;
    CREATE TABLE `user` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(50) DEFAULT NULL,
      `password` varchar(50) DEFAULT NULL,
      `name` varchar(50) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of user
    -- ----------------------------
    INSERT INTO `user` VALUES ('1', 'zhangsan', '123', '张三');
    INSERT INTO `user` VALUES ('2', 'lisi', '123', '李四');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    ⑤:创建实体Bean

    public class User {
        // 主键
        private Long id;
        // 用户名
        private String username;
        // 密码
        private String password;
        // 姓名
        private String name;
      
        //此处省略getter,setter,toString方法 .. ..
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    ⑥: 定义数据层接口与映射配置

    @Mapper
    public interface UserDao {
    
        @Select("select * from user")
        public List<User> getAll();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    ⑦:测试类中注入dao接口,测试功能

    @SpringBootTest
    class Springboot05MybatisApplicationTests {
    
        @Autowired
        private UserDao userDao;
    
        @Test
        void contextLoads() {
            List<User> userList = userDao.getAll();
            System.out.println(userList);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    ⑧:运行如下

    [User{id=1, username='zhangsan', password='123', name='张三'}, User{id=2, username='lisi', password='123', name='李四'}]
    
    • 1

    总结:

    1. 勾选MyBatis技术,也就是导入MyBatis对应的starter
    2. 数据库连接相关信息转换成配置
    3. 数据库SQL映射需要添加@Mapper被容器识别到

    26-SpringBoot整合MyBatis常见问题处理

    SpringBoot版本低于2.4.3(不含),Mysql驱动版本大于8.0时,需要在url连接串中配置时区

    jdbc:mysql://localhost:3306/springboot_db?serverTimezone=UTC
    
    • 1

    或在MySQL数据库端配置时区解决此问题

    1.MySQL 8.X驱动强制要求设置时区

    • 修改url,添加serverTimezone设定
    • 修改MySQL数据库配置(略)

    2.驱动类过时,提醒更换为com.mysql.cj.jdbc.Driver

    27-SpringBoot整合MyBatisPlus

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jOHh2JVw-1662949981914)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298745.png)]

    ①:手动添加SpringBoot整合MyBatis-Plus的坐标,可以通过mvnrepository获取

       <dependency>
           <groupId>com.baomidougroupId>
           <artifactId>mybatis-plus-boot-starterartifactId>
           <version>3.4.3version>
       dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意事项: 由于SpringBoot中未收录MyBatis-Plus的坐标版本,需要指定对应的Version

    ②:定义数据层接口与映射配置,继承BaseMapper

    @Mapper
    public interface UserDao extends BaseMapper<User> {
    
    }
    
    • 1
    • 2
    • 3
    • 4

    ③:其他同SpringBoot整合MyBatis
    (略)

    ④:测试类中注入dao接口,测试功能

    @SpringBootTest
    class Springboot06MybatisPlusApplicationTests {
    
        @Autowired
        private UserDao userDao;
    
        @Test
        void contextLoads() {
            List<User> users = userDao.selectList(null);
            System.out.println(users);
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    ⑤: 运行如下:

    [User{id=1, username='zhangsan', password='123', name='张三'}, User{id=2, username='lisi', password='123', name='李四'}]
    
    • 1

    注意: 如果你的数据库表有前缀要在 application.yml 添加如下配制

    #设置Mp相关的配置
    mybatis-plus:
      global-config:
        db-config:
          table-prefix: tbl_
    
    • 1
    • 2
    • 3
    • 4
    • 5

    小结:
    1.手工添加MyBatis-Plus对应的starter
    2.数据层接口使用BaseMapper简化开发
    3.需要使用的第三方技术无法通过勾选确定时,需要手工添加坐标

    28-SpringBoot整合Druid

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UeBHIXAl-1662949981914)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298746.png)]

    ①: 导入Druid对应的starter

       <dependency>
           <groupId>com.alibabagroupId>
           <artifactId>druid-spring-boot-starterartifactId>
           <version>1.2.6version>
       dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ②: 指定数据源类型 (这种方式只需导入一个 Druid 的坐标)

    #DB Configuration:
    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/springboot_db?serverTimezone=UTC
        username: root
        password: 123456
        type: com.alibaba.druid.pool.DruidDataSource
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    或者 变更Druid的配置方式(推荐) 这种方式需要导入 Druid对应的starter

    spring:
      datasource:
        druid:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/springboot_db?serverTimezone=UTC
          username: root
          password: 123456
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    小结:

    1.整合Druid需要导入Druid对应的starter
    2.根据Druid提供的配置方式进行配置
    3.整合第三方技术通用方式

    • 导入对应的starter
    • 根据提供的配置格式,配置非默认值对应的配置项

    29-SSMP整合案例制作分析

    案例效果演示:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FhyJr1Mi-1662949981914)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298747.png)]

    案例实现方案分析与流程解析

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

    30-模块创建

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CJgRbSPP-1662949981915)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298748.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FfMFyhsK-1662949981915)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_10,color_FFFFFF,t_70,g_se,x_16.png)]

    pom.xml

       <dependencies>
           <dependency>
               <groupId>org.springframework.bootgroupId>
               <artifactId>spring-boot-starter-webartifactId>
           dependency>
    
           <dependency>
               <groupId>mysqlgroupId>
               <artifactId>mysql-connector-javaartifactId>
               <scope>runtimescope>
           dependency>
    
           <dependency>
               <groupId>com.baomidougroupId>
               <artifactId>mybatis-plus-boot-starterartifactId>
               <version>3.4.3version>
           dependency>
    
           <dependency>
               <groupId>com.alibabagroupId>
               <artifactId>druid-spring-boot-starterartifactId>
               <version>1.2.6version>
           dependency>
    
           <dependency>
               <groupId>org.springframework.bootgroupId>
               <artifactId>spring-boot-starter-testartifactId>
               <scope>testscope>
           dependency>
    
       dependencies>
    
    • 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

    tbl_book.sql

    DROP TABLE IF EXISTS `tbl_book`;
    CREATE TABLE `tbl_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=13 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of tbl_book
    -- ----------------------------
    INSERT INTO `tbl_book` VALUES ('1', '计算机理论', 'Spring实战第5版', 'Spring入门经典教程,深入理解Spring原理技术内幕');
    INSERT INTO `tbl_book` VALUES ('2', '计算机理论', 'Spring 5核心原理与30个类手写实战', '十年沉淀之作,写Spring精华思想');
    INSERT INTO `tbl_book` VALUES ('3', '计算机理论', 'Spring 5设计模式', '深入Spring源码剖析Spring源码中蕴含的10大设计模式');
    INSERT INTO `tbl_book` VALUES ('4', '计算机理论', 'Spring MVC+ MyBatis开发从入门到项目实战', '全方位解析面向Web应用的轻量级框架,带你成为Spring MVC开发高手');
    INSERT INTO `tbl_book` VALUES ('5', '计算机理论', '轻量级Java Web企业应用实战', '源码级剖析Spring框架,适合已掌握Java基础的读者');
    INSERT INTO `tbl_book` VALUES ('6', '计算机理论', 'Java核心技术卷|基础知识(原书第11版)', 'Core Java第11版,Jolt大奖获奖作品,针对Java SE9、10、 11全面更新');
    INSERT INTO `tbl_book` VALUES ('7', '计算机理论', '深入理解Java虚拟机', '5个维度全面剖析JVM,面试知识点全覆盖');
    INSERT INTO `tbl_book` VALUES ('8', '计算机理论', 'Java编程思想(第4版)', 'Java学习必读经典殿堂级著作!赢得了全球程序员的广泛赞誉');
    INSERT INTO `tbl_book` VALUES ('9', '计算机理论', '零基础学Java (全彩版)', '零基础自学编程的入门]图书,由浅入深,详解Java语言的编程思想和核心技术');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    小结:

    1. 勾选SpringMVC与MySQL坐标

    2. 修改配置文件为yml格式

    3. 设置端口为80方便访问

      server:
        port: 80
      
      • 1
      • 2

    31-实体类快速开发(lombok)

    • Lombok,一个Java类库,提供了一组注解,简化POJO实体类开发
            
            <dependency>
                <groupId>org.projectlombokgroupId>
                <artifactId>lombokartifactId>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • lombok版本由SpringBoot提供,无需指定版本
    • 常用注解:@Data
    @Data
    public class Book {
        private Integer id;
        private String type;
        private String name;
        private String description;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 为当前实体类在编译期设置对应的get/set方法,toString方法,hashCode方法,equals方法等

    小结:

    1. 实体类制作
    2. 使用lombok简化开发
    	导入lombok无需指定版本,由SpringBoot提供版本
    	@Data注解
    
    • 1
    • 2
    • 3
    • 4

    32-数据层标准开发(基础CRUD)

    • 导入MyBatisPlus与Druid对应的starter
            <dependency>
                <groupId>com.baomidougroupId>
                <artifactId>mybatis-plus-boot-starterartifactId>
                <version>3.4.3version>
            dependency>
    
            <dependency>
                <groupId>com.alibabagroupId>
                <artifactId>druid-spring-boot-starterartifactId>
                <version>1.2.6version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 配置数据源与MyBatisPlus对应的基础配置(id生成策略使用数据库自增策略)
    # druid 数据源配制
    spring:
      datasource:
        druid:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/springboot_db?serverTimezone=UTC
          username: root
          password: 123456
    
    # mybatis-plus
    mybatis-plus:
      global-config:
        db-config:
          table-prefix: tbl_
          id-type: auto # 主键策略
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 继承BaseMapper并指定泛型
    @Mapper
    public interface BookDao extends BaseMapper<Book> {
    
        /**
         * 查询一个
         * 这是 Mybatis 开发
         * @param id
         * @return
         */
        @Select("select * from tbl_book where id = #{id}")
        Book getById(Integer id);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 制作测试类测试结果
    @SpringBootTest
    public class BookDaoTestCase {
    
        @Autowired
        private BookDao bookDao;
    
        @Test
        void testGetById() {
            System.out.println(bookDao.getById(1));
            System.out.println(bookDao.selectById(1));
        }
    
        @Test
        void testSave() {
            Book book = new Book();
            book.setType("测试数据123");
            book.setName("测试数据123");
            book.setDescription("测试数据123");
            bookDao.insert(book);
        }
    
        @Test
        void testUpdate() {
            Book book = new Book();
            book.setId(13);
            book.setType("测试数据asfd");
            book.setName("测试数据123");
            book.setDescription("测试数据123");
            bookDao.updateById(book);
        }
    
        @Test
        void testDelete() {
            bookDao.deleteById(13);
        }
    
        @Test
        void testGetAll() {
            System.out.println(bookDao.selectList(null));
        }
    
        @Test
        void testGetPage() {
        }
    
        @Test
        void testGetBy() {
        }
    }
    
    
    • 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

    小结:

    1. 手工导入starter坐标(2个)
    2. 配置数据源与MyBatisPlus对应的配置
    3. 开发Dao接口(继承BaseMapper)
    4. 制作测试类测试Dao功能是否有效

    33-开启MP运行日志

    • 为方便调试可以开启MyBatisPlus的日志
    # mybatis-plus
    mybatis-plus:
      global-config:
        db-config:
          table-prefix: tbl_
          id-type: auto # 主键策略
      configuration:
        # 开启MyBatisPlus的日志
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    小结:

    1. 使用配置方式开启日志,设置日志输出方式为标准输出

    34-分页

    • 分页操作需要设定分页对象IPage
        @Test
        void testGetPage() {
            IPage page = new Page(1, 5);
            bookDao.selectPage(page, null);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • IPage对象中封装了分页操作中的所有数据

      • 数据
      • 当前页码值
      • 每页数据总量
      • 最大页码值
      • 数据总量
    • 分页操作是在MyBatisPlus的常规操作基础上增强得到,内部是动态的拼写SQL语句,因此需要增强对应的功能,

    • 使用MyBatisPlus拦截器实现

    @Configuration
    public class MybatisPlusConfig {
    
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor() {
            //1. 定义 Mp 拦截器
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            //2. 添加具体的拦截器 分页拦截器
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
            return interceptor;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 测试
        @Test
        void testGetPage() {
            IPage page = new Page(1, 5);
            bookDao.selectPage(page, null);
            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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LyKojA7X-1662949981916)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298850.png)]

    小结:

    1. 使用IPage封装分页数据
    2. 分页操作依赖MyBatisPlus分页拦截器实现功能
    3. 借助MyBatisPlus日志查阅执行SQL语句

    35-数据层标准开发(条件查询)

    • 使用QueryWrapper对象封装查询条件,推荐使用LambdaQueryWrapper对象,所有查询操作封装成方法调用
        @Test
        void testGetBy2() {
            LambdaQueryWrapper<Book> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.like(Book::getName, "Spring");
            bookDao.selectList(lambdaQueryWrapper);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
        @Test
        void testGetBy() {
            QueryWrapper<Book> queryWrapper = new QueryWrapper<>();
            queryWrapper.like("name", "Spring");
            bookDao.selectList(queryWrapper);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 支持动态拼写查询条件
        @Test
        void testGetBy2() {
            String name = "1";
            LambdaQueryWrapper<Book> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            //if (name != null) lambdaQueryWrapper.like(Book::getName,name);
            lambdaQueryWrapper.like(Strings.isNotEmpty(name), Book::getName, name);
            bookDao.selectList(lambdaQueryWrapper);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    小结:

    1. 使用QueryWrapper对象封装查询条件
    2. 推荐使用LambdaQueryWrapper对象
    3. 所有查询操作封装成方法调用
    4. 查询条件支持动态条件拼装

    36-业务层标准开发(基础CRUD)

    • Service层接口定义与数据层接口定义具有较大区别,不要混用
      selectByUserNameAndPassword(String username,String password); 数据层接口
      login(String username,String password); Service层接口

    • 接口定义

    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(int currentPage,int pageSize);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 实现类定义
    @Service
    public class BookServiceImpl implements BookService {
    
        @Autowired
        private BookDao bookDao;
    
        @Override
        public Boolean save(Book book) {
            return bookDao.insert(book) > 0;
        }
    
        @Override
        public Boolean update(Book book) {
            return bookDao.updateById(book) > 0;
        }
    
        @Override
        public Boolean delete(Integer id) {
            return bookDao.deleteById(id) > 0;
        }
    
        @Override
        public Book getById(Integer id) {
            return bookDao.selectById(id);
        }
    
        @Override
        public List<Book> getAll() {
            return bookDao.selectList(null);
        }
    
        @Override
        public IPage<Book> getPage(int currentPage, int pageSize) {
            IPage page = new Page(currentPage, pageSize);
            bookDao.selectPage(page, null);
            return page;
        }
    }
    
    • 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
    • 测试类定义
    @SpringBootTest
    public class BookServiceTestCase {
    
        @Autowired
        private BookService bookService;
    
        @Test
        void testGetById() {
            System.out.println(bookService.getById(4));
        }
    
        @Test
        void testSave() {
            Book book = new Book();
            book.setType("测试数据123");
            book.setName("测试数据123");
            book.setDescription("测试数据123");
            bookService.save(book);
        }
    
        @Test
        void testUpdate() {
            Book book = new Book();
            book.setId(14);
            book.setType("测试数据asfd");
            book.setName("测试数据123");
            book.setDescription("测试数据123");
            bookService.update(book);
        }
    
        @Test
        void testDelete() {
            bookService.delete(14);
        }
    
        @Test
        void testGetAll() {
            System.out.println(bookService.getAll());
        }
    
        @Test
        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());
        }
    }
    
    
    • 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

    小结:

    1. Service接口名称定义成业务名称,并与Dao接口名称进行区分
    2. 制作测试类测试Service功能是否有效

    37-业务层快速开发(基于MyBatisPlus构建)

    • 快速开发方案
      使用MyBatisPlus提供有业务层通用接口(ISerivce)与业务层通用实现类(ServiceImpl
      在通用类基础上做功能重载或功能追加
      注意重载时不要覆盖原始操作,避免原始提供的功能丢失
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PY19yZJx-1662949981916)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298852.png)]

    • 接口定义

    public interface IBookService extends IService<Book> {
    }
    
    • 1
    • 2
    • 接口追加功能
    public interface IBookService extends IService<Book> {
    
        // 追加的操作与原始操作通过名称区分,功能类似
        Boolean delete(Integer id);
    
        Boolean insert(Book book);
    
        Boolean modify(Book book);
    
        Book get(Integer id);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sU24WfRP-1662949981917)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298853.png)]

    • 实现类定义
    @Service
    public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements IBookService {
    }
    
    • 1
    • 2
    • 3
    • 实现类追加功能
    @Service
    public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements IBookService {
    
        @Autowired
        private BookDao bookDao;
    
        public Boolean insert(Book book) {
            return bookDao.insert(book) > 0;
        }
    
        public Boolean modify(Book book) {
            return bookDao.updateById(book) > 0;
        }
    
        public Boolean delete(Integer id) {
            return bookDao.deleteById(id) > 0;
        }
    
        public Book get(Integer id) {
            return bookDao.selectById(id);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 测试类定义
    @SpringBootTest
    public class BookServiceTest {
    
        @Autowired
        private IBookService bookService;
    
        @Test
        void testGetById() {
            System.out.println(bookService.getById(4));
        }
    
        @Test
        void testSave() {
            Book book = new Book();
            book.setType("测试数据123");
            book.setName("测试数据123");
            book.setDescription("测试数据123");
            bookService.save(book);
        }
    
        @Test
        void testUpdate() {
            Book book = new Book();
            book.setId(14);
            book.setType("===========");
            book.setName("测试数据123");
            book.setDescription("测试数据123");
            bookService.updateById(book);
        }
    
        @Test
        void testDelete() {
            bookService.removeById(14);
        }
    
        @Test
        void testGetAll() {
            System.out.println(bookService.list());
        }
    
        @Test
        void testGetPage() {
            IPage<Book> page = new Page<>(2, 5);
            bookService.page(page);
            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
    • 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

    小结:

    1. 使用通用接口(ISerivce)快速开发Service
    2. 使用通用实现类(ServiceImpl)快速开发ServiceImpl
    3. 可以在通用接口基础上做功能重载或功能追加
    4. 注意重载时不要覆盖原始操作,避免原始提供的功能丢失

    38-表现层标准开发

    • 基于Restful进行表现层接口开发
    • 使用Postman测试表现层接口功能

    表现层开发

    @RestController
    @RequestMapping("/books")
    public class BookController {
    
        @Autowired
        private IBookService bookService;
    
        @GetMapping
        public List<Book> getAll() {
            return bookService.list();
        }
    
        @PostMapping
        public Boolean save(@RequestBody Book book) {
            return bookService.save(book);
        }
    
        @PutMapping
        public Boolean update(@RequestBody Book book) {
            return bookService.modify(book);
        }
    
        @DeleteMapping("{id}")
        public Boolean delete(@PathVariable Integer id) {
            return bookService.delete(id);
        }
    
        @GetMapping("{id}")
        public Book getById(@PathVariable Integer id) {
            return bookService.getById(id);
        }
    
        @GetMapping("{currentPage}/{pageSize}")
        public IPage<Book> getPage(@PathVariable Integer currentPage, @PathVariable int pageSize) {
            return bookService.getPage(currentPage, pageSize);
        }
    
    }
    
    
    • 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

    添加 分页的业务层方法

    IBookService

     IPage<Book> getPage(int currentPage,int pageSize);
    
    • 1

    BookServiceImpl

        @Override
        public IPage<Book> getPage(int currentPage, int pageSize) {
    
            IPage page = new Page(currentPage, pageSize);
            bookDao.selectPage(page, null);
    
            return page;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    功能测试
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9j6l9xFd-1662949981917)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298854.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fJM8DSaF-1662949981917)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298855.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vunr7BCS-1662949981917)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298856.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SLJMejFI-1662949981918)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298857.png)]

    小结:

    1. 基于Restful制作表现层接口
      新增:POST
      删除:DELETE
      修改:PUT
      查询:GET
    2. 接收参数
      实体数据:@RequestBody
      路径变量:@PathVariable

    39-表现层数据一致性处理(R对象)

    • 之前的格式
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YIN1Eqrt-1662949981918)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298958.png)]

    • 增加一个 data 属性,把数据全部封装到 data 里
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ct49u2He-1662949981918)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298959.png)]

      当数据为 null 可能出现的问题

      • 查询id不存在的数据,返回 null
      • 查询过程中抛出异常,catch 中返回 null
    • 增加 一个状态属性
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cwYhGxl9-1662949981919)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298960.png)]

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

    @Data
    public class R {
        private Boolean flag;
        private Object data;
    
        public R() {
        }
    
        /**
         * 不返回数据的构造方法
         *
         * @param flag
         */
        public R(Boolean flag) {
            this.flag = flag;
        }
    
        /**
         * 返回数据的构造方法
         *
         * @param flag
         * @param data
         */
        public R(Boolean flag, Object data) {
            this.flag = flag;
            this.data = data;
        }
    }
    
    • 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
    • 表现层接口统一返回值类型结果
    @RestController
    @RequestMapping("/books")
    public class BookController {
    
        @Autowired
        private IBookService bookService;
    
        @GetMapping
        public R getAll() {
            return new R(true, bookService.list());
        }
    
        @PostMapping
        public R save(@RequestBody Book book) {
            return new R(bookService.save(book));
    
        }
    
        @PutMapping
        public R update(@RequestBody Book book) {
            return new R(bookService.modify(book));
        }
    
        @DeleteMapping("{id}")
        public R delete(@PathVariable Integer id) {
            return new R(bookService.delete(id));
        }
    
        @GetMapping("{id}")
        public R getById(@PathVariable Integer id) {
            return new R(true, bookService.getById(id));
        }
    
        @GetMapping("{currentPage}/{pageSize}")
        public R getPage(@PathVariable Integer currentPage, @PathVariable int pageSize) {
            return new R(true, bookService.getPage(currentPage, pageSize));
        }
    
    }
    
    • 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

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7YSEOSoW-1662949981919)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342298961.png)]

    小结:

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

    40-前后端调用(axios发送异步请求)

    使用VUE的方法时提示报错:

    Method definition shorthands are not supported by current JavaScript version

    表示:该方法定义的缺陷是不支持当前的JavaScript版本,虽然可以程序可以正常运行,但是这个方法会出现红色的波浪线,很不爽

    解决:
    打开 File -> Settings -> Languages & Frameworks -> Javascript
    把JavaScript版本为ECMAScript 6就可以了

    • 前后端分离结构设计中页面归属前端服务器
    • 单体工程中页面放置在resources目录下的static目录中(建议执行clean)
    • 前端发送异步请求,调用后端接口
            //钩子函数,VUE对象初始化完成后自动执行
            created() {
                //调用查询全部数据的操作
                this.getAll();
            },
    
    • 1
    • 2
    • 3
    • 4
    • 5
                //列表
                getAll() {
                    //发送异步请求
                    axios.get("/books").then((res)=>{
                        console.log(res.data);
                    })
                },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0svuelDh-1662949981919)(../../../Pictures/SpringBoot/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5pqX5oGL6Iqx6aaZ,size_20,color_FFFFFF,t_70,g_se,x_16-166220342299062.png)]

    小结:

    1. 单体项目中页面放置在resources/static目录下
    2. created钩子函数用于初始化页面时发起调用
    3. 页面使用axios发送异步请求获取数据后确认前后端是否联通

    41-列表功能

    • 列表页
        //列表
        getAll() {
            //发送异步请求
            axios.get("/books").then((res) => {
                //console.log(res.data);
                this.dataList = res.data.data;
            })
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    小结:

    1. 将查询数据返回到页面,利用前端数据双向绑定进行数据展示

    42-添加功能

    • 弹出添加窗口
    // 弹出添加窗口
    handleCreate() {
    	this.dialogFormVisible = true;
    },
    
    • 1
    • 2
    • 3
    • 4
    • 清除数据
       //重置表单
       resetForm() {
           this.formData = {};
       },
    
    • 1
    • 2
    • 3
    • 4
    • 在弹出添加窗口时 清除数据
      //弹出添加窗口
      handleCreate() {
          this.dialogFormVisible = true;
          this.resetForm();
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 发送添加请求
       //添加
       handleAdd() {
           axios.post("/books", this.formData).then((res) => {
               //判断当前操作是否成功
               if (res.data.flag) {
                   //1.关闭弹层
                   this.dialogFormVisible = false;
                   this.$message.success("添加成功");
               } else {
                   this.$message.error("添加失败");
               }
           }).finally(() => {
               //2.重新加载数据
               this.getAll();
           })
       },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 取消添加
      //取消
      cancel() {
          //1.关闭弹层
          this.dialogFormVisible = false;
          //2.提示用户
          this.$message.info("当前操作取消");
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    小结:

    1. 请求方式使用POST调用后台对应操作
    2. 添加操作结束后动态刷新页面加载数据
    3. 根据操作结果不同,显示对应的提示信息
    4. 弹出添加Div时清除表单数据

    43-删除功能

    • 删除
      // 删除
      handleDelete(row) {
          axios.delete("/books/" + row.id).then((res) => {
              if (res.data.flag) {
                  this.$message.success("删除成功");
              } else {
                  this.$message.error("删除失败");
              }
          }).finally(() => {
              this.getAll();
          });
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 加入确认删除对话框
       // 删除
       handleDelete(row) {
           //1. 弹出提示框
           this.$confirm("些操作永久删除当前信息,是否继续?", "提示", {type: "info"}).then(() => {
               //2. 做删除业务
               axios.delete("/books/" + row.id).then((res) => {
                   //判断当前操作是否成功
                   if (res.data.flag) {
                       this.$message.success("删除成功");
                   } else {
                       this.$message.error("删除失败");
                   }
               }).finally(() => {
                   //2.重新加载数据
                   this.getAll();
               })
           }).catch(() => {
               //3. 取消删除
               this.$message.info("取消操作");
           });
    
       },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    小结:

    1. 请求方式使用Delete调用后台对应操作
    2. 删除操作需要传递当前行数据对应的id值到后台
    3. 删除操作结束后动态刷新页面加载数据
    4. 根据操作结果不同,显示对应的提示信息
    5. 删除操作前弹出提示框避免误操作

    44修改功能(加载数据)

    • 弹出修改窗口
      //弹出编辑窗口
      handleUpdate(row) {
          axios.get("/books/" + row.id).then((res) => {
              if (res.data.flag && res.data.data != null) {
                  // 展示弹层,加载数据
                  this.dialogFormVisible4Edit = true;
                  this.formData = res.data.data;
              } else {
                  this.$message.error("数据同步失败,自动刷新");
              }
          }).finally(() => {
              //重新加载数据
              this.getAll();
          });
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 删除消息维护
       // 删除
       handleDelete(row) {
           //1. 弹出提示框
           this.$confirm("些操作永久删除当前信息,是否继续?", "提示", {type: "info"}).then(() => {
               //2. 做删除业务
               axios.delete("/books/" + row.id).then((res) => {
                   //判断当前操作是否成功
                   if (res.data.flag) {
                       this.$message.success("删除成功");
                   } else {
                       this.$message.error("数据同步失败,自动刷新");
                   }
               }).finally(() => {
                   //2.重新加载数据
                   this.getAll();
               });
           }).catch(() => {
               //3. 取消删除
               this.$message.info("取消操作");
           });
    
       },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    小结:

    1. 加载要修改数据通过传递当前行数据对应的id值到后台查询数据
    2. 利用前端数据双向绑定将查询到的数据进行回显

    45-修改功能

    • 修改
      //修改
      handleEdit() {
          axios.put("/books", this.formData).then((res) => {
              //判断当前操作是否成功
              if (res.data.flag) {
                  //1.关闭弹层
                  this.dialogFormVisible4Edit = false;
                  this.$message.success("修改成功");
              } else {
                  this.$message.error("修改失败");
              }
          }).finally(() => {
              //2.重新加载数据
              this.getAll();
          });
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 取消添加和修改
      //取消
      cancel() {
          //1.关闭弹层
          this.dialogFormVisible = false;
          this.dialogFormVisible4Edit = false;
          //2.提示用户
          this.$message.info("当前操作取消");
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    小结:

    1. 请求方式使用PUT调用后台对应操作
    2. 修改操作结束后动态刷新页面加载数据(同新增)
    3. 根据操作结果不同,显示对应的提示信息(同新增)

    46-异常消息处理

    • 业务操作成功或失败返回数据格式
    {
        "flag": true,
        "data": null
    }
    
    {
        "flag": false,
        "data": null
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 后台代码BUG导致数据格式不统一性
    {
        "timestamp": "2021-11-07T12:44:29.343+00:00",
        "status": 500,
        "error": "Internal Server Error",
        "path": "/books"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 对异常进行统一处理,出现异常后,返回指定信息
    @RestControllerAdvice
    public class ProjectExceptionAdvice {
    
        //拦截所有的异常信息
        @ExceptionHandler(Exception.class)
        public R doException(Exception ex) {
            // 记录日志
            // 发送消息给运维
            // 发送邮件给开发人员 ,ex 对象发送给开发人员
            ex.printStackTrace();
            return new R(false, null, "系统错误,请稍后再试!");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 修改表现层返回结果的模型类,封装出现异常后对应的信息
      flag:false
      Data: null
      消息(msg): 要显示信息
    @Data
    public class R{
    	private Boolean flag;
    	private Object data;
    	private String msg;
    	public R(Boolean flag,Object data,String msg){
    		this.flag = flag;
    		this.data = data;
    		this.msg = msg;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 页面消息处理,没有传递消息加载默认消息,传递消息后加载指定消息
      //添加
      handleAdd() {
          axios.post("/books", this.formData).then((res) => {
              //判断当前操作是否成功
              if (res.data.flag) {
                  //1.关闭弹层
                  this.dialogFormVisible = false;
                  this.$message.success("添加成功");
              } else {
                  this.$message.error(res.data.msg);
              }
          }).finally(() => {
              //2.重新加载数据
              this.getAll();
          })
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 可以在表现层Controller中进行消息统一处理
        @PostMapping
        public R save(@RequestBody Book book) throws IOException {
    		//if (book.getName().equals("123")) throw new IOException();
            boolean flag = bookService.save(book);
            return new R(flag, flag ? "添加成功^_^" : "添加失败-_-!");
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 页面消息处理
      //添加
      handleAdd() {
          axios.post("/books", this.formData).then((res) => {
              //判断当前操作是否成功
              if (res.data.flag) {
                  //1.关闭弹层
                  this.dialogFormVisible = false;
                  this.$message.success(res.data.msg);
              } else {
                  this.$message.error(res.data.msg);
              }
          }).finally(() => {
              //2.重新加载数据
              this.getAll();
          })
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    小结:

    1. 使用注解@RestControllerAdvice定义SpringMVC异常处理器用来处理异常的
    2. 异常处理器必须被扫描加载,否则无法生效
    3. 表现层返回结果的模型类中添加消息属性用来传递消息到页面

    47-分页

    • 页面使用 el 分页组件添加分页功能
      
      <div class="pagination-container">
    
          <el-pagination
                  class="pagiantion"
    
                  @current-change="handleCurrentChange"
    
                  :current-page="pagination.currentPage"
    
                  :page-size="pagination.pageSize"
    
                  layout="total, prev, pager, next, jumper"
    
                  :total="pagination.total">
    
          el-pagination>
    
      div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 定义分页组件需要使用的数据并将数据绑定到分页组件
    data: {
        pagination: { // 分页相关模型数据
            currentPage: 1, // 当前页码
            pageSize: 10,	// 每页显示的记录数
            total: 0,		// 总记录数
        }
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 替换查询全部功能为分页功能
    getAll() {
        axios.get("/books/" + this.pagination.currentPage + "/" + this.pagination.pageSize).then((res) => {});
    },
    
    • 1
    • 2
    • 3
    • 分页查询
      使用路径参数传递分页数据或封装对象传递数据
        @GetMapping("{currentPage}/{pageSize}")
        public R getPage(@PathVariable Integer currentPage, @PathVariable int pageSize) {
            return new R(true, bookService.getPage(currentPage, pageSize));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 加载分页数据
         //分页查询
         getAll() {
             //发送异步请求
             axios.get("/books/" + this.pagination.currentPage + "/" + this.pagination.pageSize).then((res) => {
                 //console.log(res.data);
                 this.pagination.currentPage = res.data.data.current;
                 this.pagination.pageSize = res.data.data.size;
                 this.pagination.total = res.data.data.total;
    
                 this.dataList = res.data.data.records;
             })
         },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 分页页码值切换
       //切换页码
       handleCurrentChange(currentPage) {
           //修改页码值为当前选中的页码值
           this.pagination.currentPage = currentPage;
           //执行查询
           this.getAll();
       },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    小结:

    1. 使用el分页组件
    2. 定义分页组件绑定的数据模型
    3. 异步调用获取分页数据
    4. 分页数据页面回显

    48-分页功能维护(删除BUG)

    • 对查询结果进行校验,如果当前页码值大于最大页码值,使用最大页码值作为当前页码值重新查询
        @GetMapping("{currentPage}/{pageSize}")
        public R getPage(@PathVariable Integer currentPage, @PathVariable int pageSize) {
            IPage<Book> page = bookService.getPage(currentPage, pageSize);
            // 如果当前页码值大于了总页码值,那么重新执行查询操作,使用最大页码值作为当前页码值
            if (currentPage > page.getPages()) {
                page = bookService.getPage((int) page.getPages(), pageSize);
            }
            return new R(true, page);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    小结:

    1. 基于业务需求维护删除功能

    49-条件查询

    • 查询条件数据封装
      单独封装
      与分页操作混合封装
       pagination: {//分页相关模型数据
           currentPage: 1,//当前页码
           pageSize: 10,//每页显示的记录数
           total: 0,//总记录数
           type: "",
           name: "",
           description: ""
       }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 页面数据模型绑定
    <div class="filter-container">
        <el-input placeholder="图书类别" v-model="pagination.type" class="filter-item" />
        <el-input placeholder="图书名称" v-model="pagination.name" class="filter-item" />
        <el-input placeholder="图书描述" v-model="pagination.description" class="filter-item" />
        <el-button @click="getAll()" class="dalfBut">查询el-button>
        <el-button type="primary" class="butT" @click="handleCreate()">新建el-button>
    div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 组织数据成为get请求发送的数据
       //分页查询
       getAll() {
           console.log(this.pagination.type);
    
           //  /books/1/10?type=???&name=???&decription=?? ;
           //1. 获取查询条件 , 拼接查询条件
           param = "?name=" + this.pagination.name;
           param += "&type=" + this.pagination.type;
           param += "&description=" + this.pagination.description;
           //console.log("-----------------" + param);
    
           //发送异步请求
           axios.get("/books/" + this.pagination.currentPage + "/" + this.pagination.pageSize + param).then((res) => {
               //console.log(res.data);
               this.pagination.currentPage = res.data.data.current;
               this.pagination.pageSize = res.data.data.size;
               this.pagination.total = res.data.data.total;
    
               this.dataList = res.data.data.records;
           })
       },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 条件参数组织可以通过条件判定书写的更简洁
    • Controller接收参数
    @GetMapping("{currentPage}/{pageSize}")
    public R getAll(@PathVariable int currentPage,@PathVariable int pageSize,Book book) {
    	System.out.println("参数=====>"+book);
    	IPage<Book> pageBook = bookService.getPage(currentPage,pageSize);
    	return new R(null != pageBook ,pageBook);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 业务层接口功能开发
         /**
       * 分页的条件查询
       *
       * @param currentPage
       * @param pageSize
       * @param book
       * @return
       */
      IPage<Book> getPage(Integer currentPage, int pageSize, Book book);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 业务层接口实现类功能开发
        @Override
        public IPage<Book> getPage(Integer currentPage, int pageSize, Book book) {
    
            LambdaQueryWrapper<Book> lambdaQueryWrapper = new LambdaQueryWrapper<>();
    
            lambdaQueryWrapper.like(Strings.isNotEmpty(book.getType()), Book::getType, book.getType());
            lambdaQueryWrapper.like(Strings.isNotEmpty(book.getName()), Book::getName, book.getName());
            lambdaQueryWrapper.like(Strings.isNotEmpty(book.getDescription()), Book::getDescription, book.getDescription());
    
            IPage page = new Page(currentPage, pageSize);
            bookDao.selectPage(page, lambdaQueryWrapper);
    
            return page;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • Controller调用业务层分页条件查询接口
        @GetMapping("{currentPage}/{pageSize}")
        public R getPage(@PathVariable Integer currentPage, @PathVariable int pageSize, Book book) {
    
            // System.out.println("book=>" + book);
    
            IPage<Book> page = bookService.getPage(currentPage, pageSize, book);
            // 如果当前页码值大于了总页码值,那么重新执行查询操作,使用最大页码值作为当前页码值
            if (currentPage > page.getPages()) {
                page = bookService.getPage((int) page.getPages(), pageSize, book);
            }
            return new R(true, page);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 页面回显数据
       //分页查询
       getAll() {
           console.log(this.pagination.type);
    
           //  /books/1/10?type=???&name=???&decription=?? ;
           //1. 获取查询条件 , 拼接查询条件
           param = "?name=" + this.pagination.name;
           param += "&type=" + this.pagination.type;
           param += "&description=" + this.pagination.description;
           //console.log("-----------------" + param);
    
           //发送异步请求
           axios.get("/books/" + this.pagination.currentPage + "/" + this.pagination.pageSize + param).then((res) => {
               //console.log(res.data);
               this.pagination.currentPage = res.data.data.current;
               this.pagination.pageSize = res.data.data.size;
               this.pagination.total = res.data.data.total;
    
               this.dataList = res.data.data.records;
           })
       },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    小结:

    1. 定义查询条件数据模型(当前封装到分页数据模型中)
    2. 异步调用分页功能并通过请求参数传递数据到后台

    50-基础篇完结

    基于SpringBoot的SSMP整合案例

    1. pom.xml
      配置起步依赖
    2. application.yml
      设置数据源、端口、框架技术相关配置等
    3. dao
      继承BaseMapper、设置@Mapper
    4. dao测试类
    5. service
      调用数据层接口或MyBatis-Plus提供的接口快速开发
    6. service测试类
    7. controller
      基于Restful开发,使用Postman测试跑通功能
    8. 页面
      放置在resources目录下的static目录中

    总结:

    1. 整合JUint
    2. 整合MyBatis
    3. 整合MyBatis-Plus
    4. 整合Druid
    5. 基于SpringBoot的SSMP整合案例

    后续学习

    • 基础篇
      • 能够创建SpringBoot工程
      • 基于SpringBoot实现ssm/ssmp整合
    • 实用篇
      • 运维实用篇 Spring Boot 2 运维实用篇学习笔记
        • 能够掌握SpringBoot程序多环境开发
        • 能够基于Linux系统发布SpringBoot工程
        • 能够解决线上灵活配置SpringBoot工程的需求
      • 开发实用篇
        • 能够基于SpringBoot整合任意第三方技术
    • 原理篇
  • 相关阅读:
    小学生python编程----学爬虫
    【Python】爬虫时注意cookie的内容
    江苏数据中心是如何保证数据安全
    [python刷题模板] 0-1BFS
    彩色相机工作原理——bayer格式理解
    vue3在router中使用store报错解决方案
    linux常用命令
    自制一种简易无线温度和湿度监控器
    vue封装一个3D轮播图组件
    卷积神经网络入门
  • 原文地址:https://blog.csdn.net/m0_61163395/article/details/126814188