一、SpringBoot
Spring Boot 是 Spring 家族中的一个子项目,旨在简化 Spring 应用的初始搭建和开发过程。一共分为 4 个方面简化操作:
1.1 parent
SpringBoot将各种各样的技术配合使用的常见依赖版本进行收集整理,制作出了最合理的依赖版本配置方案。而SpringBoot 做了无数个技术版本搭配的列表,这个技术搭配列表的名字叫做 parent 。
我们也可以查看关联的其他技术的版本,项目中的 pom.xml 中继承了一个坐标:
xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
</parent>
打开后可以查阅到其中又继承了一个坐标:
xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.4</version>
</parent>
其中可以查询到各式各样的依赖版本号属性:
xml
<properties>
<activemq.version>5.16.3</activemq.version>
<aspectj.version>1.9.7</aspectj.version>
<assertj.version>3.19.0</assertj.version>
<commons-codec.version>1.15</commons-codec.version>
<commons-dbcp2.version>2.8.0</commons-dbcp2.version>
<commons-lang3.version>3.12.0</commons-lang3.version>
<commons-pool.version>1.6</commons-pool.version>
<commons-pool2.version>2.9.0</commons-pool2.version>
<h2.version>1.4.200</h2.version>
<hibernate.version>5.4.32.Final</hibernate.version>
<hibernate-validator.version>6.2.0.Final</hibernate-validator.version>
<httpclient.version>4.5.13</httpclient.version>
<jackson-bom.version>2.12.4</jackson-bom.version>
<javax-jms.version>2.0.1</javax-jms.version>
<javax-json.version>1.1.4</javax-json.version>
<javax-websocket.version>1.1</javax-websocket.version>
<jetty-el.version>9.0.48</jetty-el.version>
<junit.version>4.13.2</junit.version>
</properties>
1.2 starter
starter 定义了使用某种技术时对于依赖的固定搭配格式,也是一种最佳解决方案, 使用 starter 可以帮助开发者减少依赖配置
如:项目中的 pom.xml 定义了使用 SpringMVC 技术,但是并没有写 SpringMVC 的坐标,而是添加了一个名字中包含 starter 的依赖:
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
在 spring-boot-starter-web 中又定义了若干个具体依赖的坐标:
xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.5.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
<version>2.5.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.5.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.9</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.9</version>
<scope>compile</scope>
</dependency>
</dependencies>
starter 与 parent 的区别
starter 是一个坐标中定了若干个坐标,以前写多个的,现在写一个, 是用来减少依赖配置的书写量的 。
parent 是定义了几百个依赖版本号,以前写依赖需要自己手工控制版本,现在由 SpringBoot 统一管理,这样就不存在版本冲突了, 是用来减少依赖冲突的 。
注:如果实际开发中发现坐标发生冲突现象,可以手工书写的方式添加对应依赖,覆盖 SpringBoot 提供给我们的配置管理
1.3 引导类
目前程序运行的入口就是 SpringBoot 工程创建时自带的那个类,也就是带有 main 方法的那个类,运行这个类就可以启动 SpringBoot 工程的运行称为 引导类 ,作为一个引导类最典型的特征就是当前类上方声明了一个注解 @SpringBootApplication 。
java
@SpringBootApplication
public class Springboot0101QuickstartApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot0101QuickstartApplication.class, args);
}
}
1.4 内嵌 tomcat
内嵌 Tomcat 服务器是 SpringBoot 辅助功能之一,内嵌 Tomcat 工作原理是将 Tomcat 服务器作为对象运行,并将该对象交给 Spring 容器管理,变更内嵌服务器思想是去除现有服务器,添加全新的服务器。
更换内嵌 Tomcat,前提是把 tomcat 排除掉,因为 tomcat 是默认加载的:
xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
</dependencies>
二、SpringBoot 基础配置
SpringBoot配置文件就是在 resources 目录下面有一个空白的文件,叫做 application.properties。简化开发者配置的书写位置,集中管理。
2.1 属性配置
properties 格式的文件书写规范是 key = value,而且application.properties 文件中只要输入要配置的属性关键字就可以根据提示进行设置:
properties
server.port=80
spring.main.banner-mode=off
logging.level.root=debug
2.2 配置文件分类
SpringBoot 除了支持 properties 格式的配置文件,还支持另外两种格式的配置文件。三种配置文件格式分别如下:
- properties 格式
- yml 格式
- yaml 格式
其中yml 和 yaml 文件格式就是一模一样的,只是文件后缀不同,所以可以合并成一种格式来看:
yaml
server:
port: 8081
spring:
application:
name: hmdp
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/hmdp?useSSL=false&serverTimezone=UTC
username: root
password: 662811
logging:
level:
com.hmdp: debug
注:配置文件间的加载优先级 properties(最高)> yml > yaml(最低),不同配置文件中相同配置按照加载优先级相互覆盖,不同配置文件中不同配置全部保留
2.3 yaml 文件
这种文件还是有严格的书写格式要求的,下面就来说一下具体的语法格式:
- 大小写敏感
- 属性层级关系使用多行描述,每行结尾使用冒号结束
- 使用缩进表示层级关系,同层级左侧对齐,只允许使用空格(不允许使用 Tab 键)
- 属性值前面添加空格(属性名与属性值之间使用冒号+空格作为分隔)
- #号 表示注释
- 注意属性名冒号后面与数据之间有一个 空格
yaml
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连接,最后使用+代表时区
2.4 yaml 数据读取
2.4.1 读取单一数据
yaml 中保存的单个数据,可以使用 Spring 中的注解@Value 读取单个数据,属性名引用方式: ${一级属性名.二级属性名......}

2.4.2 读取全部数据
SpringBoot 提供了一个对象Environment,能够把所有的数据都封装到这一个对象中,使用自动装配注解可以将所有的 yaml 数据封装到这个对象中,通过 Environment 的接口获取属性,具体方法是 getProperties(String),参数填写属性名即可。

2.4.3 读取对象数据

这个@ConfigurationProperties 必须告诉他加载的数据前缀是什么,这样指定前缀下的所有属性就封装到这个对象中,且数据属性名要与对象的变量名一一对应。
2.4.4 yaml 文件中的数据引用
在书写 yaml 数据时,经常出现如下现象,比如很多个文件都具有相同的目录前缀:
yaml
center:
dataDir: /usr/local/fire/data
tmpDir: /usr/local/fire/tmp
logDir: /usr/local/fire/log
msgDir: /usr/local/fire/msgDir
在配置文件中可以使用${属性名}方式引用属性值,你可以使用引用格式来定义数据,其实就是搞了个变量名,然后引用变量了,格式如下:
yaml
baseDir: /usr/local/fire
center:
dataDir: ${baseDir}/data
tmpDir: ${baseDir}/tmp
logDir: ${baseDir}/log
msgDir: ${baseDir}/msgDir
如果属性中出现特殊字符,可以使用双引号包裹起来作为字符解析:
yaml
lesson: "Spring\tboot\nlesson"
三、SSMP 整合综合案例
整体案例中需要采用的技术如下,先了解一下,做到哪一个说哪一个
- 实体类开发------------使用 Lombok 快速制作实体类
- Mapper 开发------------整合 MyBatisPlus,制作数据层测试
- Service 开发------------基于 MyBatisPlus 进行增量开发,制作业务层测试类
- Controller 开发------------基于 Restful 开发,使用 PostMan 测试接口功能
- Controller 开发------------前后端开发协议制作
- 页面开发------------基于 VUE+ElementUI 制作,前后端联调,页面数据处理,页面消息处理
- 列表
- 新增
- 修改
- 删除
- 分页
- 查询
3.1 实体类开发
添加lombok依赖和mp的依赖,简化开发:
xml
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
实体类:
java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
private Integer id;
private String type;
private String name;
private String description;
}
3.2 数据层开发
添加lombok依赖:
xml
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
使用 MyBatisPlus 的标准通用接口 BaseMapper 加速开发:
java
@Mapper
public interface BookDao extends BaseMapper<Book> {
}
其中核心在于 Dao 接口继承了一个 BaseMapper 的接口,这个接口中帮助开发者预定了若干个常用的 API 接口,简化了通用 API 接口的开发工作。

配置端口和数据源:
yaml
server:
port: 80
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
username: root
password: root
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_ #设置表名通用前缀
id-type: auto #设置主键id字段的生成策略为参照数据库设定的策略,当前数据库设置id生成策略为自增
注:MyBatisPlus也可以实现复杂的sql语句,可以通过https://baomidou.com/getting-started/ MyBatisPlus官方文档学习。
3.3 业务层开发
业务层接口定义如下:
java
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);
}
业务层实现类如下,调用数据层即可:
java
@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;
}
}
3.4 业务层开发(整合 MyBatisPlus)
业务层接口快速开发:
java
public interface IBookService extends IService<Book> {
//添加非通用操作API接口
}
业务层接口实现类快速开发,关注继承的类需要传入两个泛型,一个是数据层接口 ,另一个是实体类。
java
@Service
public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements IBookService {
@Autowired
private BookDao bookDao;
//添加非通用操作API
}
注:但MyBatisPlus 提供的功能不足以支撑你的使用需要,不推荐使用。
3.5 表现层开发
基于 Restful 的表现层接口开发,表现层接口如下:
java
@RestController
@RequestMapping("/books")
public class BookController2 {
@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 int currentPage,@PathVariable int pageSize){
return bookService.getPage(currentPage,pageSize, null);
}
}
3.6 表现层消息一致性处理
目前不同的操作结果所展示的数据格式差异化严重,会给前端开发添加问题
增删改操作结果
tex
true
查询单个数据操作结果
tex
{
"id": 1,
"type": "计算机理论",
"name": "Spring实战 第5版",
"description": "Spring入门经典教程"
}
每种不同操作返回的数据格式都不一样,而且还不知道以后还会有什么格式,必须将所有操作的操作结果数据格式统一起来,需要设计表现层返回结果的模型类,用于后端与前端进行数据格式统一,也称为 前后端数据协议
java
@Data
public class R {
private Boolean flag;
private Object data;
}
表现层开发格式也需要转换一下:
java
@RestController
@RequestMapping("/books")
public class BookController2 {
@Autowired
private IBookService bookService;
@GetMapping
public R getAll(){
List<Book> bookList = bookService.list();
return new R(true, bookList);
}
@PostMapping
public R save(@RequestBody Book book){
Boolean flag = bookService.save(book);
return new R(flag);
}
@PutMapping
public R update(@RequestBody Book book){
Boolean flag = bookService.modify(book);
return new R(flag);
}
@DeleteMapping("{id}")
public R delete(@PathVariable Integer id){
Boolean flag = bookService.delete(id);
return new R(flag);
}
@GetMapping("{id}")
public Book getById(@PathVariable Integer id){
Book book = bookService.getById(id);
return new R(true,book);
}
@GetMapping("{currentPage}/{pageSize}")
public R getPage(@PathVariable int currentPage,@PathVariable int pageSize){
IPage<Book> page = bookService.getPage(currentPage,pageSize);
return new R(true,page);
}
}
最后感谢黑马程序员提供的优质学习资源,让我们在技术道路上能够站在巨人的肩膀上继续前行。本资料仅为学习过程的副产品,希望能帮助到更多同样在努力学习的开发者。