Spring Boot 基础入门:从核心配置到 SSMP 整合实战

一、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 整合综合案例

整体案例中需要采用的技术如下,先了解一下,做到哪一个说哪一个

  1. 实体类开发------------使用 Lombok 快速制作实体类
  2. Mapper 开发------------整合 MyBatisPlus,制作数据层测试
  3. Service 开发------------基于 MyBatisPlus 进行增量开发,制作业务层测试类
  4. Controller 开发------------基于 Restful 开发,使用 PostMan 测试接口功能
  5. Controller 开发------------前后端开发协议制作
  6. 页面开发------------基于 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);
    }
}

最后感谢黑马程序员提供的优质学习资源,让我们在技术道路上能够站在巨人的肩膀上继续前行。本资料仅为学习过程的副产品,希望能帮助到更多同样在努力学习的开发者。

相关推荐
客卿1232 小时前
力扣--组合,子集--回溯法的再探索--总结回溯法
java·算法·leetcode
毕设源码-赖学姐2 小时前
【开题答辩全过程】以 高校晚查寝系统为例,包含答辩的问题和答案
java
xiaoye37082 小时前
某大厂java面试题二面20260313
java·开发语言·spring
Full Stack Developme2 小时前
Java -jar 命令 可以有哪些参数设置
java·开发语言·jar
hjxu20162 小时前
【 MySQL 速记5】插入
android·数据库·mysql
一只程序熊3 小时前
vite-cool-unix-ctx] Unexpected token l in JSON at position 0
java·服务器·前端
晨晖23 小时前
idea2017的下载,破解及使用
java·ide·intellij-idea
摇滚侠3 小时前
Java 项目教程《黑马商城-MQ 篇》,分布式架构项目,从开发到部署
java·分布式·架构
矩阵科学3 小时前
【Spring 原理系列】手搓一个Spring框架
spring