Springboot基础篇
1.快速上手Springboot
1.基础配置
1.parent
通过配置指定父工程依赖为
spring-boot-starter-paerent
实现了版本管理的功能,再导入springboot整合其他技术的jar包即可
-
作用:指定jar包版本信息信息,避免依赖版本冲突
这个
spring-boot-dependecies
才是管理所有收录jar包版本和坐标的类,这是自动配置核心所以创建boot工程可以这样写
spring-boot-dependecies
(管理坐标) +spring-boot-starter
(自动配置类)所以在创建boot工程的时候pom.xml文件也可以这样写,不用声明parent为spring-boot-starter-parent
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>springboot_30_loadup</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> </dependencies> <!--重点,只需要导入这个,再导入spring-boot-starter即可完成一个boot工程--> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <!--不用看--> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${spring-boot.version}</version> <configuration> <mainClass>com.example.Springboot30LoadupApplication</mainClass> <skip>true</skip> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
2.starter
总述starter好处:
①springboot整合其他技术后形成的一个统一的jar包,springboot将jar包中有些类的初始化全部变成了读取配置文件方式
②starter定义了当前技术所依赖的jar包,达到减少依赖配置的目的
- 使用任意坐标时,仅书写GAV中的G和A,V由SpringBoot提供,除非SpringBoot未提供对应版本V,由
parent
标签指定
-
下面这张图,点进去starter之后是parent提供的版本信息
里面都是该技术所依赖的jar包及其默认版本,最终版本由标签里面的版本决定
3.引导类
作用:
①Boot工程的执行入口
②SpringBoot工程运行后初始化Spring容器,扫描引导类所在包加载bean,初始化Spring容器
- 扫包方式:当前引导类所在包及其子包
4.内嵌Tomcat
内嵌Tomcat,启动服务器原理:
将Tomcat服务器作为bean对象,并将该对象交给Spring容器管理。当Spring容器启动时,spring容器自动运行tomcat-embed-core内嵌核心,而内嵌核心在spring-boot-starter-web中
-
更换web服务器
tomcat(默认):apache出品,粉丝多,应用面广,负载了若干较重的组件
jetty:更轻量级,负载性能远不及tomcat
undertow:负载性能勉强跑赢tomcat
想更换只需更换对应starter即可
2.配置文件
1.核心配置文件
- starter加载application.yml文件,spring-boot-starter里的这个starter是所有的SpringBoot的starter的基础依赖,里面定义了SpringBoot相关的基础配置
2.属性配置
#设置springboot日志配置
logging.level.root=debug
3.配置文件
- properties格式
- yml格式**(主流格式)**
- yaml格式
-
配置文件优先级:(了解)
application.properties > application.yml > application.yaml
不同配置文件中相同配置按照加载优先级相互覆盖,不同配置文件中不同配置全部保留
4.yaml文件
-
书写核心规则:数据前面要加空格与冒号隔开
-
格式:
5.yaml文件读取
- 读取单个数据规则
- 读取特殊要求数据规则
- 在配置文件中使用
${}
进行引用数据- 出现特殊字符,需要使用
转义字符
-
一次性读取全部数据,解决一次读取一个数据痛点
使用Enviroment接口加载配置文件数据,使用相应方法读取
缺点:无法做到针对性封装,下面引出针对性封装
-
针对性封装✏️
步骤:
①设置一个与属性一一对应的实体类
②在实体类上加上
@ConfigurationProperties(prefix = “属性前缀”)
注解实现自动装配
2.基于Springboot整合SSMP
整合过程一般就是导入相应技术的starter,这些starter
有的提供好注解(@SpringbootTest)
,有的需要提供好配置信息
等总之这些starter的作用提供jar包,并交给spring容器管理,通过配置文件来读取相关信息,初始化好相关的bean(如
mybatis
)
1.整合Junit
-
本质上还是Spring的测试
-
纯手工制作步骤:
1.注意classes位置⭐️
-
如果测试类和引导类在一个包或者其子包中,那么会扫描到,不用管;
否则要指定@SpringBootTest的classes属性为引导类名
-
原理:通过找到引导类,来获取IOC容器,获取IOC容器中的对象。没有指定classes属性,那么就会在本包中搜索配置类,没找到爆错
2.整合Druid
原本需要
DataSource属性
后,配置在type
里,现在导入starter后直接配置在自己的属性里
5.整合第三方技术总结⭐️
3.SSM整合案例
-
分析
1.持久层:CRUD操作
1.基本流程
- 导包的时候一定要相应技术与boot技术的整合包,便于开发
2.MP开启日志,便于看到内部执行过程
page
对象中封装了分页的所有信息,IPage
只是一个接口
3.分页功能
4.条件查询
- 1.创建查询对象
- 2.为查询对象封装条件
- 3.调用bookDao中的selectList方法去实现
2.业务层:
要与数据层功能区分开来,这里是一个个操作的集合
-
借助mybatisplus快速开发Service
如果不满足开发要求,那么手动加入到接口中,然后自己实现
3.表现层
- 前端参数获取:
- 参数在路径中,用
@PathVarible
注解获取- 参数是json格式,用
@RequestBody + 实体类对象
进行获取
-
表现层数据统一处理,解决返回格式乱的问题
设置R对象,增加
flag
和data
字段,flag用来表示查没查找。data用来处理查询到的数据R对象无固定格式,合理即可
3.1 前后端数据协议⭐️
-
Service层做操作的时候
查询的返回结果为数据
增删改,返回的数据为boolen类型
-
表现层做返回值的时候
查询类
全部的返回R全部用ture和对象,因为一定会查到
查询单个数据有可能不返回true
增删改类
的不一定能影响数据
修改删除类的返回R,根据Service层影响数据来设置flag,不用设置data数据值
4. 前后端调用⭐️
页面路径问题:
- 普通的springbootweb项目,static下放页面
- themeleaf的web项目,templates下放页面
4.1 Ajax发送异步请求
4.2 新增操作
-
清理表单数据操作进行的地方:
①每次打开新增数据弹窗的时候
4.3 删除操作
- 存在并发删除的时候,会报异常,这时候前端Ajax可以捕获异常处理
4.4 修改操作
-
列表功能(回显数据) + 新增功能组合
-
调用方法一定为PUT,逻辑与增加数据一样
-
注意点:
4.5 异常处理⭐️
异常处理目的:使前后端格式一致
使用
@RestControllerAdivce
注解配置全局拦截器使用
@ExceptionHandler(异常名称)
捕获异常,并且写相应的方法处理再在R类中设置一个
message
属性,用来设置正常信息和异常信息
-
R实体类
package com.example.util; import lombok.Data; /** * @author qin start * @create 2023-03-22-16:54 */ @Data public class R { private boolean flag; private Object data; private String msg;//用于提示异常信息 public R() { } public R(boolean flag) { this.flag = flag; } public R(boolean flag, Object data) { this.flag = flag; this.data = data; } public R(String msg) { this.flag = false; this.data = null; this.msg = msg; } public R(boolean flag,String msg) { this.flag = flag; this.msg = msg; } }
-
后台异常处理:
-
前后台消息格式统一
-
总结:前后端无论是异常还是提示信息,都交给R中的msg处理,这样实现了提示消息的统一
4.6 分页操作⭐️
-
BUG:
-
正常处理
-
总结
前台
后端
-
这里getPage方法中封装了方法:①创建一个分页Page②调用通用service的分页方法③返回一个page对象
-
分页产生的删除bug
产生:(假设最后一页页码为3)
删除最后一页的最后一条数据的时候之后再进行分页查询的时候,传递过去的分页当前页数据为3,但是分页最大只能为两页。
由前端分页插件处理后,得出
总分页大小为2页
,当前页为第三页(这时候已经被总分页数据2覆盖了),因此会出现当前页为2,但是数据为空的现象 -
处理:
如果当前页面值超过最大分完页数之后,那么将
分完页的总页数
作为当前页数(为最大值)参数,重新进行分页,这样才能得到正确数据 -
还存在问题:
如果再进行大于判断的时候,又删除了几条数据,又会出现问题。这时候就要考虑锁机制
4.7 按条件查询
-
思路:将条件查询当成分页中的一部分数据
-
就是将页面上数据收集,然后组织成参数,用selectPage(page,wrapper)处理即可
多次like默认连接SQL符号为
and
4.8 总结
片转存中…(img-Pvb32rSa-1688197071750)]
-
处理:
如果当前页面值超过最大分完页数之后,那么将
分完页的总页数
作为当前页数(为最大值)参数,重新进行分页,这样才能得到正确数据 -
还存在问题:
如果再进行大于判断的时候,又删除了几条数据,又会出现问题。这时候就要考虑锁机制
-
[外链图片转存中…(img-UvhNb2Kh-1688197071751)]
4.7 按条件查询
-
思路:将条件查询当成分页中的一部分数据
-
就是将页面上数据收集,然后组织成参数,用selectPage(page,wrapper)处理即可
-
[外链图片转存中…(img-fPseVqvH-1688197071752)]
-
[外链图片转存中…(img-8zEYVk6U-1688197071753)]
[外链图片转存中…(img-Sw0y4ytu-1688197071753)]
多次like默认连接SQL符号为
and
[外链图片转存中…(img-oEcnlHiT-1688197071754)]
[外链图片转存中…(img-r589x3c8-1688197071755)]