Web阶段总结
1.Maven
1.Maven的作用:
-
依赖(jar包)管理
在pom.xml文件中添加坐标,坐标是资源(jar包)唯一的标识,pom.xml中的坐标通过Maven仓库找到所要的jar包文件
-
统一项目结构
src/main/java:源代码
src/main/resources:配置文件信息
src/test/java : 测试代码
src/test/resources:测试配置文件信息
target: 编译,打包生成文件存放目录
-
项目构建
Maven提供了标准的,跨平台的的自动化项目构建方式
2.Maven模型
- 构建生命周期
- 依赖管理
- 项目对象
3.Maven仓库
当项目中使用坐标引入对应依赖的jar包后,首先会查找本地仓库中是否有对应的jar包,如果有,则项目直接引用,如果没有,则去中央仓库下载对应的jar包到本地仓库
4.pom.xml文件的标签
:根标签,表示当前的maven项目
:声明项目描述遵循哪一个pom模型版本
,,:三个标签组成一个坐标
:打包方法,通常为jar或者war,默认值是jar
5.依赖
-
在pom.xml文件中编写标签,在标签中引用引入坐标,定义坐标的,,
-
依赖具有传递性:
- 直接依赖:在当前项目中通过依赖配置建立的依赖关系
- 间接依赖:被依赖的资源如果依赖了其他的资源,则当前项目间接的依赖了其他的资源
-
排除依赖:
主动断开依赖的资源,通过实现
-
依赖范围:
通过标签指定依赖的作用范围
- compile:默认,所有地方都能使用
- test:测试程序中可以使用
- provided:主程序和测试程序中可以使用
- runtime:测试程序和运行时可以使用
6.生命周期
clean --> compile --> test --> package --> install
2.Spring Boot
1.各种请求
TCP协议 | 请求-响应模型 | HTTP协议 |
---|---|---|
面向连接(三次握手),安全可靠,基于字节流的传输层协议通信 | 一次响应对应一次请求,(请求和响应之间是一一对应的关系) | 无状态协议 |
2.HTTP协议
-
请求协议:浏览器将数据以请求格式发到服务器,包括:请求行,请求头,请求体(GET方法没有请求体)
-
请求行:HTTP请求中的第一行数据,由请求方式,资源路径,协议/版本 组成(之间用空格分隔)
-
请求头:第二行开始,格式为key:value形式
-
请求体:请求方式的请求参数在请求行中,不需要设置请求体
-
各种请求方式
请求方式 请求说明 具体方式 GET 向特定的资源发出请求,获取资源;请求参数有长度限制,限制与浏览器有关, 参数以key=value形式出现,多个请求参数之间用&相连,请求路径和请求参数之间用?连接; /brand/findAll?name=OPPO&status=1 POST 向指定的资源提交数据进行处理请求,数据被包含在请求体中,作为实体主体被传输 请求体和请求行之间用空格隔开 OPTIONS 返回服务器针对特定资源所支持的http请求方式 HEAD 获取报文首部,类似GET,不同在于HEAD不要求返回数据 PUT 将文件包含在报文实体中,保存到URL指定的服务器位置 DELETE 请求服务器删除Request-URI标识的资源 TRACE 回显服务器收到的请求,主要用于测试或者诊断 CONNECT 用隧道协议连接代理
-
-
响应协议:服务器将数据以响应的格式返回浏览器,包括响应行,响应头,响应体
-
响应状态码
状态码分类 说明 1xx 响应中—临时状态码,表示已经接受,如果客户继续请求或者请求已完成则忽略 2xx 成功 3xx 重定向—重定向到其他地方,让客户再发起一个请求已完成整个处理 4xx 客户端错误—处理发生错误,责任在客户端,如客户端请求一个不存在的资源或者客户端未被授权等 5xx 服务器端错误—责任在服务器端,如服务端抛出异常,路由出错,HTTP版本不支持等
3.HTTP解析
- ServerSocket程序,会读取服务器上
html/a.html
文件,并把文件数据发送给浏览器 - 浏览器接收到a.html文件中的数据后进行解析
4.简单参数
-
在向服务器发起请求时,向服务器传递的是一些普通的请求数据
-
在Spring Boot的环境中,参数名与形参变量名相同,定义同名参数就可以完成接收
@RestController public class RequestController { // http://localhost:8080/simpleParam?name=Tom&age=10 //springboot方式 @RequestMapping("/simpleParam") public String simpleParam(String name , Integer age ){//形参名和请求参数名保持一致 System.out.println(name+" : "+age); return "OK"; } }
-
参数名不一致的情况下,在方法形参前面加上@RequestParam注解,然后通过value属性执行请求参数名,从而完成映射
@RestController public class RequestController { // http://localhost:8080/simpleParam?name=Tom&age=20 // 请求参数名:name //springboot方式 @RequestMapping("/simpleParam") public String simpleParam(@RequestParam("name") String username , Integer age ){ System.out.println(username+" : "+age); return "OK"; } }
-
@RequestParam中的required属性默认为true,代表该请求参数必须传递,如果不传递将报错
5.实体参数
请求参数名和实体类的属性名相同
- 简单实体类对象:pojo类中定义
- 复杂实体类对象(在实体类中有一个或多个属性也是实体类对象):请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套实体类属性参数
6.数组参数
请求参数名与形参数组名相同且请求参数为多个,定义数组类型形参即可接收参数
@RestController
public class RequestController {
//数组集合参数
@RequestMapping("/arrayParam")
public String arrayParam(String[] hobby){
System.out.println(Arrays.toString(hobby));
return "OK";
}
}
7.集合参数
请求参数名与形参集合对象名相同,且请求参数有多个,则用@RequestParam绑定参数关系
@RestController
public class RequestController {
//数组集合参数
@RequestMapping("/listParam")
public String listParam(@RequestParam List<String> hobby){
System.out.println(hobby);
return "OK";
}
}
8.日期参数
@DateTimeFormat注解中的pattern属性中指定日期格式
后端controller方法中,需要用Date或者LocalDateTime来封装传递的参数
9.JSON参数
- 传递JSON类型的参数,在controller中会使用实体类进行封装
- 封装规则:JSON数据键名与形参对象属性名相同,定义pojo类型形参接收参数,需要使用@RequestBody
@RestController
public class RequestController {
//JSON参数
@RequestMapping("/jsonParam")
public String jsonParam(@RequestBody User user){
System.out.println(user);
return "OK";
}
}
@RequestBody注解:将JSON数据映射到形参的实体类的对象中(JSON中的key和实体类的属性名保持一致)
10.路径参数
- 前端:通过URL直接传递参数
- 后端:使用{…}标识路径参数,需要使用@PathVariable获取路径参数
@RestController
public class RequestController {
//路径参数
@RequestMapping("/path/{id}")
public String pathParam(@PathVariable Integer id){
System.out.println(id);
return "OK";
}
}
传递多个路径参数
@RestController
public class RequestController {
//路径参数
@RequestMapping("/path/{id}/{name}")
public String pathParam2(@PathVariable Integer id, @PathVariable String name){
System.out.println(id+ " : " +name);
return "OK";
}
}
11.响应
@RestController = @Controller + @ResponseBody
12.IOC&DI
-
IOC:控制反转,将对象的控制权转交给Spring的IOC容器,实现解耦
-
IOC容器创造的对象叫Bean对象
-
使用@Autowired注解注入bean对象
-
IOC相关的注解
-
注解 说明 位置 @Controller @Component的衍生注解,在集成web开发中,声明控制器只能用该注解 标注在控制器类上 @Service @Component的衍生注解 标注在业务类上 @Repository @Component的衍生注解 标注在数据访问类上(由于与mybatis整合,用的少) @Component 声明bean的基础注解 不属于以上三类时,用此注解 -
在IOC容器中,每一个Bean都有属于自己的名字,可以通过注解的value属性指定bean的名字,如果没有指定,默认为类名首字母小写
-
组件扫描:@SpringBootApplication 中,存在扫描注解@ComponentScan,默认扫描的范围是SpringBoot启动类所在包及其子包
-
DI:注入,使用@Autowired注解注入bean对象
-
当存在多个相同类型的Bean注入时:
- 加上@Primary注解,来确定默认的实现
- 在@Qualifier注解的value属性中,指定当前要注入的bean名称(不能单独使用,必须配合@Autowired使用)
- 在@Resource注解中的name属性中,指定要注入的bean的名称
- @Autowird是spring框架提供的注解,默认是按照类型注入,@Resource是JDK提供的注解,按照名称注入
3.MySQL简单语法
1.创建数据库
create datebase dept;
2.删除数据库
drop datebase dept;
3.添加字段
alter table 表名 add 字段名 类型(长度) [comment 注释] [约束];
4.修改字段
alter table 表名 modify 字段名 新数据
类型(长度);
alter table 表名 表名 change 旧字段名 新字段名 类型(长度) [comment 注释] [约束];
5.删除字段
alter table 表名 drop 字段名;
6.添加数据
-
向指定字段添加数据
insert into 表名 (字段名1,字段名2) values (值1,值2);
-
向全部字段添加数据
insert into 表名 values (值1,值2,...);
-
向指定字段批量添加数据
insert into 表名 (字段1,字段2) values (值1,值2),(值1,值2);
-
向全部字段批量添加数据
insert into 表名 values (值1,值2,...);
-
字符串和日期类型数据应该包含在引号中
7.修改字段
-
语法
update 表名 set 字段名1=值1,字段名2=值2,... [where 条件]
-
修改条件可有可无,没有时则修改整张表的数据
-
在修改数据时,一般需要同时修改公共字段update_time,将其修改为当前操作时间。
8.删除数据
-
语法
delete from 表名 [where 条件]
-
删除条件可有可无,没有时删除整张表的数据;
-
不能删除某一个字段的值,但是可以使用update将该字段值设置为null
9.DQL(数据库操作)查询
-
语法结构
select 字段列表 from 表名列表 where 条件列表 group by 分组字段列表 having 分组后的条件列表 order by 排序字段列表 limit 分页参数
-
基本查询设置别名
select 字段1 [ as 别名1 ] , 字段2 [ as 别名2 ] from 表名;
-
基本查询去除重复记录
select distinct 字段列表 from 表名;
-
排序查询
- ASC :升序,默认
- DESC:降序
10.外键:
- 外键约束:让两张表的数据建立连接,保证数据的一致性和完整性,对应的关键字为 : foreign key
- 添加外键约束时,要保证数据完整性
- 物理外键:使用关键字定义外键关联另一张表,会影响效率,仅适用于单节点数据库,且容易引发数据库的死锁问题
- 逻辑外键:在业务逻辑层中,解决外键关联问题
- 语法:
--创建表时指定
create table 表名(
字段名 数据类型,
...
[constraint] [外键名称] foreign key (外键字段名) references 主表 (主表列名)
);
--建完表后添加
alter table 表名 add constraint 外键名称 foreign key(外键字段名) references 主表(主表列名);
11.多表设计
- 一对一:在任意一方加入字段,对应另一方的主键,且设置该字段为唯一的(UNIOUE)
- 多对多:建立第三张中间表,至少包含两个外键,分别关联两方主键
12.多表查询
-
内连接
-
隐式内连接:
select 字段列表 from 表1,表2 where 条件...;
-
显式内连接:
select 字段列表 from 表1 [inner] join 表2 on 连接条件 where 过滤条件;
-
-
外连接
-
左外连接
select 字段列表 from 表1 left [ outer ] join 表2 on 连接条件 ... ;
-
右外连接
select 字段列表 from 表1 right [ outer ] join 表2 on 连接条件 ... ;
-
13.子查询
-
SQL语句中嵌套select语句,称为嵌套查询,又称子查询。
SELECT * FROM t1 WHERE column1 = ( SELECT column1 FROM t2 ... );
-
子查询的书写位置:
- where之后
- from之后
- select之后
-
标量子查询(子查询结果为单个值[一行一列])
-
列子查询(子查询结果为一列,但可以是多行)
-
行子查询(子查询结果为一行,但可以是多列)
-
表子查询(子查询结果为多行多列[相当于子查询结果是一张表])
14.事务
-
定义:一组操作的集合,这组操作,要么同时成功,要么同时失败
-
操作方式:
-
自动提交(默认):执行一条语句,提交一次事务
-
手动提交:先开启,在提交
-
相关语句
sql语句 描述 start transaction;/begin; 开启手动提交事务 commit; 提交事务 rollback; 回滚事务 -
手动提交事务的步骤
- 第1种情况:开启事务 => 执行SQL语句 => 成功 => 提交事务
- 第2种情况:开启事务 => 执行SQL语句 => 失败 => 回滚事务
-
-
四大特性(ACID)
- 原子性(Atomicity):事务是不可分割的最小单元,要么全部成功,要么全部失败。
- 一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
- 隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
- 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。
15.SQL注入
- 通过操作输入的数据来修改事先定义好的SQL语句,完成对服务器的攻击
- #{}防止sql注入
- ${}不能防止sql注入
4.Mybatis
1.xml文件配置规范
- xml映射文件的名称与Mapper接口名称一致,并且要在相同包下(同包同名)
- xml映射文件的namespace属性与Mapper接口全限定名一致
- xml映射文件中sql语句的id与Mapper接口的方法名一致,并保持返回类型一致
2.分页
-
当使用了PageHelper分页插件进行分页,就无需再Mapper中进行手动分页了。 在Mapper中我们只需要进行正常的列表查询即可。在Service层中,调用Mapper的方法之前设置分页参数,在调用Mapper方法执行查询之后,解析分页结果,并将结果封装到PageBean对象中返回。
-
PageBean
@Data @NoArgsConstructor @AllArgsConstructor public class PageBean { private Long total; //总记录数 private List rows; //当前页数据列表 }
-
在pom中导入依赖
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.4.2</version> </dependency>
-
EmpMapper
@Mapper public interface EmpMapper { //获取当前页的结果列表 @Select("select * from emp") public List<Emp> page(Integer start, Integer pageSize) ; }
-
EmpService
public interface EmpService { /** * 条件分页查询 * @param page 页码 * @param pageSize 每页展示记录数 * @return */ PageBean page(Integer page, Integer pageSize); }
-
EmpServiceImpl
@Override public PageBean page(Integer page, Integer pageSize) { // 设置分页参数 //page--当前页码.pageSize--每页显示条数 PageHelper.startPage(page, pageSize); // 执行分页查询 List<Emp> empList = empMapper.list(name,gender,begin,end); // 获取分页结果 Page<Emp> p = (Page<Emp>) empList; //封装PageBean PageBean pageBean = new PageBean(p.getTotal(), p.getResult()); return pageBean; }
5.事务&AOP
1.Transactional注解
- 在当前这个方法执行开始之前开始来开启事务,方法执行完毕之后提交事务,如果这个方法执行过程中出现了异常,就进行事务的回滚
- 异常回滚属性:rollbaFor,保证事务操作前后数据是一致的,可以指定出现何种异常类型时,回滚事务(默认情况下,只有出现RunTimeException才会回滚事务)
- 事务的传播行为:propagation
- 当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行事务控制(在A方法运行的时候,首先会开启一个事务,在A方法当中又调用了B方法, B方法自身也具有事务,那么B方法在运行的时候,到底是加入到A方法的事务当中来,还是B方法在运行的时候新建一个事务?)
- REQUIRED(默认值)需要事务,有则加入,无则创建新事务
- REQUIRES_NEW 需要新事务,无论有无,总是创建新事务
2.AOP
-
面向切面编程,即面向指定的一个或多个方法编程
-
实现步骤
- 在pom文件中导入依赖
- 编写AOP程序
-
优点:
- 代码无侵入
- 减少重复代码
- 提高开发效率
- 维护方便
-
核心概念
-
连接点:JoinPoint 可以被AOP控制的方法
- 对于@Around通知,获取连接点的信息只能使用ProceedingJoinPoint类型
- 对于其他的四种通知,获取连接点信息只能使用JoinPoint类型,它是ProceedingJoinPoint的父类型
-
通知:Advice 共性功能
- @Around :环绕通知,此注解标注的通知方法在目标方法前后都被执行
- @Before : 前置通知,此注解标注的通知方法在目标方法前被执行
- @After :后置通知,此注解标注的通知方法在目标方法后被执行,无论是否有异常都会执行
- @AfterReturning : 返回后通知,此注解标注的通知方法在目标方法后被执行,有异常不会执行
- @AfterThrowing : 异常后通知,此注解标注的通知方法发生异常后执行
- 通知顺序
- 目标方法前:字母排名靠前的先执行
- 目标方法后:字母排名靠后的先执行
- @Order 注解,可以控制通知的执行顺序
-
切入点:PointCut 匹配连接点的条件,通知仅会在切入点方法执行时被应用
-
表达式
-
execution
execution(访问修饰符? 返回值 包名.类名.?方法名(方法参数) throws 异常?)
访问修饰符可省略,
包名.类名可通配(*单个独立的任意符号 …多个连续的任意符号)
throws异常可以省略
-
@annotation
自定义一个注解并匹配
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface MyLog { }
@Override @MyLog //自定义注解(表示:当前方法属于目标方法) public List<Dept> list() { List<Dept> deptList = deptMapper.list(); //模拟异常 //int num = 10/0; return deptList; }
-
-
-
切面: Aspect 描述通知和切入点的对应关系(通知+切入点),描述当前AOP程序需要针对哪个原始方法
-
目标对象:Target 通知所应用的对象
-
6.Spring Boot原理
1.配置优先级
配置文件优先级排名(从高到低):
- properties配置文件
- yml配置文件
- yaml配置文件
属性配置优先级: 命令行参数 > 系统属性参数 > properties参数 > yml参数 > yaml参数
2. Bean作用域
- IOC容器中,默认Bean对象为单例
- 使用@Scope注解来进行配置作用域
- 第三方Bean:如果要管理的bean对象来自于第三方(不是自定义的),是无法用@Component 及衍生注解声明bean的,就需要用到@Bean注解。
3.组件扫描
-
SpringBoot项目中的@SpringBootApplication注解,具有包扫描的作用,但是它只会扫描启动类所在的当前包以及子包。
-
方案1:@ComponentScan 组件扫描
-
方案2:@Import 导入(使用@Import导入的类会被Spring加载到IOC容器中)
导入形式主要有以下几种:
导入普通类
导入配置类
导入ImportSelector接口实现类