# SpringBootDemo **Repository Path**: cgrs572/spring-boot-demo ## Basic Information - **Project Name**: SpringBootDemo - **Description**: 完整示例 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-12-17 - **Last Updated**: 2024-12-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # SpringBoot - SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化Spring应用的初始搭建以及开发过程 - Spring程序与SpringBoot程序对比如下 ![image-20241215120522553](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215120522553.png) - Spring程序配置以及依赖设置繁琐 - SpringBoot程序自动配置,并简化了依赖配置(即具有起步依赖),除此之外还添加了辅助功能(比如内置了服务器) - 注意 - SpringBoot在创建项目时,采用的是jar包的方式 - SpringBoot的引导类是项目的入口,运行main方法即可启动项目 - 引导类名为`项目名+Application`,以快速入门为例,即`SpringBootDemoApplication` ## SpringBoot快速入门 - **并不是所有的IDE均可创建SpringBoot项目框架** - 基于idea开发SpringBoot程序需要确保联网且能够加载到程序框架结构 - 其它IDE开发SpringBoot程序需要进入SpringBoot官网来加载程序框架结构 ### idea创建方式 - **Step1:** ![image-20241215114525473](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215114525473.png) - **Step2:** 若创建的是Web项目的话则按下图步骤创建即可;反之则排除10、11两步即可 ![image-20241215113356330](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215113356330.png) - **Step3:** 创建完成后初始SpringBoot项目框架目录如图所示 ![image-20241215114559420](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215114559420.png) - **Step4:** 在at.guigu包下创建表现层controller包,并在该包下创建BookController类,代码如下 ```java package at.guigu.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/books") public class BookController { @GetMapping("/{id}") public String getById(@PathVariable(value = "id") Integer id) { System.out.println("id===>" + id); return "Hello SpringBoot!!!"; } } ``` - **Step5:** 运行SpringBoot的引导类`SpringBootDemoApplication`,该项目即可启动成功,如图所示 ![image-20241215115436926](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215115436926.png) ![image-20241215115909568](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215115909568.png) - **Step6:** 利用Postman测试 - 前端页面显示 ![image-20241215120101446](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215120101446.png) - idea控制台显示 ![image-20241215120147419](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215120147419.png) ### 其它ide创建方式 - **Step1:** 进入到[SpringBoot官网](https://spring.io/projects/spring-boot),选择`Quickstart Your Project`,如图所示 ![image-20241215121158028](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215121158028.png) - **Step2:** 若创建的是Web项目的话则按下图步骤创建即可;反之则排除8、9两步即可 ![image-20241215121744101](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215121744101.png) - **Step3:** 然后就会生成一个包含SpringBoot项目的压缩包,解压后Import导入项目即可(此步不在演示) ## SpringBoot项目快速启动 - SpringBoot可用于前后端分离合作开发 - 传统项目下后端人员做完项目后,前端人员若想使用则必须连后端人员的电脑才能使用,为解决这个弊端,SpringBoot可以将项目打包成jar包传给前端人员,且该jar包与后端人员连接同一个数据库,此时即可使项目不依赖Tomcat等环境运行 ![image-20241215122731833](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215122731833.png) - **Step1:** 执行Maven构建指令`package`来对SpringBoot项目进行打包 > 注意:在执行Maven构建指令`package`来对SpringBoot项目进行打包前,最好执行一下`clean`指令,以此来避免不必要的麻烦 ![image-20241215123137316](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215123137316.png) - **Step2:** 将jar包发给前端人员(此处在博主电脑上进行示例),然后在文件所在位置通过`cmd`打开命令窗口,输入指令`java -jar SpringBoot的jar包名.jar` - 注意:若通过命令窗口报错:`java.lang.UnsupportedClassVersionError: org/springframework/boot/loader/launch/JarLauncher has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 52.0`,说明你的jdk版本过低无法运行当前SpringBoot项目,则需要升级jdk版本,由于博主设置了jdk1.8和jdk21两个jdk版本,所以设置临时环境变量的步骤如下: - Step1:将jdk版本临时切换为jdk21:`set JAVA_HOME1=F:\app\jdk-21`,后为自己的jdk安装路径 - Step2:使用`set PATH=%JAVA_HOME1%\bin;%PATH%`指令让临时环境变量生效 - Step3:输入指令`java -jar SpringBoot的jar包名.jar` 运行SpringBoot项目的jar包即可,如图所示 ![image-20241215130648598](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215130648598.png) - **Step3:** 利用Postman测试 - 前端页面显示 ![image-20241215130811785](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215130811785.png) - 命令窗口显示 ![image-20241215130919597](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215130919597.png) - **注意** - 在执行Maven构建指令`package`来对SpringBoot项目进行打包前,最好执行一下`clean`指令,以此来避免不必要的麻烦 - jar包支持命令行启动需要依赖maven插件支持,所以在打包前需要确认SpringBoot项目的pom.xml文件中是否具有SpringBoot对应的maven插件,若不存在则添加即可,插件代码如下 ```xml org.springframework.boot spring-boot-maven-plugin ``` - 配置文件中若存在中文可能会打包失败,则解决步骤如下: - **Step1:** 将IDE编码格式均改为UTF-8 ![image-20241216201054264](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241216201054264.png) - **Step2:** 关闭配置文件,然后重新打开配置文件,看是否有乱码,若有则将乱码删除重新写一下即可。 ## pom.xml文件解析 > 快速入门中SpringBoot项目`SpringBootDemo`的pom.xml文件初始代码如下 ```xml 4.0.0 org.springframework.boot spring-boot-starter-parent 3.4.0 org.example SpringBootDemo 0.0.1-SNAPSHOT SpringBootDemo SpringBootDemo 21 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ``` - 该pom.xml文件中用到的关键词 - `starter`:SpringBoot中常见项目名称,定义了当前项目使用的所有项目坐标,以达到减少依赖配置的目的 - `parent`: - 所有SpringBoot项目要继承的项目,定义了若干个坐标版本号(依赖管理,而非依赖),以达到减少依赖冲突的目的 - spring-boot-starter-parent(2.5.0)与 spring-boot-starter-parent(2.4.6)共计57处坐标版本不同 - `SpringBootDemo`的pom.xml文件有聚合工程(即父工程),父工程名为`spring-boot-starter-parent`如下: ```xml org.springframework.boot spring-boot-starter-parent 3.4.0 ``` - `SpringBootDemo`的pom.xml文件中的依赖均为起步依赖(即需要什么就导入对应的起步依赖,起步依赖均有一个`starter`标志) - 若该项目为web工程(即做web开发),则导入web工程的起步依赖 - 若该项目需要测试,则导入测试的起步依赖 - 默认情况下SpringBoot项目的pom.xml文件在初始状态下就有以下两个起步依赖 ```xml org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test ``` - 注意 - 在实际开发中,自己SpringBoot项目的pom.xml文件中的依赖均来源于`spring-boot-dependencies`的pom.xml文件中所配置的可选依赖,这也就是为什么自己的pom.xml文件中存在的两个初始依赖不需要配置版本的原因 - 在实际开发中,用户需要什么,就导入对应的起步依赖即可,因为该依赖内部已配置好对应的内容,用户使用即可。这也就是为什么博主在快速入门中没有导入一些列Spring、SpringMvc以及Tomcat等坐标依赖还能成功运行原因 - 在实际开发中使用任意坐标时,仅书写GAV中的G和A,V由SpringBoot提供。若发生坐标错误,再指定version(要小心版本冲突) - Jetty相对于Tomcat来说更轻量级,可扩展性更强,且谷歌应用引擎(GAE)已经全面切换为Jetty,所以我们在创建SpringBoot项目时可自行在web项目的起步依赖中排除使用Tomcat依赖,转而使用Jetty依赖,步骤如下: - **Step1:** 利用``标签排除Tomcat依赖 ```xml org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-tomcat org.springframework.boot spring-boot-starter-test test ``` > 注意:若不知道Tomcat依赖的groupId和artifactId,则进入到`spring-boot-starter-web`的pom.xml文件中找,如图所示 ![image-20241215150443960](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215150443960.png) - **Step2:** 添加Jetty依赖 - 由于SpringBoot的聚合工程的聚合工程(即父工程的父工程)提供的可选依赖中存在该Jett依赖,所以添加时仅书写GAV中的G和A,而V由SpringBoot提供 ```xml org.springframework.boot spring-boot-starter-jetty ``` > 注意:若不知道Jetty依赖的groupId和artifactId,则进入到spring-boot-starter-web的pom.xml文件中找,如图所示 ![image-20241215151228379](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215151228379.png) - 此时快速入门中创建的SpringBoot项目的pom.xml文件完整代码如下 ```xml 4.0.0 org.springframework.boot spring-boot-starter-parent 3.4.0 org.example SpringBootDemo 0.0.1-SNAPSHOT SpringBootDemo SpringBootDemo 21 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-tomcat org.springframework.boot spring-boot-starter-jetty org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin ``` 成功运行后截图如下 ![image-20241215151638583](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215151638583.png) ### 聚合工程(即父工程)的pom文件 - `SpringBootDemo`的pom.xml文件有聚合工程(即父工程),父工程名为`spring-boot-starter-parent`,该父工程的pom.xml文件中主要有四部分内容: - `spring-boot-starter-parent`也存在聚合工程(父工程),即`spring-boot-dependencies` - 开启资源文件目录加载属性的过滤器 - 插件配置 - 多环境配置 ![image-20241215142143049](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215142143049.png) - `spring-boot-dependencies`的pom.xml文件中主要有三部分内容 - 多环境配置 - 可选依赖 - 自己所创建的SpringBoot项目的依赖都是来源于该工程下 - 插件配置 ![image-20241215142531976](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215142531976.png) - 注意:自己的初始pom.xml文件中对应的起步依赖就在该聚合工程`spring-boot-dependencies`的可选依赖中配置的。实际开发过程中,自己需要什么,就导入对应的起步依赖即可。这也就是为什么博主在快速入门中没有导入一些列Spring、SpringMvc以及Tomcat等坐标依赖还能成功运行原因 - SpringBoot的有些起步依赖为辅助功能,因为这些依赖并不是为程序员开发程序提供业务功能的,而是帮助启动的。比如博主的初始pom.xml中的web起步依赖,就是为了程序运行使用的,它就是一个辅助功能 # SpringBoot基础配置 > 以快速入门的SpringBoot项目为例 ## 配置文件格式 - SpringBoot提供了三种配置文件,分别为 - application.properties(默认) - application.yml(实际开发项目中主要用该格式的配置文件) - application.yaml - 若三种形式的配置文件均存在于项目中,则此时properties为主启动配置文件,yml为次配置文件,yaml为最次配置文件,即加载顺序优先级为`application.properties`>`application.yml`>`application.yaml` - 若三种格式的配置文件均存在于项目中且配置内容均一致,只有属性值不同,则优先级最高的生效,可详见SpringBoot多环境开发配置的快速入门部分内容 - 在以上三种配置文件中配置内容时SpringBoot均会给出提示 - 若配置文件未给出提示,则需要进行设置,步骤如图所示 ![image-20241215163627130](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215163627130.png) - 注意:若上图的Modules对应的SpringBoot项目下不存在Spring,则按下图所示步骤创建即可 ![image-20241215162640823](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215162640823.png) > 三种配置文件以修改服务器端口为例进行演示 > > SpringBoot默认服务器端口为8080,如快速入门`http://localhost:8080/books/1`,将其端口号改为80,即`http://localhost/books/1` - **方式一:** 打开源代码配置文件目录(即资源文件`resources`)下的`application.properties`文件,该文件初始代码如图所示 ![image-20241215155106135](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215155106135.png) - 添加端口配置,文件完整代码如下 ```properties spring.application.name=SpringBootDemo server.port=80 ``` - 此时运行后,后端控制台截图如下 ![image-20241215155413911](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215155413911.png) - **方式二:** 在源代码配置文件目录(即资源文件`resources`)下创建`application.yml`文件,完整代码如下 > 注意:yml文件中的参数前必须要有空格,否则配置不成功 ```yaml server: port: 81 ``` ![image-20241215155924508](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215155924508.png) - **方式三:** 在源代码配置文件目录(即资源文件`resources`)下创建`application.yaml`文件,完整代码如下 > 注意:yml文件中的参数前必须要有空格,否则配置不成功 ```yaml server: port: 82 ``` ![image-20241215160703397](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215160703397.png) ## yaml格式 - YAML(YAML Ain't Markup Language),一种数据序列化格式 - 优点: - 容易阅读 - 容易与脚本语言交互 - 以数据为核心,重数据轻格式 - YAML文件扩展名 - .yml(主流) - .yaml - yaml语法规则 - 大小写敏感 - 属性层级关系使用多行描述,每行结尾使用冒号`:`结束 - 比如我有个三级属性a.b.c=111,则除含属性值的属性外,前两级属性用`:`结束,代码表示如下: ```yaml a: b: c: 111 ``` - 假设我有两个三级属性a.b.c=111和a.b.d=222,则c和d同级,代码表示如下: ```yaml a: b: c: 111 d:222 ``` - 使用缩进表示层级关系,同层级左侧对齐,只允许使用空格(不允许使用`Tab`键) - 属性值前面添加空格(属性名与属性值之间使用`冒号+空格`作为分隔) - `#`表示注释 - 核心规则:**数据前面要加空格与冒号隔开** - **yaml数组数据:** 数组数据在数据书写位置的下方使用减号`-`作为数据开始符号,每行书写一个数据,减号与数据间空格分隔,代码表示如下: ```yaml a: b: c: 111 d: 222 array: - music - game ``` ## yaml数据读取 - yaml数据读取有三种方式 - 方式一:利用`@Value("${}")`读取 - 属性名引用方式:`${一级属性名.二级属性名……}` - 方式二:将数据全部封装到`Environment`对象 - 方式三:创建自定义的对象来封装数据(常用) - 使用该方式时可能会有自定义对象封装数据警告,则在自己的pom.xml文件中引入以下依赖即可解决 > 该依赖存在于聚合工程的聚合工程(即父工程的父工程)`spring-boot-dependencies`的pom.xml文件的可选依赖中,所以不需导入版本号 ```xml org.springframework.boot spring-boot-configuration-processor true ``` - 可能用到的接口及方法 | 接口 | 解释 | | ------------------------------------------------------------ | ------------------------------------------------------------ | | `Environment` | Spring 中的一个重要组件,用于处理和访问应用程序的**环境变量**和**配置属性** | | **`Environment`接口方法** | **解释** | | `String getProperty(String key)` | 用于获取指定属性的值,如果属性不存在返回 `null` | | `String getProperty(String key, String defaultValue)` | 用于获取指定属性的值,如果属性不存在返回 默认值 | | `String resolvePlaceholders(String text)` | 解析字符串中的占位符(`${}`)。如果占位符没有对应的值,会抛出异常。 | | `String resolveRequiredPlaceholders(String text)` | 解析字符串中的占位符(`${}`)。如果占位符没有对应的值,会抛出`IllegalArgumentException`异常 | | ` T getProperty(String key, Class targetType)` | 将指定的属性值转换为目标类型返回,如果属性不存在返回 `null` | | ` T getProperty(String key, Class targetType, T defaultValue)` | 将指定的属性值转换为目标类型返回,如果属性不存在返回 默认值 | | `boolean containsProperty(String key)` | 判断是否存在指定属性 | | `String[] getActiveProfiles()` | 获取当前激活的环境的 Profiles,通常用于区分开发、测试、生产环境 | | `String[] getDefaultProfiles()` | 获取默认环境的的 Profiles(当未激活任何 Profiles 时使用) | | `PropertySources getPropertySources()` | 返回所有属性源(`PropertySource` 的集合),可以获取详细的属性来源 | | **`Environment`接口的子接口** | **解释** | | `ConfigurableEnvironment` | | | **`ConfigurableEnvironment`方法** | **解释** | | `void addFirst(PropertySource propertySource)` | 将自定义的属性源添加到属性源集合的首位,优先级最高 | | `void addLast(PropertySource propertySource)` | 将自定义的属性源添加到属性源集合的末尾,优先级最低。 | - 可能用到的Spring的注解(Spring注解解释及示例可详见[Spring部分内容](https://blog.csdn.net/cgrs5572/article/details/144315543?spm=1001.2014.3001.5501)) | 注解 | 解释 | | ------------ | -------------------------- | | `@Value` | 注入普通属性 | | `@Component` | 使用在类上,用于实例化bean | - 可能用到的SpringBoot的注解 | 注解 | 解释 | | ---------------------------------- | ------------------------------------------------------------ | | `@ConfigurationProperties` | 用于将外部配置(如 `application.properties` 或 `application.yaml`)中的属性值映射到 Spring 管理的 Java Bean 中 | | **`@ConfigurationProperties`属性** | **解释** | | `prefix`或`value` | 用于指定配置文件中需要绑定的属性前缀。只有以该前缀开头的配置项会被绑定到对应的 Java 类中 | | `ignoreUnknownFields` | SpringBoot 是否会忽略配置文件中没有在 Java 类中定义的属性。默认为`true`;若为false,此时若存在没有在 Java 类中定义的属性则会报错 | | `ignoreInvalidFields` | 是否忽略类型不匹配的字段,默认为`true` | > `@ConfigurationProperties`注解**不能直接读取配置文件中所有属性的值**,是基于前缀绑定的注解,要求指定一个属性前缀(`prefix`)来将相关的配置项绑定到类的字段。 > > 也就是说该注解不能直接绑定整个配置文件中的所有属性,只能按指定的前缀绑定特定的部分。可详见第三种方式示例 - `prefix`或`value` - 该属性的属性值只能有一个,否则报错,详细示例可见第三种方式示例 - `ignoreUnknownFields`示例 ![image-20241216172921400](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241216172921400.png) - `ignoreInvalidFields`示例 ![image-20241216172954645](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241216172954645.png) > 以下代码示例只进行关键步骤演示,其余步骤可详见快速入门部分内容 - 两种方式公用的yaml配置文件代码内容如下 ```yaml server: port: 82 name: zhangsan a: b: c: 111 d: 222 arrayOne: - music - game e: arrayTwo: - 你好 - nihao ``` ### 前两种方式示例 - **yaml数据读取方式:** controller包下的`BookController`类代码更改如下: ```java package at.guigu.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/books") public class BookController { @Value("${name}") private String name; @Value("${a.b.c}") private Integer c; @Value("${a.b.arrayOne[0]}") private String arrOne; @Value("${e.arrayTwo[0]}") private String arrTwo; @GetMapping("/{id}") public String getById(@PathVariable(value = "id") Integer id) { System.out.println("id===>" + id); System.out.println("name===>" + name); System.out.println("c===>" + c); System.out.println("arrOne===>" + arrOne); System.out.println("arrTwo===>" + arrTwo); return "Hello SpringBoot!!!"; } } ``` 运行截图如下 ![image-20241215170425252](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215170425252.png) - **数据全部封装到Environment对象的方式**: 在controller包下创建`BookControllerTwo`类,代码如下: ```java package at.guigu.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/booksTwo") public class BookControllerTwo { @Autowired private Environment environment; @GetMapping("/{id}") public String getById(@PathVariable(value = "id") Integer id) { System.out.println("id===>" + id); System.out.println(environment.getProperty("name")); System.out.println(environment.getProperty("a.b.c")); System.out.println(environment.getProperty("a.b.arrayOne[0]")); System.out.println(environment.getProperty("e.arrayTwo[0]")); System.out.println("--------------------------------"); System.out.println(environment.resolvePlaceholders("d的属性值为:${a.b.d}")); System.out.println("--------------------------------"); System.out.println(environment.resolveRequiredPlaceholders("post的属性值为:${server.port}")); return "Hello SpringBoot!!!"; } } ``` 运行截图如下 ![image-20241215181748300](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241215181748300.png) ### 第三种方式示例(常用) - **Step1:** 在at.guigu包下创建pojo包,并在该包中创建`Enterprise`类,然后在该类中创建配置文件中对应的属性,代码如下: - **Step1-1:** 用`@Component`修饰该类 - **Step1-2:** 利用`@ConfigurationProperties`注解的`prefix`属性指定一个属性前缀来将相关的配置项对应的属性值绑定到类的字段。 > **注意:该类中的字段名要与配置文件中对应前缀的属性名称一致,否之无法获取到对应的属性值** ```java package at.guigu.pojo; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.Arrays; @Component @ConfigurationProperties(prefix = "a.b") public class Enterprise { private int c; private int d; private String[] arrayOne; public int getC() { return c; } public void setC(int c) { this.c = c; } public int getD() { return d; } public void setD(int d) { this.d = d; } public String[] getArrayOne() { return arrayOne; } public void setArrayOne(String[] arrayOne) { this.arrayOne = arrayOne; } @Override public String toString() { return "Enterprise{" + "c=" + c + ", d=" + d + ", arrayOne=" + Arrays.toString(arrayOne) + '}'; } } ``` - **Step2:** 在controller包下创建`BookControllerThree`类,代码如下: - **Step2-1:** 在该类中利用`@Autowired`自动依赖注入一个私有的`Enterprise`对象 ```java ``` ![image-20241216183913252](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241216183913252.png) # SpringBoot多环境开发配置 - SpringBoot提供多种环境设定(即:生产环境、开发环境、测试环境)如图所示,可帮助开发者快速切换环境 ![image-20241216185746670](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241216185746670.png) ## 快速入门 > 本项目`SpringBootDemoTwo`已上传至Gitee,可自行下载。具体搭建步骤可详见SpringBoot快速入门,此处只进行关键步骤示例。该项目已上传至GItee,可自行下载 - 配置文件格式有三种,properties格式的配置文件进行多环境开发配置与另外两种不同,此处均会进行详细示例 ### yml及yaml格式的配置文件 - **Step1:** 在源代码配置文件目录(即资源文件`resources`)下创建配置文件`application.yml`,代码如下: > `---` 是 YAML 格式的多文档分隔符,用于区分不同环境的配置 ```yaml # 设置启动的环境---假设现在启用生产环境pro spring: profiles: active: pro --- # 生产环境 server: port: 81 spring: profiles: pro --- # 开发环境 server: port: 82 spring: profiles: dev --- # 测试环境 server: port: 83 spring: profiles: test ``` - 注意:若SpringBoot版本过高则`spring.profiles`会被标记无效,且运行会报错,如图所示 ![image-20241216191958973](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241216191958973.png) - 此时配置文件`application.yml`,代码更改如下 ```yaml # 设置启动的环境---假设现在启用生产环境pro spring: profiles: active: pro --- # 生产环境 server: port: 81 spring: config: activate: on-profile: pro --- # 开发环境 server: port: 82 spring: config: activate: on-profile: dev --- # 测试环境 server: port: 83 spring: config: activate: on-profile: test ``` - **Step2:** 运行SpringBoot的引导类`SpringBootDemoTwoApplication`,截图如下 ![image-20241216192310402](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241216192310402.png) ### properties格式的配置文件 - **Step1:** 在源代码配置文件目录(即资源文件`resources`)下创建配置文件`application-pro.properties`,代码如下 ```properties spring.application.name=SpringBootDemoTwo # 设置生产环境的端口号 server.port=85 ``` - **Step2:** 在源代码配置文件目录(即资源文件`resources`)下创建配置文件`application-dev.properties`,代码如下 ```properties spring.application.name=SpringBootDemoTwo # 设置开发环境的端口号 server.port=86 ``` - **Step3:** 在源代码配置文件目录(即资源文件`resources`)下创建配置文件`application-test.properties`,代码如下 ```properties spring.application.name=SpringBootDemoTwo # 设置测试环境的端口号 server.port=87 ``` - **Step4:** 在源代码配置文件目录(即资源文件`resources`)下的配置文件`application.properties`中写入要启用的环境配置对应的配置文件名`-`后的内容,代码如下: > 以生产环境为例,由于生产环境对应的配置文件名为`application-pro.properties`,所以`spring.profiles.active=pro` > > 若想启用其它环境,只需更改该配置文件`spring.profiles.active`的属性值即可 ```properties spring.application.name=SpringBootDemoTwo # 设置启用的环境---此处以生产环境为例 spring.profiles.active=pro ``` 运行SpringBoot的引导类`SpringBootDemoTwoApplication`,截图如下 ![image-20241216193909858](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241216193909858.png) - 注意: - 若三种格式的配置文件均存在于项目中且配置内容均一致,则在以上三种配置文件示例中由于properties格式的配置文件优先级最高,所以生产环境、开发环境以及测试环境的端口号就会以properties格式的配置文件为准,也就是说这三种配置文件均存在且配置的内容一样时,properties格式的配置文件生效,而其它两种格式的配置文件失效,如上图所示 ## 多环境命令行启动参数设置 - 注意 > 本示例以SpringBoot多环境开发配置的快速入门为基准,由于该项目现在有多个配置文件,如图一所示,所以博主会将properties格式的三种环境配置文件备份放到bak文件夹下,以免影响后续操作,如图二所示 > > 注意:此时`application.properties`会由于找不到三种环境配置文件导致多环境开发配置失效,转而使application.yml中对多环境开发的配置生效,如图三所示 ![image-20241216195746559](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241216195746559.png) ![image-20241216200403362](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241216200403362.png) - 多环境命令行启动的指令格式 - `java -jar SpringBoot的jar包名.jar`:启动对应的SpringBoot项目 - `java -jar SpringBoot的jar包名.jar --server.port=自定义的端口号`:启动对应的SpringBoot项目并将端口号自定义为自己想用的端口号 - `java -jar SpringBoot的jar包名.jar --spring.profiles.active=想要切换的环境`:启动对应的SpringBoot项目并切换环境(即生产、开发、测试) - `java -jar SpringBoot的jar包名.jar --server.port=自定义的端口号 --spring.profiles.active=想要切换的环境`:启动对应的SpringBoot项目并切换环境(即生产、开发、测试),同时将端口号自定义为自己想用的端口号 > 后端开发人员在开发过程中的环境为开发环境,当后端人员开发完成后将SprootBoot项目打包成jar包发送给测试人员后,测试人员发现由于jar包中的环境为开发环境导致无法测试并且后端人员使用的端口号均与自己的冲突,则此时就用到了多环境命令行启动参数设置来将其改为测试环境并修改端口号 ### 多环境切换 - **Step1:** 将该项执行Maven构建指令`package`来对SpringBoot项目`SpringBootDemoTwo`打包 > 注意:在执行Maven构建指令`package`来对SpringBoot项目进行打包前,最好执行一下`clean`指令,以此来避免不必要的麻烦 ![image-20241216200750582](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241216200750582.png) - **Step2:** 将jar包发给前端人员(此处在博主电脑上进行示例),然后在文件所在位置通过`cmd`打开命令窗口,输入指令`java -jar SpringBoot的jar包名.jar` 等运行成功后查看当前端口号,以此来判断是否是测试环境 - 注意:若通过命令窗口报错:`java.lang.UnsupportedClassVersionError: org/springframework/boot/loader/launch/JarLauncher has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 52.0`,说明你的jdk版本过低无法运行当前SpringBoot项目,则需要升级jdk版本,由于博主设置了jdk1.8和jdk21两个jdk版本,所以设置临时环境变量的步骤如下: - Step1:将jdk版本临时切换为jdk21:`set JAVA_HOME1=F:\app\jdk-21`,后为自己的jdk安装路径 - Step2:使用`set PATH=%JAVA_HOME1%\bin;%PATH%`指令让临时环境变量生效 - Step3:输入指令`java -jar SpringBoot的jar包名.jar` 运行SpringBoot项目的jar包即可,如图所示,此时端口号为81,所以后端开发人员发送的jar包为开发环境 ![image-20241216202050025](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241216202050025.png) - **Step3:** 在命令窗口界面`ctrl+c`停止项目运行,然后输入指令`java -jar SpringBoot的jar包名.jar --server.port=自定义的端口号 --spring.profiles.active=想要切换的环境` ,如图所示 ![image-20241216203454443](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241216203454443.png) - **Step4:** 再次运行后可看出已将jar包切换到测试环境,并且测试环境的端口号由原来的83变更为了100,如图所示 ![image-20241216203704179](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241216203704179.png) ## Maven与SpringBoot的多环境开发兼容性问题 > 问题引入:假设现在在Maven的pom.xml文件以及SpringBoot的配置文件中均配置了多环境开发,且Maven中以开发环境为主,SpringBoot以测试环境为主,则项目启动时是以哪个为主呢? - 由于命令行启动时是通过Maven的指令`package`将SpringBoot项目打包成一个jar包,然后通过命令窗口来启动,所以最终会以Maven的环境为主,所以在两者均配置了多环境时,会以Maven为主,SpringBoot为辅。 ### 快速入门 > 本快速入门以`多环境命令行启动参数设置`的项目示例为基准,只进行关键步骤的演示 > 题目:在Maven中配置多环境,然后通过SpringBoot的配置文件来获取当前启动的环境并在SpringBoot的配置文件中来设置对应的端口号 - **Step1:** 在pom.xml文件中配置多环境,配置多环境代码如下: ```xml pro pro dep dep true test test ``` - **Step2:** 在pom.xml文件中添加以下插件,以此来**开启SpringBoot配置文件目录加载属性的过滤器** ```xml org.apache.maven.plugins maven-resources-plugin 3.3.1 UTF-8 true ``` pom.xml文件完整代码如下 ```xml 4.0.0 org.springframework.boot spring-boot-starter-parent 3.4.0 org.example SpringBootDemoTwo 0.0.1-SNAPSHOT SpringBootDemoTwo SpringBootDemoTwo 21 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test pro pro true dep dep test test org.springframework.boot spring-boot-maven-plugin org.apache.maven.plugins maven-resources-plugin 3.3.1 UTF-8 true ``` - **Step3:** 在SpringBoot的配置文件中引用属性,代码如下 ```yaml # 设置启动的环境---读取pom.xml文件中要启用的环境 spring: profiles: active: ${profile.active} --- # 生产环境 server: port: 81 spring: config: activate: on-profile: pro --- # 开发环境 server: port: 82 spring: config: activate: on-profile: dev --- # 测试环境 server: port: 83 spring: config: activate: on-profile: test ``` 执行Maven的`package`指令打包后,查看jar包中的application.yml文件可知,SpringBoot已成功获取到Maven的多环境配置 ![image-20241217150113016](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217150113016.png) # 配置文件分类 > **问题引入:** > > ​ 后端人员将SpringBoot项目打包发给前端或测试人员时,由于与前端或测试人员的配置冲突,所以前端或测试人员需要重新设置临时属性,这就有了一个问题: > > ​ 若需要设置的临时属性就一两个则很轻松就能设置完;但如果需要设置的临时属性过多,此时前端或测试人员编写对应的指令就会过多,这样就很麻烦,如图所示。因此SpringBoot就引入了多级配置文件来解决该问题 ![image-20241217150945866](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217150945866.png) - SpringBoot中4级配置文件 - 1级: file :config/application.yml 【最高】 - 2级: file :application.yml - 3级:classpath:config/application.yml - 4级:classpath:application.yml 【最低】 - 1级优先级最高,4级优先级最低 - 解释 - 1级、2级为打包后,在jar包所在目录下按1级2级规定格式设置 - 3级、4级为后端开发人员在项目的类路径下按3级4级规定格式设置 - 详细解释可见示例部分内容 - 作用: - 1级与2级留做系统 **打包后** 设置通用属性 - 3级与4级用于系统 **开发阶段** 设置通用属性 ## 快速入门 - 本快速入门的项目S`pringBootDemoThree`已上传至Gitee,可自行下载。搭建过程可详见SpringBoot快速入门,此处只进行关键步骤演示 - 本快速入门通过端口号的变化来演示,这样更能直观看出4级配置文件的优先级顺序 - 本项目以yml格式的配置文件为基准进行演示,所以会删除原有的application.properties文件 ### 4级配置文件示例 - **Step1:** 在源代码配置文件目录(即资源文件`resources`)下创建application.yml配置文件,代码及项目运行截图如下 > 在配置文件中将该项目的端口号设置为80 ![image-20241217152943789](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217152943789.png) - 注意: - 由于此时该配置文件是直接在源代码配置文件目录(即资源文件`resources`)下的,所以会被自动认定为4级配置文件 ### 3级配置文件示例 - **Step1:** 在源代码配置文件目录(即资源文件`resources`)下创建config目录,然后在config目录下创建application.yml配置文件,代码及项目运行截图如下 ![image-20241217153249970](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217153249970.png) - 注意 - 虽然现在有两个名称一致的配置文件,并且有一个在config目录下,但是项目在启动过程中若识别到在源代码配置文件目录(即资源文件`resources`)下存在config目录,就会自动将该目录下的配置文件视为3级配置文件。此时,处于config目录下的配置文件生效,而直接处于源代码配置文件目录(即资源文件`resources`)下的配置文件会失效 ### 2级配置文件示例 > 在进行2级、3级配置文件示例之前需要将项目打包,此处博主已进行打包 - **Step1:** 打开jar包所在目录,在该目录下创建配置文件`application.yml`,代码及项目运行截图如下 ![image-20241217154330251](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217154330251.png) - 注意 - 与jar包同级的配置文件即为2级配置文件,它会覆盖原来的3级和4级配置文件 ### 1级配置文件示例 - **Step1:** 打开jar包所在目录,在该目录下创建config目录,并在config目录下配置文件`application.yml`,代码及项目运行截图如下 ![image-20241217155137746](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217155137746.png) - 注意 - 虽然现在有两个名称一致的配置文件,并且有一个在config目录下,但是jar包在启动过程中若识别到同级目录下存在config目录,就会自动将该目录下的配置文件视为1级配置文件。此时,处于config目录下的配置文件生效,而处于与jar包同级的配置文件会失效 # SpringBoot整合JUnit > 本项目SbJunitDemo以SpringBoot已上传至Gitee,可自行下载。搭建过程可详见SpringBoot快速入门,此处只进行关键步骤演示 ## 环境准备 - **Step1:** 创建业务层service包 - **Step1-1:** 在该包下创建`BookService`接口,代码如下 ```java package at.guigu.service; import java.awt.print.Book; public interface BookService { public void save(); } ``` - **Step1-2:** 在service包下创建impl包,并在impl包下创建`BookService`接口的实现类`BookServiceImpl`,代码如下 ```java package at.guigu.service.impl; import at.guigu.service.BookService; import org.springframework.stereotype.Service; @Service public class BookServiceImpl implements BookService { @Override public void save() { System.out.println("BookService Running..."); } } ``` ## 测试示例 - **Step1:** 在该项目自动生成的测试类`SbJunitDemoApplicationTests`中编写代码,如下 ```java package at.guigu; import at.guigu.service.BookService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class SbJunitDemoApplicationTests { @Autowired private BookService bookService; @Test void contextLoads() { bookService.save(); } } ``` 运行后截图如下 ![image-20241217161256806](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217161256806.png) - 注意 - 在实际测试过程中我们除了可以使用项目所提供的测试类的方法`void contextLoads()`外,还可以使用自定义的测试方法,如下所示 ![image-20241217161629319](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217161629319.png) - 在实际测试过程中我们除了可以使用项目所提供的测试类`SbJunitDemoApplicationTests`之外,也可自定义测试类,此处不在演示,可详见[Spring整合Junit部分内容](https://blog.csdn.net/cgrs5572/article/details/144315543?spm=1001.2014.3001.5501) - 若测试类在SpringBoot启动类的包或子包中,则可以省略启动类(即引导类)的配置(即省略`@SpringBootTest`注解的`classes`属性的设置);反之则不可以省略 ## 可能出现的问题 > 测试类必须在SpringBoot引导类的包或子包中,否则会失效,报错: `Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test` > > 解决办法:给`@SpringBootTest`注解添加`classes`属性且属性值为SpringBoot引导类 - **Step1:** 在项目默认的测试类所在包的上一层包下创建test包,并在test包下创建`ServiceTest`测试类 - **Step1-1:** 给`ServiceTest`测试类加上`@SpringBootTest` - **Step1-2:** 利用`@Autowired`进行自动依赖注入 - **Step1-3:** 编写测试方法并用`@Test`注解修饰 ```java package at.test; import at.guigu.test.BookService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest public class ServiceTest { @Autowired private BookService bookService; @Test public void serviceTest() { bookService.save(); System.out.println("运行自定义的测试方法"); } } ``` 运行后报错如下: ![image-20241217163538240](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217163538240.png) - **Step2:** 给`ServiceTest`测试类的`@SpringBootTest`注解指定SpringBoot引导类,代码如下 ```java package at.test; import at.guigu.SbJunitDemoApplication; import at.guigu.test.BookService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest(classes = SbJunitDemoApplication.class) public class ServiceTest { @Autowired private BookService bookService; @Test public void serviceTest() { bookService.save(); System.out.println("运行自定义的测试方法"); } } ``` 运行截图如下 ![image-20241217163847941](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217163847941.png) # SpringBoot整合MyBatis > 本项目SbMyBatisDemo已上传至Gitee,可自行下载 ## 项目创建 - **Step1:** ![image-20241217170305922](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217170305922.png) - **Step2:** 若创建的是Web项目的话则按下图步骤创建即可;反之则排除10、11两步即可 ![image-20241217170722183](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217170722183.png) - **Step3:** 添加MyBatis的起步依赖:`MyBatis Framework`以及`MySQL Driver` ![image-20241217170809663](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217170809663.png) 初始项目结构如下 ![image-20241217170942665](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217170942665.png) ## 环境准备 - **Step1:** 创建数据库表tb_brand **并使IDEA与数据库建立连接** ,SQL代码如下 ```sql DROP TABLE IF EXISTS tb_brand; -- 创建品牌表brand CREATE TABLE IF NOT EXISTS tb_brand ( -- id 主键 id int PRIMARY KEY auto_increment, -- 品牌名称 brand_name VARCHAR(20), -- 企业名称 company_name VARCHAR(20), -- 排序字段 ordered INT, -- 描述信息 description VARCHAR(100), -- 状态:0:禁用 1:启用 status INT ); -- 添加数据 INSERT INTO tb_brand(brand_name, company_name, ordered, description, status) VALUES ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0), ('华为', '华为技术有限公司', 100, '华为致力于构建万物互联的世界', 1), ('小米', '小米科技有限公司', 50, 'Are you OK', 1); SELECT * FROM tb_brand; ``` - **Step2:** 在pom.xml文件中添加数据源坐标依赖 > 注意:若不添加,则会使用SpringBoot的默认数据源。此处根据实际情况来决定是否添加数据源。博主使用druid数据源 > > 此处只给出相关的两个数据源坐标,可自行选择使用 ```xml com.alibaba druid 1.2.18 com.mchange c3p0 0.9.5.5 ``` - **Step3:** 将配置文件application.properties改为application.yml格式的配置文件,并在该配置文件中配置数据库连接信息以及数据源信息 > 注意:若使用的是cp30则type属性值即为cp30信息。博主使用的为Druid数据源 ```yaml # 配置数据库连接信息以及数据源信息 spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: 123456 ``` - **Step4:** 创建一个与三层架构包同级的pojo包,并在该包下创建实体类`Brand`,代码如下 ```java package at.guigu.pojo; import org.apache.ibatis.type.Alias; @Alias("brand") public class Brand { // id 主键 private Integer id; // 品牌名称 private String brandName; // 企业名称 private String companyName; // 排序字段 用于将某个品牌显示在最前面让消费者看到 private Integer ordered; // 描述信息 private String description; // 状态:0:禁用 1:启用 private Integer status; public Brand() {} public Brand(Integer id, String brandName, String companyName, Integer ordered, String description, Integer status) { this.id = id; this.brandName = brandName; this.companyName = companyName; this.ordered = ordered; this.description = description; this.status = status; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getBrandName() { return brandName; } public void setBrandName(String brandName) { this.brandName = brandName; } public String getCompanyName() { return companyName; } public void setCompanyName(String companyName) { this.companyName = companyName; } public Integer getOrdered() { return ordered; } public void setOrdered(Integer ordered) { this.ordered = ordered; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Integer getStatus() { return status; } public void setStatus(Integer status) { this.status = status; } @Override public String toString() { return "Brand{" + "id=" + id + ", brandName='" + brandName + '\'' + ", companyName='" + companyName + '\'' + ", ordered=" + ordered + ", description='" + description + '\'' + ", status=" + status + '}'; } } ``` - **Step5:** 创建三层架构包,且初始代码分别如下 - 在持久层dao包下创建`BrandDao`接口 ```java package at.guigu.dao; import org.apache.ibatis.annotations.Mapper; @Mapper public interface BrandDao { } ``` - 在该SpringBoot项目的源代码配置文件目录(即main包下的resources目录下)创建多级目录,然后在与`BrandDao`接口对应的目录下创建 SQL映射文件`BrandDao.xml` ,如图所示,SQL映射文件初始代码如下所示 ```xml ``` - 注意:结果映射中的`type="brand"`会标红报错,所以解决办法为:利用`@Alias("别名")`注解为类的全类名设置类型别名 - 在业务层service包下创建BrandService接口及其实现类,初始代码如下: ```java package at.guigu.service; public interface BrandService { } ``` ```java package at.guigu.service.impl; import at.guigu.dao.BrandDao; import at.guigu.service.BrandService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class BrandServiceImpl implements BrandService { @Autowired private BrandDao brandDao; } ``` - 在表现层controller包下创建BrandController类,初始代码如下: ```java package at.guigu.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; // @RestController = @Controller+ @ResponseBody @RestController // Restful风格 @RequestMapping(value = "/brands") public class BrandController { } ``` ## 查询所有数据 > SpringBoot注解开发形式仅以查询所有数据示例,其它增删改操作可根据[MyBatis完整知识点汇总](https://blog.csdn.net/cgrs5572/article/details/140025774?spm=1001.2014.3001.5501)示例操作 - **Step1:** 在dao包下的`BrandDao`接口中写入查询方法,然后在对应的SQL映射文件中写入对应SQL语句 > 注意: > > ​ 简单查询SQL语句采用注解方式,复杂SQL语句采用映射文件方式 > > ​ 在java文件中利用注解形式书写SQL语句时,不需要对特殊字符进行转义 - BrandDao接口代码如下 ```java package at.guigu.dao; import at.guigu.pojo.Brand; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import java.util.List; import java.util.Map; @Mapper public interface BrandDao { // 查询所有条数据 @Select("select * from tb_brand") List all(); // 查询单条数据 @Select("select * from tb_brand where id = #{id}") Brand selectById(@Param("id") Integer id); //静态单条件查询 @Select("select * from tb_brand where id > #{id}") List selectBySingleConOne(Integer id); // 动态单条件查询——对象参数接收 List selectBySingleConTwo(Brand brand); // 动态单条件查询——Map集合参数接收 List selectBySingleConTwoo(Map map); // 动态多条件查询——对象参数接收 List selectByMaxConOne(Brand brand); // 动态多条件查询——Map集合参数接收 List selectByMaxConTwo(Map map); } ``` - SQL映射文件BrandDao.xml代码如下 ```xml ``` - **Step2:** 书写业务层service包下的代码,代码如下 - 在业务层service包下的`BrandService`接口来调用`dao`包下的`BrandDao`接口中的方法,代码如下 ```java package at.guigu.service; import at.guigu.pojo.Brand; import java.util.List; import java.util.Map; public interface BrandService { // 查询所有条数据 public List getAll(); // 查询单条数据 public Brand getById(Integer id); //静态单条件查询 public List selectBySingleConOne(Integer id); // 动态单条件查询——对象参数接收 public List selectBySingleConTwo(Brand brand); // 动态单条件查询——Map集合参数接收 public List selectBySingleConTwoo(Map map); // 动态多条件查询——对象参数接收 public List selectByMaxConOne(Brand brand); // 动态多条件查询——Map集合参数接收 public List selectByMaxConTwo(Map map); } ``` - `BrandService`接口的实现类`BrandServiceImpl`代码如下 ```java package at.guigu.service.impl; import at.guigu.dao.BrandDao; import at.guigu.pojo.Brand; import at.guigu.service.BrandService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; @Service public class BrandServiceImpl implements BrandService { @Autowired private BrandDao brandDao; @Override public List getAll() { return brandDao.all(); } @Override public Brand getById(Integer id) { return brandDao.selectById(id); } @Override public List selectBySingleConOne(Integer id) { return brandDao.selectBySingleConOne(id); } @Override public List selectBySingleConTwo(Brand brand) { return brandDao.selectBySingleConTwo(brand); } @Override public List selectBySingleConTwoo(Map map) { return brandDao.selectBySingleConTwoo(map); } @Override public List selectByMaxConOne(Brand brand) { return brandDao.selectByMaxConOne(brand); } @Override public List selectByMaxConTwo(Map map) { return brandDao.selectByMaxConTwo(map); } } ``` - **Step3:** 在表现层controller包下的`BrandController`类的代码如下: ```java package at.guigu.controller; import at.guigu.pojo.Brand; import at.guigu.service.BrandService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; import java.util.Map; // @RestController = @Controller+ @ResponseBody @RestController // Restful风格 @RequestMapping(value = "/brands") public class BrandController { @Autowired private BrandService brandService; // 查询所有数据 @GetMapping public List getAll() { return brandService.getAll(); } // 查询单条数据:通过id查询 @GetMapping("/{id}") public Brand getById(@PathVariable(value = "id") Integer id) { return brandService.getById(id); } // 静态单条件查询 @GetMapping("/singleConOne/{id}") public List selectBySingleConOne(@PathVariable(value = "id") Integer id) { return brandService.selectBySingleConOne(id); } // 动态单条件查询——对象参数接收 @GetMapping("/singleConTwo") public List selectBySingleConTwo(@RequestParam("brandName") String brandName, @RequestParam("companyName") String companyName, @RequestParam("ordered") Integer ordered,@RequestParam("description") String description, @RequestParam("status") Integer status) { Brand brand = new Brand(); brand.setBrandName(brandName); brand.setCompanyName(companyName); brand.setOrdered(ordered); brand.setDescription(description); brand.setStatus(status); return brandService.selectBySingleConTwo(brand); } // 动态单条件查询——Map集合参数接收 @GetMapping("/singleConTwoo") public List selectBySingleConTwoo(@RequestParam("map") Map map) { return brandService.selectBySingleConTwoo(map); } // 动态多条件查询——对象参数接收 @GetMapping("/maxConOne") public List selectByMaxConOne(@RequestParam("brandName") String brandName, @RequestParam("companyName") String companyName, @RequestParam("ordered") Integer ordered,@RequestParam("description") String description, @RequestParam("status") Integer status) { Brand brand = new Brand(); brand.setBrandName(brandName); brand.setCompanyName(companyName); brand.setOrdered(ordered); brand.setDescription(description); brand.setStatus(status); return brandService.selectByMaxConOne(brand); } // 动态多条件查询——Map集合参数接收 @GetMapping("/maxConTwo") public List selectByMaxConTwo(@RequestParam("map") Map map) { return brandService.selectByMaxConTwo(map); } } ``` 运行后截图如下: ![image-20241217184759409](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217184759409.png) ## 可能出现的问题 > 经过以上步骤之后运行项目,可能会报如下图所示错误,原因是实体类别名配置未生效 ![image-20241217184932565](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217184932565.png) - 解决方法为:在SpringBoot的配置文件application.yml中指定 MyBatis 别名扫描路径。此时,配置文件的代码如下: ```yaml # 配置数据库连接信息以及数据源信息 spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: 123456 # 指定 MyBatis 别名扫描路径 mybatis: type-aliases-package: at.guigu.pojo ``` # SpringBoot整合SSM框架 > 本项目SbSsmDemo已上传至Gitee,可自行下载 > > 本项目已ssm整合为基准,重复步骤均省略,可详见[博客](https://blog.csdn.net/cgrs5572/article/details/144317034?spm=1001.2014.3001.5501) ## 项目创建 - **Step1:** ![image-20241217185730576](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217185730576.png) - **Step2:** 若创建的是Web项目的话则按下图步骤创建即可;反之则排除10、11两步即可 ![image-20241217170722183](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217170722183.png) - **Step3:** 添加MyBatis的起步依赖:`MyBatis Framework`以及`MySQL Driver` ![image-20241217170809663](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217170809663.png) 初始项目结构如下 ![image-20241217190144971](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217190144971.png) ## 环境准备 - **Step1:** 创建数据库ssm_db,然后在该数据库下创建表tbl_book **并使IDEA与数据库建立连接** ,SQL代码如下 ```sql -- 创建ssm_db数据库 CREATE DATABASE IF NOT EXISTS ssm_db CHARACTER SET utf8; -- 使用ssm_db数据库 USE ssm_db; -- 创建tbl_book表 CREATE TABLE tbl_book( id INT PRIMARY KEY AUTO_INCREMENT, -- 图书编号 TYPE VARCHAR(100), -- 图书类型 NAME VARCHAR(100), -- 图书名称 description VARCHAR(100) -- 图书描述 ); -- 添加初始化数据 INSERT INTO tbl_book VALUES(NULL,'计算机理论','Spring实战 第5版','Spring入门经典教材,深入理解Spring原理技术内幕'); INSERT INTO tbl_book VALUES(NULL,'计算机理论','Spring 5核心原理与30个类手写实战','十年沉淀之作,手写Spring精华思想'); INSERT INTO tbl_book VALUES(NULL,'计算机理论','Spring 5设计模式','深入Spring源码剖析,Spring源码蕴含的10大设计模式'); INSERT INTO tbl_book VALUES(NULL,'市场营销','直播就该这么做:主播高效沟通实战指南','李子柒、李佳琦、薇娅成长为网红的秘密都在书中'); INSERT INTO tbl_book VALUES(NULL,'市场营销','直播销讲实战一本通','和秋叶一起学系列网络营销书籍'); INSERT INTO tbl_book VALUES(NULL,'市场营销','直播带货:淘宝、天猫直播从新手到高手','一本教你如何玩转直播的书,10堂课轻松实现带货月入3W+'); ``` - **Step2:** 在pom.xml文件中添加数据源坐标依赖 > 注意:若不添加,则会使用SpringBoot的默认数据源。此处根据实际情况来决定是否添加数据源。博主使用druid数据源 > > 此处只给出相关的两个数据源坐标,可自行选择使用 ```xml com.alibaba druid 1.2.18 com.mchange c3p0 0.9.5.5 ``` - **Step3:** 将配置文件application.properties改为application.yml格式的配置文件,并在该配置文件中配置数据库连接信息以及数据源信息 > 注意:若使用的是cp30则type属性值即为cp30信息。博主使用的为Druid数据源 ```yaml # 配置端口号 server: port: 80 # 配置数据库连接信息以及数据源信息 spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/ssm_db?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: 123456 # 指定 MyBatis 别名扫描路径 mybatis: type-aliases-package: at.guigu.pojo ``` ## 其它步骤 - **Step1:** 将ssm整合项目`RestfulDemo`中的三层架构包、pojo包、exception包、resolver包及包中的代码,以及SQL映射文件复制到该SpringBoot整合SSM框架的项目SbSsmDemo中,如图所示 ![image-20241217193931235](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217193931235.png) - **Step2:** 将静态资源以及html页面复制均到源代码配置文件目录(即资源文件`resources`)下的static目录下,如图所示 ![image-20241217194321312](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217194321312.png) ## 接口测试 ### 使用JUint来测试业务层接口 - **Step1:** 在测试目录test下创建测试类及对应的包,代码及步骤如图所示 ![image-20241217194741982](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217194741982.png) 运行结果如下 ![image-20241217195724368](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217195724368.png) ### 使用POstMan测试表现层 运行引导类后,运行截图如下 ![image-20241217200242053](C:\Users\10195\AppData\Roaming\Typora\typora-user-images\image-20241217200242053.png)