野先生
前端知识
框架
-
javaSE:韩顺平900.
-
Spring:黑马程序员新版Spring零基础入门到精通,一套搞定spring全套视频教程(含实战源码)_哔哩哔哩_bilibili
-
MyBatis:尚硅谷MyBatis实战教程全套完整版(初学者零基础从入门到精通,好评如潮,资料齐全)_哔哩哔哩_bilibili
-
MyBatisPlus:尚硅谷MyBatisPlus教程(mybatis-plus框架精讲)_哔哩哔哩_bilibili
-
Maven:黑马程序员Maven全套教程,maven项目管理从基础到高级,Java项目开发必会管理工具maven_哔哩哔哩_bilibili
-
SpringBoot2:【尚硅谷】SpringBoot2零基础入门教程(spring boot2干货满满)_哔哩哔哩_bilibili
-
SpringSecurity:尚硅谷SpringSecurity框架教程(spring security源码剖析从入门到精通)_哔哩哔哩_bilibili
-
Mysql:黑马程序员 MySQL数据库入门到精通,从mysql安装到mysql高级、mysql优化全囊括_哔哩哔哩_bilibili
-
Redis:黑马程序员Redis入门到实战教程,深度透析redis底层原理+redis分布式锁+企业解决方案+黑马点评实战项目_哔哩哔哩_bilibili
-
消息队列:Kafka、ActiveMQ、TubeMQ、RocketMQ
-
微服务。
-
容器Docker。
-
K8S
-
CI/CD
常用类库
JAVASE
最基础
JDK
JDK介绍
-
JDK编程环境
-
JRE运行环境
-
JVM运行软件
JDK目录介绍
-
JRE运行环境
-
bin目录是开发工具
-
lib依赖包
-
src源码
-
db是jdk自带数据库
-
include是C和C++开发JDK所用的头文件
-
demo例子
配置JAVA_HOME
方便DOS命令调用lib中的命令【命令对应:命令 -help】
项目结构
-
项目
-
包
-
类等
-
字段等
命名
-
规则
-
字母,数字,下划线,美元符为元素
-
不能是关键字
-
不能是数字开头
-
-
规范
-
包名全小写
-
类名,接口名大驼峰
-
变量名,方法名小驼峰
-
常量名,全大写下划线连接
-
变量
-
使用
-
声明
-
赋值
-
-
四类八种
-
整数Long要使用L
-
浮点数Folat要使用F,是近似值
-
字符输出Unicod编码
-
布尔只能是两种值
-
加号
-
左右是数值是加法
-
左右有字符串是拼接
编码
-
ASCII统一一个字节
-
Unicode统一两个字节【java的字符编码】
-
UTF-8字母一个字节,汉字三个字节
-
GBK字母一个字节汉字两个字节
-
gb2312可以表示汉字
-
big5可繁体中文
类型转换
-
不同类型之间的计算
-
两条自动转换线
-
整数到浮点数转换中只有int到double不会丢失精度
-
【非自动转换就是强转,会丢失精度或溢出】
String
转成字符串
-
字符串相加拼接成字符
转成基本类型
-
Integer.parseInt()解析成Int
-
字符从字符串下标获取就行
-
解析成基本类型必须保证类型正确
运算
运算符
-
单目:+,-,*,/,%
-
双目:++,--
-
三目:boolean ? value1 : value2
-
关系:==,!=,<,>,<=,>=,instanceof
-
逻辑:&&,&,||,|,!,^
-
赋值:=,单目=
进制
-
二进制
-
八进制
-
十进制
-
十六进制F
位运算
正数三码合一,负数
-
源码
-
反码:源码保留符号位其他全部取反
-
补码:反码加一
位运算
-
<<左移
-
<<右移
-
>>>无符号右移
-
~取反
-
&与
-
|或
-
^异或
流程
-
顺序:向前引用
-
分支:if...else。switch...case...default【break防止穿透】。
-
循环:for。while。do...while。
-
break:跳出循环
-
continue:跳出本次循环
-
return:跳出方法
数组
该数据类型解决单个数据存放问题,多个相同数据方便使用。
特点
-
定长
-
连续下标
-
存储相同元素
使用
-
声明
-
开辟空间
-
初始化
-
下标取元素
内存
内存布局
-
方法区:类加载信息
-
栈:执行方法
-
堆:存放对象
-
常量池:存放字符串,或final常量
类加载时机
-
new本类
-
new子类
-
使用类的静态成员
-
反射
继承的所有属性都在一个对象中。
类加载过程
解决字节码加载到内存开始,到Class类对象创建
-
加载:加载字节码到内存【方法区】【并且创建类对象】
-
连接
-
验证:验证内存中的字节码【格式,数据,字节码,符号引用】
-
准备:静态变量默认初始化
-
解析:常量池中的符号引用替换成直接引用
-
-
初始化:开始静态初始化
【-Xverify:none:关闭大部分验证】
对象创建
-
类加载过程【先加载父类对象】
-
静态属性默认初始化
-
静态属性显示初始化:属性直接初始化和静态代码块初始化按照顺序来。
-
-
实例化对象【先加载父类对象】
-
属性初始化
-
属性显示初始化:属性直接初始化和代码块初始化按照顺序来。
-
构造方法初始化
-
-
赋值给引用
-
指定初始化
静态属性存储。说法一:静态属性在方法区的静态域。说法二:静态属性是创建的class对象中。
面向对象-基础
-
类
-
属性
-
方法
-
构造函数
-
包
-
封装
-
继承
-
多态
-
静态
-
代码块
该数据类型解决数组问题,有类型,有名称,可以使用函数。
类
解决类型的定义。
-
属性
-
方法
-
构造器
-
代码块
-
内部类
使用
-
实例化
-
初始化
-
对象操作属性和方法
属性
类数据类型中的元素。
特点
-
有访问修饰符
-
有默认值
方法
解决执行代码可重用问题。
特点
-
有访问修饰符
-
有返回值
-
有方法名
-
有参数
返回值
-
方法声明返回值可以是任意类型或void
-
return返回具体返回值或跳出方法
参数
-
可以有,可以没有
-
调用的时候传参兼容【兼容,个数,顺序】
-
【传参机制】
方法递归
解决同源的复杂问题,将大问题一步步拆分成为一个最简单的问题。
方法自己调用自己
方法重载
解决功能和名称映射问题,同功能的方法名称保持一致。
-
方法名相同
-
形参列表不一致【类型,个数,顺序】
可变参数
解决不确定参数个数的问题,将任意个同类型参数的方法封装成一个方法。
-
可变参必须放在形参列表最后
-
可变参只能出现一个
-
传参可以是数组也可以是多个同类型参数
作用域
解决数据的生命,节省存储数据的空间
-
全局变量:
-
普通属性作用域是对象,静态属性作用域是类。
-
有访问修饰符
-
有默认值
-
生命等同对象
-
-
局部变量:
-
所在代码块中
-
生命等同方法
-
-
全局变量和局部变量可以同名
构造器
解决对象实例化问题,同时有参构造还可以初始化。
-
有访问修饰符
-
没有返回值
-
构造器方法名等同于类名
-
没有任意一个构造器的时候会给一个无参构造
-
构造器由JVM系统调用
-
构造器可以重载
This
解决本类属性和参数同名时,指向本类属性。
-
本质this指向本对象
-
指属性
-
指方法
-
指构造
面向对象-中级
包
解决相同类名的问题,管理类。
-
package表示所在包
-
import表示引入的包或类
-
使用引入两个同名类的时候,需要权限的类名指定
-
命名规则:com+公司名+项目名+业务模块
访问修饰符
解决方法和属性的访问权限问题。
-
public公开
-
protected受保护,同类同包或子类
-
default同类同包
-
private本类
封装
解决类中的属性设置和获取时加上一层过滤。
-
将属性和操作属性的方法封装在一起
-
操作属性的时候加一层过滤
使用
-
属性私有化
-
设置和获取方法
构造器参与封装
解决创建对象的时候没有一层过滤
-
构造器初始化时调用对应set方法
继承
解决重复定义类的问题。
-
访问修饰符决定属性和方法继承或不继承
-
子类必须调用父类的构造器,完成父类初始化.
-
所有子类默认调用父类无参构造器
-
显示调用父类构造器要放在子类构造器的第一行代码
-
this和super都只能放在构造器第一行代码,不能共存
-
所有类都是Object的子类
-
一个类只能有一个父类
-
所有类都可以调用Object类的方法
-
继承需要保持IS-A的关系
查找机制
-
从子类向Object去找
-
找到不可以访问的就会报错
Super
解决继承中子类访问父类的对象信息。
-
父类可访问属性
-
父类可访问方法
-
父类可访问构造
-
【表示父类对象】
重写
解决继承中,子类覆盖父类的方法。
-
方法名相同
-
形参列表相同
-
访问权限比父类大
-
返回值比范围父类小
多态
解决不确定具体类型,用统一类型表示具体类型。
方法多态
解决相同的方法名,调用出来不同的功能实现。
-
方法重载:根据不同的参数决定
-
方法重载:对象不一样就调用不一样的方法
对象多态
-
对象引用类型不能修改,也就是编译类型不能修改
-
父类引用可以指向子类对象
向上转型
解决父类引用类型指向子类运行类型。
-
父类引用指向子类实现
-
只能访问父类的属性和方法
-
以及子类的重写方法
向下转型
解决父类类型不能调用子类特有方法。
-
子类引用强制指向父类引用【类型强制转换】
-
编译类型和运行类型一致,就等同于创建一个子类
多态使用
-
多态数组
-
多态参数
动态绑定机制
解决继承中所有的方法查找,从实现类开始查找。
-
方法有动态绑定,从具体实现开始查找方法实现。
-
属性没有动态绑定,从引用类型开始查找。
Object
解决所有类的父类,提供最基础的方法。
-
equals比较对象地址【==还可以判断基本类型的值】常重写判断内容
-
getClass运行时类型
-
finalize回收没有引用的对象时调用该方法【System.gc主动回收】
-
hashCode对象hash值【集合处重写】
-
toString对象字符串表示【全类名+@+hash十六进制值】常重写打印内容【输出对象默认调用】
断点调试
解决代码运行类型源码查看,看代码原理或排错。
-
F7跳入
-
F8跳过
-
F9下一个断点
-
shift+F7强制跳入
-
shift+F8跳出
面向对象-高级
Static
解决类所持有的属性,方法
-
修饰属性:是类变量,可以和访问修饰符顺序颠倒
-
修饰方法:是类方法,可以和访问修饰符顺序颠倒
类变量
解决所有同类对象的共同属性。
-
对象名和类名都可以调用
-
所有同类对象共享属性
-
【静态属性和属性的区别只有对象共享的区别】
类方法
解决不创建对象直接调用方法。
-
对象名和类名都可以调用
-
【静态方法和普通方法的区别静态方法只能调用静态成员】
Main方法
解决JVM调用方法的入口。
-
public:虚拟机不总是和main方法同包
-
static:虚拟机调用main方法不必创建对象
-
void:虚拟机在获取返回值的时候程序就结束了
-
main:虚拟机默认找到的入口方法标签
-
args:虚拟机执行main方法所需要的命令
-
IDEA参数传递:program arguments
代码块
解决类,对象初始化问题
-
静态代码块:给静态属性赋值,或者
-
普通代码块:抽取构造器的前面公共代码
单例模式
解决全局只有一个该类的对象。
-
饿汉式:创建好一个实例给静态属性,等待使用静态方法去获取
-
懒汉式:第一次使用静态方法获取实例的时候才创建对象
各自特点
-
加载时机:饿汉式类加载的时候就创建,懒汉式调用方法的时候才创建。
-
线程安全:饿汉式是线程安全的,懒汉式线程不安全。
-
资源问题:饿汉式可能会一次都没有使用,懒汉式不会有资源浪费问题。
final
解决类,方法,属性,局部变量的使用限制。
-
类:不能被继承
-
方法:不能被重写
-
属性:只能初始化一次【常量】
-
局部变量:只能赋值一次
构造器不能被final修饰,构造器本就不能被继承。
final类一定全是final方法,final方法的类不一定是final类。
final配合static:类不会被加载【没有顺序要求】
抽象类
解决继承中,父类的方法只给方法定义不给实现的抽象方法。
-
抽象类只能被继承不能被实例化。
-
抽线方法只能被重写。
抽象方法一定在抽象类中,但是抽象类中不一定有抽象方法。
只有实现类实现了抽线类的所有抽象方法,才能实例化。
接口
解决实现类的规范。
定义
-
接口只能是public或者default。和类的访问修饰符一样
-
所有的属性都是静态常量。【public默认】
-
所有方法都是抽象方法。【public默认】
-
接口是LIKE-A的关系
实现
-
实现类实现接口,必须实现所有的抽象方法。
-
抽象类实现接口,可以保留抽象方法。
-
接口可以被接口或实现类或抽象类多实现。
接口多态
-
可以和对象多态一样使用在多态数组,和多态参数上。
-
多态传递,方法需要被重写,传递到实现类去重写。
JDK7:可以有静态方法和默认方法
JDK8:可以有私有方法
内部类
解决类的单继承问题。
-
局部内部类
-
地位是局部变量
-
修饰该类的修饰符和修饰局部变量一样
-
局部内部类直接访问外部类成员
-
作用域下外部类创建对象之后再访问内部类
-
作用域是所在方法
-
内部类调用外部类重名成员(调用外部类:外部类名+this+成员)
-
-
匿名内部类
-
同局部内部类的区别
-
是一个没有名称的类【名称:外部类名$数字】
-
还是一个构造器创建的对象
-
-
成员内部类
-
地位是普通属性
-
修饰该类的修饰符和修饰普通属性一样
-
成员内部类直接访问外部类成员
-
作用域下外部内创建对象再访问内部类
-
作用域是所在对象
-
内部类调用外部类重名成员(调用外部类:外部类名+this+成员)
-
-
静态成员内部类
-
地位是静态属性
-
修饰该类的修饰符和修饰普通属性一样
-
静态内部类直接访问外部类静态成员
-
作用域下外部内创建对象再访问内部类
-
作用域是所在类对象
-
枚举和注解
枚举
解决存放有限特定的对象问题
普通类实现枚举
-
构造器私有化
-
去掉set方法
-
创建实例给静态常量
枚举类
-
默认继承Enum类
-
枚举类型默认是静态常量,创建的对象
-
【枚举类有枚举对象,隐式继承Enum以外就是一个普通类】
注解
解决给代码提供解释信息,配置书写的一种形式。
-
继承Annotation接口。
-
定义时就是定义一个抽象方法,可以给默认值。
-
使用直接给方法名赋值。
元注解
-
@Target使用目标位置【类,属性,方法,参数,构造函数,局部变量,注解,包,类型参数,类型使用】
-
@Retention:注解声明周期【源码,字节码,运行时】
-
@Documented:可以作为文档
-
@Inherited:可以被继承
异常处理
解决出现异常的时候程序任然能继续运行。
抛出的异常信息系统会封装成对应的异常
-
具体异常类
-
异常相关信息
-
异常追踪
处理
-
catch捕获异常
-
throws或throw抛出异常【默认throws】抛给方法调用处
catch
-
没有出现异常不会进入catch
-
出现异常try后面代码不运行直接进入catch
-
catch可以有多个从上往下一一匹配【父类在下面】
finally
-
无论出不出现异常都会执行
return
-
return最后出现在哪里就会返回哪里的值
自定义异常
-
继承异常类
-
将异常信息向父类调用
常用类
Wrapper类
包装类类型
解决基本类型没有对应的处理方法
八种基本数据类型对应的引用类型
-
int基本数据类型对应Integer引用类型
-
char基本数据类型对应Character引用类型
拆箱装箱
解决包装类型的使用。
JDK1.5自动拆箱装箱:直接将相关类型进行赋值。【底层是valueOf和intValue】
拆箱:intValue
装箱:Integer.valueOf【在构造函数上加了一个字节的数字缓存】
String类型转换
解决基本类型或包装类型和字符串的关联。
转成包装类
-
Integer的构造方法【底层调用对应的parse类型方法,character类型直接使用String的charAt方法】
转成字符串
-
String类的valueOf【数值类型调用的是对应的toString方法,boolean是判断true或false,字符是使用字符数组创建字符串】
-
数值加上双引号【底层还是toString】
Integer特点
解决缓存int类型一个字节使用最频繁的数字,来提高速度。
-
Integer包装类的valueOf方法有一个字节的缓存。
-
只要有基本数据类型==判断的是值是否相等
String
解决字符序列的保存,本质是类中维护char数组常量。
创建
-
引号引起来【指向常量池】
-
new一个String类【先指向堆中String对象再指向常量池】
Intern方法
-
池中已经存在了就【指向常量池】
-
池中没有就new一个String类【指向常量池新创建的字符串常量】
StringBuffer
解决用可变字char数组代替String对象数组。
-
StringBuufer保存的是临时char数组
-
真正保存数组的是抽象父类AbstractStringBuilder中的value
-
默认初始化StringBuffer的容量是16
-
添加一个空字符串会往里面加上null
-
容量不够扩容2被+2个容量,最大容量是Integer最大值
StringBuilder
解决StringBuilder所有方法都没有StringBuffer上的锁。
Math
解决数学运算的API。
-
正数类型的int和long
-
浮点类型的float和double
Arrays
解决数组的操作工具类。
排序
-
自然排序
-
定制排序:传入Comparator接口实现类
System
解决系统相关信息的获取。
大数据处理
解决比较大的数计算。
-
范围更大的整数:BigInterger
-
高精度浮点数:BigDecimal
除法需要注意到除不尽的情况。
日期
解决日期的使用。
-
Date和SimpleDateFormat
-
Calender
-
LocalDate
Date和SimpleDateFormat
解决简单的日期获取设置,基于时区的毫秒数。
-
Date:获取当前时间毫秒数
-
SimpleDateFormat:格式化Date时间
-
构造参数是格式化的格式
-
format方法是将Date转成String
-
parse方法是将String类型解析成Date
-
Calendar
解决日期的拆分,并且增删改问题,还可以修改时区
-
getInstance方法获取Calendar对象
-
使用get方法传入对应的参数【比如Calendar.YEAR】
LocalDate
解决日期的计算问题,丰富的API
优点
-
可变性:增删改
-
偏移量:Date从1900年开始
-
格式化:Calendar不能格式化
-
LocalDate:可以处理润秒【每隔两天多一秒】
时间API
-
LocalDate:日期【API】
-
LocalTime:时间【API】
-
LocalDateTime:日期时间【API】
-
now方法获取对象
-
get类型获取对应时间数据
格式化API
-
DateTimeFormatter类【API】
-
ofPattern方法定义格式
-
format(时间API)进行格式化
时间戳API
-
Instant类【API】
-
now方法获取时间戳
-
Date的from静态方法能将Instant转成Date
-
Date的toInstant方法能将Date转成Instant
集合
解决存放Object类型。
Collection
解决单个值的集合。
遍历
-
迭代器:Collection集合实现了Iterable接口的都可以使用迭代器
-
增强for:集合和数组都可以使用增强for遍历
-
fori循环:list集合和数组都可以使用fori遍历
List
解决有序的单列集合。
-
存取有序
-
有索引
-
可重复
在Collection的基础上增加了有关下标的方法。
ArrayList
解决以数组为数据结构的集合。
-
默认构造函数创建一个空对象数组
-
第一次添加最低开辟空间为10个容量
-
超过容量了才会扩容,增加容量是(原来容量+原来容量除2)
-
扩容过后还不够,直接扩容到所需容量
-
数组的最大长度是int的最大值
-
可以添加任意个null
Vector
解决以数组为数据结构并且是线程安全的集合。
-
默认构造函数创建10个容量
-
超过了容量才会扩容,增加容量是(原来的两倍)
-
【要是设置了容量增长个数,就是(原来容量+增长个数)】
-
扩容过后还不够,直接扩容到所需容量
-
数组的最大长度是int的最大值
-
可以添加任意个null
LinkedList
解决以双向列表和双端队列数据结构的集合
-
集合属性维护前后两个节点
-
Node内部类维护前后两个Node节点和本类数据
-
每一次操作都是两端开始【双端队列】
-
可以添加任意个null
Set
解决不重复元素的单列集合。
-
不重复
-
无索引
-
存取无序
在Collection的基础上没有方法增加。
HashSet
解决以hash表为数据结构的集合
-
HashSet里面维护了一个HashMap集合
-
存放数据是将HashSet的数据存放到HashMap的key中,HashMap的value使用空值常量
-
可以为null
LinkedHashSet
解决以hash表为数据结构还维护了一个双向链表。
-
LinkedHashSet全是调用HashSet的方法,维护了一个LinkedHashMap
-
可以为null
TreeSet
解决以红黑树为数据结构的集合
-
底层维护了一个TreeMap
Map
解决双列数据的集合
-
所有的Key都和Set的值一样
-
唯一不同的是,Set使用的value是常量
遍历
Map中的Node元素遍历方法。
-
entrySet方法获取所有的k-v
-
keySet方法获取所有的k
-
values方法获取所有的v
HashMap
解决以Hash表为数据结构的集合
扩容机制
-
默认构造不给数组赋值
-
第一次添加会扩容到16个容量
-
根据key计算数组的索引【计算下标】
-
情况一:hash处理之所在数组下标为空,直接存放到table数组
-
情况二:hash处理之所在数组下标不为空
-
情况一:找到根节点【重复不添加】
-
情况二:找到根节点,为树结构【树结构添加】
-
最后:先遍历链表
-
如果结尾为空直接存放,如果链表长度等于8【树化】
-
如果链表中数据【重复不添加】
-
-
最后:添加成功
-
【节点介入后】【LinkedHashMap扩展方法】
-
-
-
判断达到0.75的阈值进行扩容【扩容】
-
【插入节点后】【LinkedHashMap扩展方法】
中括号解析
-
【计算下标】(key的hash值异或key的hash无符号右移16位)再与计算数组最大下标
-
【重复不添加】(key的值相等或者key的equals相等)
-
【树化】
-
情况一:数组容量小于64先扩容
-
情况二:红黑树化
-
-
【树结构添加】
-
【扩容】
-
情况一:原来表的容量大于0
-
情况一:原来容量达到2的30次方(Integer最大值)
-
情况二:没达到2的30次方且容量达到16【两倍扩容】
-
-
情况二:阈值大于0(将阈值赋值给新的容量)
-
情况三:新的容量为16,新的阈值为0.75*16
-
如果阈值等于0
-
新容量和阈值都小于2的30次方,返回0.75阈值
-
否则返回Integer的最大值阈值。
-
-
遍历复制数据【第一个不为空才复制】
-
情况一:下一个为空,直接找到对应下标存放
-
情况二:红黑树遍历
-
情况三:链表遍历
-
-
数据结构
-
链表:Node元素是维护了(key的hash处理值,key,value,下一个Node节点)
-
红黑树:TreeNode元素维护了(父节点,左子节点,右子节点,上一页节点,红黑判断)间接继承了Node元素
LinkedHahsMap
解决以hash表为数据结构还维护了一个双向链表。
-
默认初始化是16个容量,最大初始化是2的30个容量
-
扩容机制和HashMap一样
TreeMap
解决以红黑树为数据结构的集合。
-
以key值作为比较
-
没给Comparator比较器,使用Comparable比较【类实现】
-
给了Comparator比较器,就不使用默认比较器【构造传入】
HashTable
解决线程安全的hash表。
-
K和V都不能为空
-
value可以覆盖
-
默认构造函数初始容量是11
-
下标计算【hashcode与上一个Integer最大值,再对容量取模】.
-
【扩容】两倍+1的扩容机制。
Properties
解决加载properties文件的集合。
-
本身继承自HashTable,集合和HashTable如出一辙
-
可以使用该集合读取Properties配置文件
Collections
解决集合的通用处理方法。
泛型
解决数据类型的类型定义。【默认Object】
声明泛型
-
类:普通属性,普通方法
-
接口:普通方法,抽象方法
-
泛型方法:可以声明
-
静态方法:必须在方法中定义
定义泛型
-
确定属性:只有类上定义可以使用
-
确定返回值
-
确定参数
使用
-
类:类上的泛型创建对象时候确定
-
接口:继承接口或者实现接口时候确定
-
泛型方法:调用的时候确定
继承和通配符
解决数据类型的类型定义的范围。
-
?:是通配符,表示数据类型可用范围
-
extends A:A类及其子类
-
super A:A类及其父类
多线程
解决多个任务同时进行。
并发并行
-
并发:一个处理器交替处理多个线程
-
并行:同一时刻多个处理器处理各自线程
Thread和Runnable
-
Thread启动线程是start0的本地方法
-
调用本地方法之后,将该方法放入可运行线程
-
实际线程的调用由底层JVM虚拟机调用
Thread方法
【Boolean终止线程】
-
setName:设置线程名
-
getName:返回线程名
-
setPriority:设置线程优先级
-
getPriority:获取线程优先级
-
sleep:休眠
-
interrupt:中断线程【中断休眠】
-
yield:让行
-
join:插入其他线程
-
setDaemon(true):设置为守护线程
线程状态
-
NEW:刚创建
-
RUNNABLE:可运行【Ready就绪和Running运行】
-
BLOCKE:阻塞
-
WAITING:等待
-
TIMED_WAITING:超时等待
-
TERMINATED:已退出
同步机制
解决多线程中数据只允许一个线程访问。
同步代码块
解决可运行的代码使用对象锁,保证同步。
-
格式:synchronized(对象){}
-
对象:互斥锁标记
同步方法
解决方法使用锁,保证方法同步。
-
格式:方法修饰符位置使用synchronized
-
静态方法:对象锁为类对象
-
普通方法:对象锁为当前对象
对象互斥锁
解决同步机制的问题。
-
在多线程中线程获取对象来执行同步代码
-
对象加锁,一次只能有一个线程获取该对象
释放锁
解决同步锁配合使用问题。
释放锁
-
当前同步代码块,同步方法执行完毕。
-
方法中break或return。
-
出现异常。
-
wait方法。
不释放锁
-
sleep:进入超时等待状态,不会释放锁
-
yield:让行,还是在运行状态
IO流
解决信息传输,网络上内存对内存传输,本机上内存对硬盘传输。【必须关闭流】
文件
解决磁盘存放资源问题。
资源路径
-
构造方法找到资源路径
-
getParent:获取父路径
-
getName:获取当前名称
-
getAbsoluteFile:获取绝对路径
文件文件夹判断
-
exitsts:是否存在
-
isFile:是文件
-
isDirectory:是文件夹
-
listFile:获取列表
文件
-
createNewFile:创建文件【单级创建】
-
length:文件大小
-
delete:删除文件
文件夹
-
mkdir:创建一级目录
-
mkdirs:创建多级目录
-
delete:删除空目录
File输入流
解决资源输入。
分类
-
字节输入流
-
字符输入流:本质是输入转换流的子类
使用
-
读取一个字节/字符
-
读取一个字节/字符数组【可截取】
-
估计文件字节/字符数量【可一次全部读取】
-
跳过字节/字符读取个数
返回读取有效长度,读完返回-1。
File输出流
解决资源输出。【必须刷新】【追加和覆盖】
分类
-
字节输出流
-
字符输出流:本质是输出转换流的子类
使用
-
写一个字节
-
写一个字节数组【可截取】
Buffer缓冲流
解决批量处理数据提供方法。
-
字符输入缓冲流:readLine读取一行
-
字符输出缓冲流:newLine换行【和系统相关】
-
字节输入缓冲流:内置数组
-
字节输出缓冲流:内置数组
Object处理流
解决存放数据的同时将数据类型也一并保存。
序列化:ObjectOutputStream
-
输出的时候write类型
-
默认所有的属性都参与序列化,除了static和transient成员
-
要求类中的属性都要实现Serializable接口
反序列化:ObjectInputStream
-
读取顺序和写出一致
-
有对应的类引用,向下转型
-
输入的时候read类型
Serializable
-
参与序列化的类都要实现Serializable接口
-
该接口有传递性,父类有子类就有了
-
SerialVersionUID序列号,当类修改了可以根据序列号找到反序列化的类
标准输入输出流
解决最基础的输入输出。
标准输入流:System.in
-
键盘输入:Scanner
-
编译类型:InputStream
-
运行类型:BufferInputStream
标准输出流:System.out
-
显示器输出:
-
编译类型:PrintStream
-
运行类型:PrintStream
转换流
解决将字节流转成字符流,根据编解码方式转换。
输入转换流:InputStreamReader。解码字符集
输出转换流:OutputStreamWriter。编码字符集
打印流
解决输出时候自动刷新。
打印字节流:PrintStream
打印字符流:PrintWriter
Properties配置
解决properties配置文件的读取和操作,本身就是一个集合。
格式:键=值
方法
-
load:加载文件到properties集合
-
list:输出到指定设备
-
getProperties:获取值
-
setProperties:设置键值对
-
store:将键值对保存到配置文件【Unicode编码】
网络
解决计算机和计算机之间的通信问题。
网络信息
解决网络标识问题。
网络范围
-
局域网:计算机连接网络的同一个设备
-
城域网:以城市为范围
-
广域网:比城市范围更大【互联网】
IP
解决计算机在网络中的标识。【ipconfig查看IP】
-
IPv4
-
格式:xx.xx.xx.xx
-
范围:xx取值0-255
-
意义:以网络号+主机号组成
-
分类【一半的一半】
-
A类:0+7+24
-
B类:10+14+16
-
C类:110+21+8
-
D类:1110+28【广播】
-
E类:11110+27【待用】
-
【127.0.0.1】
-
-
购买的服务器IP才是固定的
-
域名
解决IP记忆问题。【根据域名映射成指定的IP】
端口号
解决计算机上的程序标识问题。【netstat -an|more】
-
取值范围:0-65535
-
已经占用:0-1024
-
常见端口:tomcat8080,mysql3306等
网络通信协议TCP/IP
解决数据传输中的编解码问题。
-
用户数据
-
应用HTTP:加上APP首部
-
传输TCP/UDP:加上TCP首部
-
网络IP:加上IP首部
-
以太网驱动:加上首位帧
TCP协议
解决数据传输时建立传输通道。
-
需要连接和释放连接【三次握手,四次挥手】
-
可进行大量数据传输
UDP协议
解决无连接数据传输。
-
将数据,源,目的封装包传输
-
数据报大小限制64K
InetAddress
解决Ip地址相关问题。
-
getLocalHost:获取本机InetAddress对象
-
getByName:获取指定主机名/域名InetAddress对象
-
getHostName:获取对象的主机名
-
getHostAddress:获取对象的地址
Socket
解决TCP通信问题
-
需要两个Socket进行IO传输
-
主动发起通信的是客户端,服务端阻塞等待客户端发送请求
使用
-
客户端:Socket(IP地址,端口),发送请求
-
服务端:ServiceSocket(端口),监听端口等待连接【阻塞】
-
ServiceSocket.accept:获取Socket对象
-
-
输入流读取【阻塞】
-
输出流写出:socket.shutdownOutput();【结束标记】【flush】
UDP
解决数据报无连接数据传输。
接收端
-
DatagramSocket:接收数据报【监听端口】receive
-
DatagramPacket:参数字符数组
发送端
-
DatagramSocket:接收数据报【发送端口】send
-
DatagramPacket:UDP数据报,接收端IP和端口
反射
解决根据路径的字符串创建对象的方法。
创建实例
-
Class.newInstance:创建实例
类对象
获取类对象
-
Class.forName:编译阶段
-
Class.class:加载阶段
-
class.getClass:运行阶段
-
ClassLoader.loadClass:类加载器加载全类名
-
基本类型.class
-
包装类型.TYPE
使用类对象方法
-
getClassLoader:获取类加载器
反射方法
获取方法对象
-
Class.getMethod(名称,参数列表)【仅公共】
-
Class.getDeclaredMethod(名称,参数列表)【仅类中声明】
使用方法对象
-
setAccessible:暴力调用
-
Method.invoke(对象)调用方法
反射属性
获取属性对象
-
Class.getField(名称)【仅公共】
-
Class.getDeclaredField(名称)【仅类中声明】
使用属性对象
-
get(对象)
-
set(对象,值)
反射构造
获取构造对象
-
getConstructor(参数)【仅公共】
-
getDeclaredConstructor(参数)【仅类中声明】
使用构造对象
-
newInstance
有Class对象的类型
-
类,成员内部类,静态内部类,局部内部类,匿名内部类
-
枚举
-
接口
-
注解
-
数组
-
基本类型
-
void
动态加载,静态加载
静态:加载的类信息中只要有new就会被加载。
动态:不执行的时候不会创建对象,也不会报错
JDBC
只需要一个MySQL驱动包。
解决关系型数据库的统一规范。【本质是数据交互关闭流】
DriverManager
解决数据库驱动的管理
-
Driver驱动类固定:com.mysql.cj.jdbc.Driver
-
原始管理驱动:DriverManager.registerDriver(new Driver());
-
JDK5之后的jdbc4会自动找到jar包下META-INF\services\java.sql.Driver去注册
Connection
解决客户端和数据的连接问题
-
获取连接:DriverManager.getConnection(url,username,password);
-
url:jdbc:mysql://IP:port/库名?【serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=true&rewriteBatchedStatements=true】
-
user:账号
-
password:密码
Statement
解决向数据库发送静态SQL。
-
Connection.createStatement:获取声明对象
-
execute:执行CRUD返回boolean
-
executeQuery:执行查询返回resultSet
-
executeUpdate:执行增删改返回int
Result
解决数据库获取结果集【List<Map>结构】
-
next:光标从第一行前面开始向下走,有数据返回true,没有数据返回false
-
get类型(int):根据列的第几列去取值
-
get类型(String):根据列的标签去取值
PreparedStatement
解决向数据库发送动态SQL。
-
SQL语句以?来占位
-
Connection.prepareStatement(SQL语句):获取预编译声明对象
-
set(index):给?设置
-
executeQuery:执行查询返回resultSet
-
executeUpdate:执行增删改返回int
主键回显
解决主键自增长回显功能
-
Connection.prepareStatement(SQL语句,Statement.RETURN_GENERATED_KEYS):
-
PrepareStatement.getGeneratedKeys():将主键结果封装到resultSet中
批量插入
解决插入的数据过多。
-
addBatch:不执行,追加values后面
-
executeBatch:批量执行
-
url上设置rewriteBatchedStatements=true
-
SQL语句不能使用;号
JDBC事务
解决JDBC中的事务问题。
-
JDBC的事务是自动提交。
-
JDBC事务使用Try,Catch
-
JDBC以连接为单位
连接池
只需要Mysql驱动包和Druid的依赖。
解决创建连接关闭连接浪费时间的问题。
DataSuorce
连接池统一规范。【Druid】
Druid
解决数据库连接的最优秀连接池。
-
DruidDataSourceFactory.createDataSource(prop配置文件):工厂创建连接池
-
DruidDataSource:连接池接口实现
-
设置连接
-
setDriverClassName:设置driver
-
setUrl:设置url
-
setUsername:设置user
-
setPassword:设置password
-
-
getConnection:获取连接
-
Connection.close:回收连接
【为同一个线程任何位置都是取到同一个连接,线程绑定数据源】
DBUtils
解决JDBC的封装工具
-
QuertRunner(DataSource):核心API可以绑定数据源
-
ResultSetHandler:结果集处理器【handle方法处理结果集】
-
SQL:书写用?代表占位符
正则表达式RegExp
解决提取文章中的复合表达式规则的数据。
步骤
-
模式编译:Pattern.compile("\d\d");
-
完整匹配:Pattern.matches(regex, CharSequence)
-
-
获取匹配器:compile.matcher(s);
-
开始匹配:matcher.find()【返回是否匹配到】
-
找到结果,将结果记录在matcher属性中
-
oldLast:记录下一个开始匹配的下标。
-
groups数组:记录【每一组】的下标
-
-
获取匹配结果:matcher.group(0)
-
group(int):从【第几组】下标截取字符串
-
元字符
转义字符:\
匹配符
-
[]:可以接收的单个字符。
-
[^]:排除接收的单个字符。
-
-:连字符一定的范围。
-
.:可以接收任意一个非空格符号
-
\\d:可以接收单个数字【大写取反】
-
\\w:可以接收单个数字和字母【大写取反】
-
\\s:可以接收任何空白【大写取反】
-
【(?!):后面的字母不区分大小写】
选择符
-
|:选择前面一种或者后面一种,最大范围选择
限定符
-
*:任意次数
-
+:最少一次
-
?:最多一次
-
{n}:n次
-
{n,}:最少nci
-
{n,m}:n次到m次
-
【后面加?:非贪心捕获,最小数量匹配。】
定位符
-
^:定位开始字符
-
$:定位结束字符
-
\\b:匹配字符结尾有空格【大写取反】
分组
捕获分组
-
(pattern):非命名捕获。从左往右1开始排号
-
(?<name> pattern):命名捕获。还可以使用组名获取分组
非捕获分组
-
(?: pattern):局部选择。
-
(?= pattern):处于结尾,前面的字符匹配就选择。
-
(?!pattern):处于结尾,前面的字符匹配不选择。
反向引用
解决已经分组捕获的内容【后】进行引用。
-
\\分组号:内部反向引用,表达式内部使用
-
$分组号:外部反向引用。
-
$使用:matcher.replaceAll("$1"):使用反向引用代替匹配的字符。
多线程超卖
JAVAWeb
HTML
解决页面内容书写。
格式
解决HTML文件书写格式。
-
声明
-
html根标签
-
首部
-
meta
-
title
-
-
尾部
-
内容
解决HTML文件最基本的组成
-
单标签
-
双标签【内容】
-
属性
-
基本属性
-
事件属性
-
语法
解决使用HTML的最基本规则。
-
【注释】<!-- -->
-
大小写不敏感
-
标签不能交叉嵌套
-
标签必须闭合
-
属性必须有值且值要加引号
标签
解决HTML编写问题【使用W3cSchool】
base参照地址:href当前标签地址。其他标签的href相对地址会根据该标签去访问。
html字符实体:&打头;结尾
font:字体标签
br:换行标签
h1-h6:标题标签
a:超链接。href写url连接,target响应目标页面显示。
ol或ul:ol是有序列表,ul是无序列表。li是列表项。
img:显示图片。src路径。
table:表格。tr行,td格,th标题格。colspan跨列,rowspan跨行。
ifarme:内嵌窗口。
div:独占一行。
span:片段。
p:段落。
表单
解决表单提交数据。
form
-
action:服务器地址
-
method:提交方式
input
-
text:文本框
-
password:加密文本框
-
select:下拉框。option选项标签【selected="selected"代表选中】
-
redio:单选框【checked="checked"代表选中】
-
checkbox:多选框【checked="checked"代表选中】
-
textarea:多行文本框
-
reset:重新到默认选择
-
submit:提交按钮
-
button:按钮
-
file:文件上传
-
hidden:隐藏域
GET请求
-
地址栏:action+?+请求参数
-
长度有限制
POST请求
-
地址栏:只有action
-
没有长度限制
路径
java路径
-
绝对路径:从盘符开始
-
相对路径:/服务器解析http:/ip:port/工程路径
web路径
-
绝对路径:从HTTP开始
-
相对路径:从当前所在目录开始
-
.标识当前目录
-
..上一级目录
-
文件名相当于./文件名
-
/浏览器解析:http:/ip:port/
-
特殊:sendRediect("/")会交给浏览器解析
CSS
解决网页页面美化问题。
语法
-
注释/* */
-
选择器{属性:值;}
使用方式
方式一:属性直接使用
-
html的style属性:style="key: value;"
方式二:头标中
-
<style type="text/css">中使用下面的代码
-
选择器{属性:值;}
方式三:头标中引入外部文件
-
<link rel="stylesheet" type="text/css" href="web路径"/>
-
外部文件书写:选择器{属性:值;}
选择器
-
标签名选择器:标签名{}
-
id选择器:#id值{}
-
class选择器:.class值{}
-
【多个选择器使用逗号隔开】
JS
解决网页动态显示问题。
使用方式
方式一:头或尾标签种使用script标签
-
<script type="text/javascripe">标签下写代码
方式二:头文件种进行外部引入
-
<script type="text/javascripe" src="web路径">
语法
变量
类型
-
number:数值
-
string:字符串
-
object:对象
-
boolean:布尔
-
function:函数
特殊值
-
undefind:未初始化
-
null:空值
-
NAN:不是数字
运算
关系运算
-
==:比较内容
-
===:比较内容和类型
逻辑运算
-
&&:返回第一个错误的值或者返回最后一个正确的值
-
||:返回第一个正确的值或者返回最后一个错误的值
-
!:取反
-
【0,null,undefined,空串。都是false】
函数
函数名称相同会被覆盖掉。
隐形参数arguments
定义
方式一:function定义
-
function 函数名(形参列表){}
方式二:函数赋值给变量
-
var 函数名 = funcation(形参列表){}
函数例子
-
alert:提示框
-
typeof:返回数据类型
对象
定义
方式一:花括号定义
-
var 对象名 = {};
方式二:对象赋值给变量
-
var 对象名 = new Object{};
数组
-
[]:空数组
-
[1,53,'asd']:定义数组同时初始化
事件
事件注册
静态注册
-
使用事件种类的属性名
-
事件属性名="事件没有;结束"
-
事件属性名="函数调用"
动态注册
-
获取标签的dom对象
-
dom对象.事件名=function(){}
页面加载事件
-
固定:window.οnlοad=函数
事件种类
-
onload:页面加载完成
-
onclick:单机
-
oblur:失去焦点
-
onchange:内容发送变化
-
obsubmit:表单提交
DOM对象
获取对象
-
根据id获取:document.getElementById(id)
-
根据name获取:document.getElementByName(Name)
-
根据标签类型获取:document.getElementByTagName(TagName)
RegExp正则表达式
标准使用
-
new RegExp(pattern):获取模板对象
-
regExp.test:判断是否包含
简单使用
-
var regExp= /pattern/:获取模板对象
-
regExp.test:判断是否包含
JQuery
只需要一个JQuery的文件。
核心对象
解决$代表JQuery对象
-
传入函数:页面加载之后执行。
-
HTML字符串:创建元素节点对象。
-
选择器字符串:查找相关节点对象。
-
DOM对象:将DOM对象包装成JQuery对象。
DOM和JQuey对象
DOM对象
-
表现形式:alert出来是[object HTMLButtonElement]
-
document获取的对象都是DOM对象
JQuey对象
-
表现形式:alert出来是[object object]
-
JQuery函数返回的对象都是JQuery对象
-
本质上是一个对DOM对象数组
XML
格式
-
文档声明
-
元素
语法
-
注释:<!-- -->
-
CDATA:<![CDATA[不解析内容]]>
dom4j解析
只需要一个依赖包
-
SAXReader对象
-
read方法读取xml文件:获取document对象
Tomcat
目录
-
bin:可执行命令
-
conf:配置文件
-
lib:依赖包
-
logs:日志存放
-
temp:临时数据
-
webapps:部署工程
-
work:存放运行时jsp翻译的servlet源码,session钝化(序列化)
启动关闭服务器
启动
-
方式一:startup.bat点击
-
方式二:DOS窗口运行startup.bat
关闭
-
方式一:shutdown.bat点击
-
方式二:关闭黑窗口
【使用了JAVA_HOME的环境变量】
配置
端口号:conf/server.xml下边
部署工程
方式一
-
把web工程放在webapps目录下即可
方式二
-
conf/Catalina/loadhost下放一个xml文件
-
xml文件书写:<Context path="/工程路径" docBase="工程绝对路径"/>
Servlet
只要servlet-api依赖。
使用
-
实现servlet接口
-
web.xml配置映射信息
Servlet生命周期
-
构造方法:第一次访问时候创建对象
-
init方法:对象创建完成之后初始化
-
service方法:每一次访问都会调用
-
destroy方法:容器关闭的时候调用
ServletConfig
-
获取初始化参数<init-param>
-
获取ServletContext对象
-
获取程序别名<servlet-name>
-
【维护父类变量:重写了初始化方法,其他方法getServletConfig是从父类获取】
ServletContext
-
获取工程信息
-
获取工程<context-param>
-
域对象保存数据
HTTP请求
-
请求行
-
请求方式
-
请求路径
-
协议版本号
-
-
请求头:K-V
-
请求空行【get请求没有】
-
请求体【get请求没有】
POST请求目前只有form表单能发送
HTTP响应
-
响应行
-
协议版本号
-
状态码
-
状态码描述
-
-
响应头:K-V
-
响应空行
-
响应体
响应码
-
200:成功
-
302:重定向
-
404:请求地址错误
-
500:服务器内部错误
MIME
HTTP协议中数据类型。
HttpServletRequest
解决请求到服务器之后,自动将请求数据封装到HttpServletRequest,传递给service方法使用
-
getRequestURL:获取请求路径
-
getMethod:获取请求方式
-
getRequestHeader:获取请求头
-
getParameter:获取value为单值的参数
-
getParameterValues:获取value为多值的参数
-
setAttribute:向request域中存放数据
-
getAttribute:从request域中获取数据
请求POST中文乱码
-
setCharacterEncoding("UTF-8"):设置请求体的字符集
-
在获取请求参数之前调用
请求转发
-
getRequestDispatcher("/转发路径").forward(req,resp);
HttpServletResponse
解决请求到服务器之后,自动创建一个新的HttpServletResponse,传递给service方法使用
-
getOutputStream:获取响应字节流
-
getWriter:获取相应字符流
响应中文乱码
-
getCharacterEncoding:默认是ISO-8859-1,欧洲编码
-
setCharacterEncoding("UTF-8"):设置服务器字符集UTF-8
-
浏览器默认是GBK
-
setHeader("Content-type","text/html;charset=UTF-8"):设置相应解析编码
-
【综合上面:setContentType("text/html;charset=UTF-8")】
-
获取相应流之前设置才有效
请求重定向
-
setStatus(302):设置相应编码
-
setHeader("Location","请求路径"):设置重定向地址
-
【综合上面:setRedirect("请求路径")】
JSP
只需要一个jsp-api依赖。
JSP本质是servlet的另一种书写形式。
格式
-
<%@ page contentType="text/html;charset=utf-8" languge="java" %>
-
HTML标签
一共有三种指令
-
page指令。jsp配置信息。
-
include指令。动态包含。也可以写成<jsp:include>。
-
taglib指令。引入JSTL标签库。
脚本
-
声明脚本:<%! 定义类的代码 %>【serlvet类中】
-
表达式脚本:<%= jsp页面输出数据 %>【_jspService方法的out.print代码】所以不能以分号结尾
-
代码脚本:<% java语句 %>【_jspService方法中】
三种注释
-
html注释:<!-- 表达式脚本中 -->
-
java注释:<% 传递到servlet源码中 %>
-
jsp注释:<%-- 注释掉所有的内容 --%>
内置对象九
-
request
-
response
-
pageContext
-
session
-
application
-
config
-
out
-
page
-
exception【需要开启】
四大域对象
-
pageContext
-
request
-
session
-
application
out和response
-
他们各自输出到自己的缓冲区
-
然后out将自己缓冲区的内容追加到response缓冲区
-
最后由response缓冲区将数据相应给浏览器
out对象
-
write:直接将数据返回给浏览器
-
print:在write的基础上对各种数据都进行了String类型处理
静态包含
-
格式:<%@ include file="/"%>
-
静态包含是将另外一个jsp的页面内容放在引入标签位置,生成一个servlet。
动态包含
-
格式:<jsp:include page=""/>
-
动态包含是将另外一个jsp对应的servlet的方法调用。
转发
-
格式:<jsp:forward page="路径"/>
-
【JSP不能直接相应客户端】
JSP的6个动作
-
<jsp:include > 动态包含
-
<jsp:forward > 请求转发
-
<jsp:param > 设置请求参数
-
<jsp:useBean > 创建一个对象
-
<jsp:setProperty > 给指定的对象属性赋值
-
<jsp:getProperty > 取出指定对象的属性值
Listener
三大对象创建销毁监听
-
ServletContextListener
-
HttpSessionListener
-
ServletRequestListener
三大对象域内容增删改
-
ServletContextAttributeListener
-
HttpSessionAttributeListener
-
ServletRequestAttributeListener
对象绑定
-
HttpSessionBindingListener:实现该接口的类,存到session或者取出都会触发绑定和解绑方法。
-
HttpSessionActivationListener:实现该接口,钝化(序列化),活化(反序列化)都是由容器执行,会调用该接口的方法。
EL
解决JSP从四大域中获取数据。Expression Language空值会输出空白而不是null。
-
格式:${key}
-
输出格式
-
对象和map:{}
-
数组:[]
-
其他属性:键值对
-
-
域对象中获取数据setAttribute("p",person)
-
输出基本属性:p.name
-
输出数组属性:p.arr
-
输出数组元素:p.arr[下标]
-
输出map集合属性:p.map
-
输出map集合元素中的值:p.map.key【key值比较特殊可以[]括起来】
-
运算符
-
关系运算
-
逻辑运算
-
算术运算
-
三元运算符
-
empty判断是否为空
-
null值
-
空串
-
集合长度为0
-
对象数组长度为0
-
EL表达式11个隐含对象
-
pageContext:page上下文
-
pageScope:page域
-
requestScope:request域
-
sessionScope:session域
-
applicationScope:application域
-
param:获取单值参数
-
paramValues:获取多值参数
-
header:获取单值请求头
-
headerValues:获取多值请求头
-
cookie:获取Cookie信息
-
initParam:获取web.xml配置的context-param
JSTL
只需要导入taglib-standard-(impl和spec)两个依赖。
解决JSP文件中的代码脚本编写。
标签库分类
-
核心库:包名core。前缀c。
-
格式化:包名fmt。前缀fmt。
-
函数:包名functions。前缀fn。
-
数据库:三层架构,只需要Dao层访问数据库。
-
xml:现在用json来和浏览器交互数据。
使用标签库
-
引入<%@ taglib prefix="前缀" url="Oracle Java Technologies | Oracle包名"%>
核心库标签
-
forEach:遍历
-
set:向域中设置变量
-
if:选择执行
-
choose:多选一。配合when和otherwise标签。
上传下载
只需要commons-(fileupload和io)两个依赖
上传
-
发送form表单,method=post请求,encType=multipart/form-data
-
表单项type=file,name表单项名
-
ServletFileUpload类解析上传数据
-
isMultipartContent:判断请求是多段格式数据
-
parseRequest:解析请求【返回FileItem集合】
-
isFormField:判断是普通表单项
-
getFieldName:获取表单项name属性
-
getString:获取表单项的值
-
getName:获取上传的文件名
-
write:文件输出到磁盘
下载
-
ServletContext.getResourceAsStream:获取资源流
-
ServletContext.getMimeType:获取下载文件的MIME类型
-
resp.setContentType(mimeType):设置响应类型
-
resp.setHeader("Content-Disposition","attachment;filename=文件名"):设置下载头
-
获取响应流
-
IOUtils.copy(输入流,输出流):复制流数据
URL编解码
解决中文转成URL格式:%xx%xx%xx
谷歌和IE
-
URLEncoder.encode("中文"):编码
-
URLDecoder.decode(String):解码
火狐【BASE64编码】
-
文件名格式:=?charset?B?xxxxx?=【xxxxx就是BASE64编码】
-
BASE64Encoder.encodeBuffer("中文".getBytes("UTF-8")):编码
-
BASE64Decoder.decodeBuffer(String):解码
Cookie
解决浏览器数据保存。
特点
-
服务器创建的Cookie对象,发送到浏览器就转成了cookie请求头
-
cookie大小不能超过4kb
使用
-
new Cookie("key","value"):创建一个cookie对象【可以覆盖】
-
resp.addCookie(cookie):响应给客户端
-
req.getCookies:获取请求头中的cookie封装成cookie数组
-
【不支持中文等特殊字符,要使用BASE64编码】
生命控制
-
setMaxAge方法
-
正数:存活秒数
-
负数:关闭浏览器就删除
-
0:立即删除
有效Cookie
-
Cookie的path默认是当前工程路径
-
当发送的URL地址包含Cookie的path路径的时候,cookie才会有效
Session
解决解决服务器保存浏览器和服务器之间需要的数据。
特点
-
服务器创建Session对象
-
将SESSIONID存储到Cookie头中
使用
-
req.getSession:第一次get是创建,第二次get就是根据cookie中的JSESSIONID获取对应的Session对象。
-
isNew:判断是不是刚创建的。
-
getId:获取SESSIONID值
-
setAttribute:向session存值
-
getAttribute:从session取值
生命控制
-
setMaxInactiveInterval:设置超时时长
-
getMaxInactiveInterval:获取超时时长
-
正数:超时时长【可以刷新】
-
负数:永不超时
-
invalidate:设置会话无效
Filter
解决请求安全性。
使用
-
类实现Filter接口
-
在web.xml文件中配置映射路径
生命周期
-
构造方法:web启动的时候Filter就创建
-
init初始化:Filter对象创建之后自动初始化
-
doFilter过滤方法:每次拦截到请求就会执行
-
destroy销毁方法:关闭服务器
FilterConfig
-
获取filter-name
-
获取init-param
-
获取ServletContext对象
FilterChain
异常统一处理
-
本来是用过滤器去转发的。
-
可以在web.xml配置中配置error-pagr设置异常统一转发页面
正常执行
-
第一个过滤器拦截到FilterChain.doFilter找到第二个过滤器
-
第二个过滤器拦截到FilterChain.doFilter请求资源
-
响应第二个过滤器FilterChain.doFilter之后的代码
-
响应第一个过滤器FilterChain.doFilter之后的代码
第二个过滤器拦截
-
第一个过滤器拦截到FilterChain.doFilter找到第二个过滤器
-
第二个过滤器拦截到FilterChain.doFilter拦截
-
响应第二个过滤器FilterChain.doFilter之后的代码【不执行】
-
响应第一个过滤器FilterChain.doFilter之后的代码
拦截器链是根据web.xml配置的顺序来执行。
拦截路径
-
精准匹配
-
目录匹配:*代表目录
-
后缀名匹配:*.html
ThreadLocal
解决当前线程存储数据。
-
ThreadLocal对象存储在ThreadLocalMap中
-
每一个当前线程都绑定了一个ThreadLocalMap
-
ThreadLocal对象简单理解为以当前线程为key,设置的值为value
JSON
只需要gson依赖。
解决服务器和浏览器数据交换的格式
定义
-
JS中定义JSON对象:var json = {"key"="value","key"="value"};
-
Java中定义JSON
JS转换
-
stringify:json对象转成json字符串
-
parse:json字符串转成json对象
Java转换
-
核心api是Gson
-
toJson:将javaBean转成json字符串
-
对象
-
List集合
-
Map集合。
-
-
fromJson(json字符串,Class):json字符串转成javaBean对象
-
fromJson(json字符串,new TypeToken<>(具体类型).getType):json字符串转成list或map集合
AJAX
解决浏览器的js和服务器的数据异步交互。
原生JS
发送
-
核心api是XMLHttpRequest。
-
var ajax = new XMLHttpRequest();:获取核心对象
-
open(method,url,async)true表示异步:设置请求参数
-
onreadystatechange:readyState发送改变自动调用该事件
-
send(string):发送请求数据
回调
-
获取响应API:responseText和responseXML。
-
status:200和404取值
-
readyState
-
0:表示请求未初始化
-
1:表示请求已连接
-
2:请求已接收
-
3:请求已处理
-
4:请求已完成,准备相应
-
JQuery异步
格式
-
未封装:$.ajax(js对象);
-
get请求封装:$.get(对应的js对象);
-
post请求封装:$.post(对应的js对象);
-
getJson请求封装:$.getJson(对应的js对象);
使用
$.ajax()
-
url:地址
-
type:mthod请求方式
-
data:请求参数【js对象】
-
success:回调函数【一定要加上一个参数】
-
dataType:响应类型【text,xml,json】
$.get()和$.post()
-
url:data:callback:type。
-
按照顺序直接书写value对应的js对象
$.getJson()
-
url:data:callback。
-
按照顺序直接书写value对应的js对象
serialize方法
解决将表单数据转换成url格式的数据。
i18n
解决不同语言的显示。
java类中
-
Locale:表示不同时区,位置,语言
-
properties文件:baseName+_locale+.properties
-
ResourceBundle
-
getBundle:根据baseName和Locale读取配置文件
-
getString:根据key获取里面的值
-
JSP中
格式化标签库
-
fmt:setLocale:设置Locale
-
fmt:setBundle:设置baseName
-
fmt:message:从文件中获取值key=?
XML约束
DTD约束
内部书写
-
格式:<!DOCTYPE 根元素[约束]>根元素
-
元素约束
-
<!ELEMENT 元素名称 类别>:类别【ANY,EMPTY】
-
<!ELEMENT 元素名称 (子元素内容)>:元素内容【子元素,字符串#PCDATA】
-
出现次数:+,?,*,|。
-
-
属性约束
-
<!ATTLIST 元素名称 属性名称 属性类型 默认值>
-
属性类型和默认值查找w3cschool文档
-
-
实体约束
-
内部实体定义:<!ENTITY 实体名称 "实体的值">
-
使用:【&实体名称;】
-
外部实体定义:<!ENTITY 实体名称 SYSTEM "URI/URL">
-
外部引入
-
将除了根元素的约束,保存到dtd文件中
-
<!DOCTYPE 根元素 SYSTEM "DTD文件路径">:引入自定义DTD
-
<!DOCTYPE 根元素 PUBLIC "PUBLIC ID" "DTD文件路径">:引入别人定义的DTD
XSD约束
更细致化的约束:值的范围,正则表达式,出现次数,顺序。
支持命名空间,在不同的命名空间下面,可以有重复元素名。
schema约束文件必须和xml文件分离。
schema文件
约束文件头
<?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3school.com.cn" xmlns="http://www.w3school.com.cn" elementFormDefault="qualified">
-
xmlns:xs="http://www.w3.org/2001/XMLSchema"
-
xs:是前缀
-
schema用到的元素和类型来自此命名空间,被约束
-
-
targetNamespace="http://www.w3school.com.cn"
-
schema定义的元素来自此命名空间,当前文件命名空间
-
-
xmlns="http://www.w3school.com.cn"
-
默认的命名空间
-
-
elementFormDefault="qualified"
-
任何 XML 实例文档所使用的且在此 schema 中声明过的元素必须被命名空间限定,被约束文件必须满足该约束。
-
约束文件定义
-
元素:<xs:element name="元素名称" type="元素类型" default="默认值">
-
属性:<xs:attribute name="属性名称" type="属性类型" default="默认值"/>
引用
<?xml version="1.0"?> <note xmlns="http://www.w3school.com.cn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3school.com.cn note.xsd">
-
xmlns="http://www.w3school.com.cn"
-
默认命名空间声明,被约束的命名空间。
-
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
XML实例命名空间,从网络中获取。【默认】
-
-
xsi:schemaLocation="http://www.w3school.com.cn note.xsd"
-
第一个值是所需要使用的命名空间,被约束的名称空间
-
第二个值是给名称空间使用的XMLschema的位置,被约束文件的文件名。
-
Hamcrest-core测试断言依赖
Lombda
表达式
必须是函数式接口
函数式接口
解决只有一个抽象方法的接口
-
Consumer消费型接口【有参数,无返回】
-
Supplier供给型接口【无参数,有返回】
-
Function函数型接口【有参数,有返回】
-
Predicate断定型接口【判断true或者false】
使用
-
有参数
-
无参数
-
返回值用return
-
一个参数小括号可以省略
-
参数类型可以省略
-
Lambda只有一条代码大括号可以省略
方法引用
解决引用方法和函数式接口方法参数和返回值一致。
方法直接替换
-
对象::实例方法名
-
类::静态方法名
方法第一个参数作为调用者出现
-
类::实例方法名
-
示例:(s1,s2)->s1.compareTo(s2)。等同于String::compareTo。
构造引用
-
类::new
数组引用
-
String[]::new
Stream流
解决集合和数组的数据计算,不会存储元素,不会改变对象,只有在就终止时候才会执行。
获取流
-
Collection.stream:顺序流
-
Collection.parallelStream:并行流
-
Arrays.stream(str);
-
Stream.of();
-
Stream.iterate(0,t->t + 2):无限迭代流
-
Stream.generate(Math::random):无限生成流
操作流
筛选【传入条件】
-
filter:过滤元素
-
distinct:去重,通过hashCode和equals去重元素
-
limit:截断流,截取前段数据
-
skip:跳过元素,去除前段数据
映射【传入函数】
-
map:内部元素处理获得新元素
-
faltMap:内部流元素处理获得一个新的流
排序【传入比较器】
-
sorted:自然排序
-
sorted(比较器):比较器排序
终止流
匹配【传入Predicate函数】
-
allMatch:是否匹配所有元素
-
anyMatch:是否匹配到任意元素
-
noneMatch:是否匹配不到元素
获取
-
findFirst:返回第一个元素
-
findAny:返回任意一个元素
-
count:返回元素个数
-
max:返回元素最大值
-
min:返回元素最小值
-
forEach:遍历内部元素
归约
-
reduce(T,BinaryOperator):以T开始,执行三个T的function
-
reduce(BinaryOperator):执行三个T的function
收集
-
collect(Collector):收集到Collector接口的实现类
-
Collector工具类Collectors
Optional类
解决空指针问题,空对象返回一个null。
创建对象
-
of(T):T必须非空
-
empty():空实例
-
ofNullable(T):T可以为null
判断内部对象
-
isPresent():判断是否包含对象
-
ifPresent(consumer):如果有值就传参并执行consumer函数
获取对象
-
get():有对象返回对象,没对象报错
-
orElse(Object other):有对象返回对象,没对象返回other
-
orElseGet(Supplier):有对象返回对象,没对象返回Supplier提供的对象
-
orElseThrow(Supplier):有对象返回对象,没对象返回Supplier提供的异常
动态代理
不改变源码的情况下给实现方法进行增强。
静态代理
将(目标对象)和(增强代码的对象)交给(目标对象的另一个实现类),再调用代理类将两个对象传给代理类。
JDK动态代理
解决有接口的实现类的不修改源码增强。
定义
public class MyInvocationHandler implements InvocationHandler { Object o; public MyInvocationHandler(Object o) { this.o = o; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(o,args); } }
调用
Proxy.newProxyInstance(Target.class.getClassLoader(), Target.class.getInterfaces(), new MyInvocationHandler(new T()));
Cglib动态代理
只需要cglib依赖。
解决没有接口的实现类的不修改源码增强。
定义
public class MyInterceptor implements MethodInterceptor { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { return methodProxy.invokeSuper(o,objects); } }
调用
MyInterceptor myInterceptor = new MyInterceptor(); Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(Target.class); enhancer.setCallback(myInterceptor); Target target = (Target) enhancer.create();
Spring
使用框架三步走:依赖,配置,使用。
IOC
只需要Beans,Core,Context,Expression,commons-logging五个依赖。
解决对象的创建交给第三方容器。
IOC本质
解决IOC的实现原理。
-
原生new代码到处写
-
使用工厂模式new代码提取到一起
-
IOC是使用xml,反射,工厂模式【将所有配置的类存储到map集合】
基础配置
解决IOC配置的基本标签。
-
<bean id="" class=""/>:配置id和全限定类名
-
<bean name="">:配置别名获取bean
-
<bean scope=”>:配置单例多例
-
<bean lazy-init="">:配置懒加载【applicationContext才有效】
-
<beans profile="环境名称">:指定环境
-
虚拟机:-Dspring.profiles.active=环境名称
-
设置环境变量:System.setProperty("spring.profiles.active","环境名称")
-
-
<import resource="">:引入外部资源
-
<alias>:起别名
Bean创建方式
-
构造方式实例化Bean。
-
工厂方式实例化Bean。
-
<bean factory-bean="Bean的id" factory-method="工厂中的方法">:【普通工厂实例化Bean】
-
<bean class="全限定类名" factory-method="工厂中的方法">:【静态工厂实例化Bean】
-
Bean初始化销毁
解决Bean在实例化之后的初始化的一个环节。
初始化方法:Bean实例化之后的初始化方法
销毁方法:Bean销毁之前的销毁方法【显示关闭调用销毁方法】
接口
-
InitializingBean:Bean初始化接口
-
DisposableBean:Bean销毁接口
配置文件
-
<bean init-method="">:Bean初始化配置
-
<bean destroy-method="">:Bean销毁配置
注解
-
@PostConstruct:Bean初始化注解
-
@PreDestroy:Bean销毁注解
获取IOC容器
解决IOC容器获取的方式。
-
BeanFactory:最顶层接口【懒加载】
-
DefaultListableBeanFactory:默认工厂实现
-
XmlBeanDefinitionReader(DefaultListableBeanFactory);读取器
-
read.loadBeanDefinition("bean.xml");读取文件
-
-
new ClassPathXmlApplicationContext("bean.xml"):从类路径获取配置
-
new FileSystemXmlApplicationContext("本地配置"):从磁盘回去配置
-
new AnnotationConfigApplicationContext("配置类"):加载配置类
BeanFactory和ApplicationContext区别
-
叫法
-
BeanFactory叫bean工厂
-
ApplicationContext叫String容器
-
-
功能
-
BeanFactory更底层
-
ApplicationContext对监听,国际化等进行扩展
-
-
Bean创建时机
-
BeanFactory调用时加载
-
ApplicationContext容器创建时加载
-
-
关系
-
ApplicationContext继承Factory
-
还进行了扩展
-
getBean
解决从容器中获取Bena。
-
方式一:根据beanName获取【需要强转】
-
方式二:根据beanType获取【类型唯一】
-
方式三:根据beanName和beanType获取
FactoryBean【延迟加载】
-
实现该接口
-
调用get获取该实现类的时候,调用的是该类的getObject方法
其他标签使用
-
p名称空间使用,可以在bean上p:name对name属性注入。
-
null子标签可以代表属性的空值
-
<>对属性中的特殊符号转义
-
<![CDATA[]]>对内容中的特殊符号转义
命名空间
context命名空间
-
<context:compont-scan base-package="包名"/>【@ComponentScan:扫描注解】
-
<context:property-placeholder location="classpath:jdbc.properties"/>【@PropertySource:加载properties】
-
${jdbc.url}使用spring的EL表达式【@Value:使用基本数据】
aop命名空间
-
<aop:aspectj-autoproxy/>【@EnableAspectJAutoProxy:使用aop注解】
tx命名空间
-
<tx:annotation-driven transaction-manager="transactionManager"/>【@EnableTransactionManagement:开启事务注解支持】
命名空间解析
-
handlerMappings:解析器存储,在/META-INF/spring.handlers文件中
-
命名空间都包含在/META-INF/spring.schemas
-
根据不同的namespaceHandler去解析各自的配置信息。
-
对应框架的BeanDefinitionParser的paeser解析
-
要么注册BeanDefinition
-
要么BeanPostProcessor加入Bean
-
自定义命名空间
-
确定命名空间,schema虚拟路径,标签名称
-
编写约束文件
-
/META-INF/约束映射文件spring.schemas和处理器映射文件spring.handlers
-
NamespaceHandler处理器,并在init方法注册BeanDefinitionParser
-
BeanDefinitionParser解析器,并在parse注册BeanPostProcessor
-
编写BeanPostProcessor
-
引入约束文件【引入约束的命名空间和命名空间的地址文件。】
-
编写自定义标签
DI
解决IOC容器中的Bean之间的关系,以及基本属性注入。
配置注入
-
set注入Bean:<property name="属性" ref="Bean的id"/>
-
set注入值:<property name="属性" value="值"/>
-
construct注入Bean:<construct-arg name="形参" ref="Bean的id"/>
-
construct注入Bean:<construct-arg name="形参" value="值"/>
1. list:\\<value>aaa\</value>\</list> <list> <value>aaa</value> <ref bean="id值"/> </list> 2. map <map> <entry key="k1" value-ref="id值"/> </map> 3. properties <props> <prop key="k1">string</prop> </props>
自动装配
配置文件
-
<bean autowire="byType">:根据set注入的名称
-
<bean autowire="byName">:根据set注入的参数类型
-
<bean autowire="byName">:根据构造注入
Bean
Bean实例化流程
解决Bean实例化的整个过程
-
Spring容器初始化
-
【读取配置文件】
-
执行一系列的BeanFactoryPostProcessor实现类,【处理注解配置】【Bean工厂后置处理器】
-
【将配置文件封装成BeanDefinitionMap集合】
-
Spring再遍历BeanDefinitionMap集合使用反射创建Bean实例对象
-
调用构造方法
-
属性注入【DI】
-
Aware接口
-
postProcessBeforeInitalization【Bean后置处理器Before方法】
-
InitializingBean初始化接口
-
init-method初始化方法
-
postProcessAfterInitalization【Bean后置处理器After方法】
-
创建号的Bean对象存储到singletonObjects的Map集合中
-
getBean方法就是从singletonObjects的Map集合中获取对象
BeanFactoryPostProcessor
解决动态注册和修改BeanDefinition的扩展点。
使用
-
实现BeanFactoryPostProcessor接口
-
把实现类交给Spring容器【Spring自动调用该接口方法】
-
修改BeanDefinition
-
getBeanDefinition:获取BeanDefinition
-
BeanDefinition的方法直接修改【修改就生效】
-
-
注册BeanDefinition
-
创建RootBeanDefinition
-
ConfigurableListableBeanFactory向下转型DefaultListableBeanFactory并调用registerBeanDefinition
-
注册BeanDefinition。
-
专门注册BeanDefinition接口
-
BeanDefinitionRegistryPostProcessor接口继承BeanFactoryPostProcessor
-
postProcessBeanDefinitionRegistry方法专门注册BeanDefinition
BeanPostProcessor
实例化之后和初始化之后的两个扩展点。
解决动态修改Bean。
使用
-
实现BeanPostProcessor接口
-
把实现类交给Spring容器【Spring自动调用该接口方法】
-
postProcessBeforeInitalization:紧接着实例化执行
-
postProcessAfterInitalization:在init初始化之后执行
Bean生命周期
解决Bean实例化之后,到最后存储到SingletonObjects中。
-
实例化阶段
-
单例判断
-
延迟判断
-
FactoryBean判断
-
【实例化】
-
-
初始化阶段
-
属性填充,依赖注入
-
普通属性直接注入
-
单向对象注入,先创建被注入对象Bean实例
-
双向对象注入,循环依赖
-
-
执行Aware【根据接口注入对象】
-
执行BeanPostProcessor的Before
-
执行InitializingBean初始化
-
执行自定义初始化
-
执行BeanPostProcessor的After
-
循环依赖
解决属性注入先实例化所需bean,现在用引用代替。Spring使用三级缓存解决。
-
singletonObjects:单例池【对象没引用其他Bean】
-
earlySingletonObjects:早期单例池【对象引用其他Bean,且被引用】
-
ObjectFactory:对象工厂【对象引用其他Bean,但是没被引用】
执行顺序
-
实例化Bean放到三级缓存。
-
查找所需依赖,三个缓存都没有,去BeanDefinition实例化。
-
查找所需依赖,三级缓存有,将三级缓存的bean移动到二级缓存,完成三级缓存中满足属性注入的Bean加入到单例池。
-
查找所需依赖,一级二级缓存有就直接加入到单例池。
Aware接口
解决Bean对象使用相关的API,由Spring容器自动注入。
-
ServletContextAware:回调方法注入ServletContext【web环境才生效】
-
BeanFactoryAware:回调方法注入BeanFactory
-
BeanNameAware:回调方法注入BeanName
-
ApplicationContextAware:回调方法注入ApplicationContext
注解配置
解决有关注解配置的使用。
特殊配置
2.5时代
-
<context:compont-scan base-package="包名"/>【扫描注解配置】
-
<context:property-placeholder location=""/>【加载properties配置】
3.0时代
-
@ComponentScan:扫描注解
-
@PropertySource:加载properties
-
@Configuration:代表application.xml配置文件【具有@Component作用】
-
@Import:引入其他配置类
-
@Primary:放在@Component或@Bean上,@Autowire获取Bean优先级更高
-
@Profile:放在@Component或@Bean上,表示指定环境下生效
-
【@Profile指定环境,第一虚拟机参数,第二环境变量System】
IOC配置
-
@Component:标识类,配置Bean
-
@Repository
-
@Service
-
@Controller
-
-
@Scope:标识bean类,作用范围
-
@Lazy:标识bean类,懒加载
-
@PostConstruct:标识bean类的方法,初始化方法
-
@PreDestroy:标识bean类的方法,销毁方法
-
@Bean:标识bean类的方法,自定义Bean【默认方法名称】【@Autowire可以省略】
DI配置
解决属性注入,有set走set,没有就暴力反射。
-
@Value:注入普通数据
-
@Autowire:根据byType自动装配
-
@Qualifier:配合@Autowire再根据byName自动装配
-
@Resource:根据byType或byName自动装配
AOP
只需要aop和aspectjweaver依赖。【aop是一个思想,aspectjweaver是实现】
解决对使用动态代理某一个Bean进行增强。
AOP本质
本质就是在Spring容器,Bean后置处理器使用的动态代理。
AOP相关词汇
-
Target目标对象
-
Proxy代理对象
-
Joinpoint连接点
-
Pointcut切入点
-
Advice通知
-
Aspect切面
-
Weaving织入
使用思路
-
增强类书写
-
哪个包类方法需要增强
-
对目标方法那些通知进行增强
切入点表达式
语法
execution([访问修饰符][返回类型][全限定类名][方法名称]([参数列表])) 1.权限修饰符:【可以省略】 2.返回类型:*代表任意字符Str* 3.全限定类名:*.代表任意字符,*..代表所有的包 4.方法名称:*代表任意字符, 5.参数列表:*代表任意类型,..代表任意类型任意个数 通配符
通知
-
前置通知:@Before:前置通知
-
返回通知:@AfterReturning:返回通知【Returning属性:获取返回值】
-
异常通知:@AfterThrowing:异常通知【Throwing属性:获取异常信息】【针对目标】
-
最终通知:@After:最终通知
-
环绕通知:@Around:环绕【ProceedingJoinPoint:调用被代理方法】
环绕通知有限执行。
XML配置aspect
解决指定通知类的方法作为通知。
-
配置目标类Bean
-
配置通知类Bean
-
aop切面配置
-
pointcut切入点表达式
-
aspect代理类的通知方法,切入点绑定
-
XML配置advice
解决实现了advice接口的类作为通知类。
-
配置目标类Bean
-
配置通知类Bean
-
实现了advice接口的通知类绑定一个advice配置
-
aop切面配置
-
pointcut切入点表达式
-
advice的配置,切入点绑定
-
注解配置AOP
-
开启注解支持:aop:aspectj-autoproxy配置或@EnableAspectJAutoProxy
-
配置目标类Bean
-
配置通知类Bean
-
@Aspect:切面配置
-
@PointCut:切入点
-
通知注解
-
-
@Order【值越小越先执行】
AOP声明式事务
使用
xml方式
-
<tx:advice>配置advice就行
-
目标方法配置属性
注解方式
-
@TransactionManager就不用配置advice和切面
-
加上<tx:annotation-driven transaction-manager="transactionManager"/>【自带AOP支持】
纯注解
-
@TransactionManager就不用配置advice和切面
-
@EnableTransactionManagement:开启事务支持【自带AOP支持】
核心三个类
-
PlatformTransactionManager接口:事务管理器
-
TransactionDefinition:事务设置
-
TransactionStatus:事务状态【提交回滚】
JdbcTemplate
解决jdbc简单封装实现。
-
将JdbcTemplate中放入dataSource就行了。
整合JUnit
只需要spring-test依赖。
Junit4
-
@RunWith(SpringJUnit4ClassRunner.class)
-
@ContextConfiguration("classpath:spring.xml")
Junit5
-
@ExtendWith(SpringExtension.class)
-
@ContextConfiguration("classpath:spring.xml")
-
复合注解@SpringJUnitConfig(locations="classpath:spring.xml")
webFlux
Servlet3.1的核心api是Reactor,异步非阻塞。
整合框架
Mybatis
解决其他框架整合。
XML配置整合
-
不需要其他命名空间:Mybatis
-
需要其他命名空间:Dubbo
XML整合Mybatis
需要mybati-spring整合包,spring-jdbc和tx依赖。
-
注入Bean
-
SqlSessionFactory
-
MapperScannerConfig
-
-
书写Mapper
-
书写Mapper.xml
Mybatis整合原理
一共四个核心类
-
SqlSessionFactoryBean:提供SqlSessionFactory
-
MapperScannerConfigurer:扫描指定mapper注册BeanDefinition
-
MapperFactoryBean:获得指定mapper是调用getObject方法
-
ClassPathMapperScanner:definition.setAutowireMode【向MapperFactory自动注入SqlSessionFactory】
注解整合Mybatis
-
注册SsqlSessionFactory的bean对象
-
@MapperScan:扫描Mapper接口
web
原生整合
-
web的三大组件
-
SerlvetContextLisener监听器执行容器的创建
-
context-param配置上要加载的spring配置文件
-
WebApplicationContextUtils.getWebApplicationContext
spring-web依赖整合
-
监听器由整合包提供
-
工具类由整合包提供
SpringMVC
只需要spring-webmvc依赖,javax-servlet-api:3.1.0【provided】不参与打包。
解决三个事情,servlet公共部分抽取,setvlet根据业务分Controller,servlet接入spring容器。
所有操作
web配置文件
-
前端控制器ServletDispatcher
-
乱码过滤器CharacterEncodingFilter
-
请求方式过滤器HiddenHttpMethodFilter
mvc配置文件
-
mvc注解驱动【添加】
-
视图控制器
-
默认servlet
-
拦截器interceptor
-
上传解析器multipartResolver
-
异常处理器解析器SimpleMappingExceptionResolver
-
视图解析器viewResolver
重要组件执行顺序
MVC:模型,视图,控制器。
-
前端控制器获取请求
-
处理器映射器解析地址【处理器映射器】
-
返回处理器执行链
-
处理器适配器找到对应的处理器【处理器适配器】
-
处理器执行【处理器】
-
处理器返回结果数据
-
处理器适配器返回结果数据
-
视图解析器解析视图【视图解析器】
-
视图解析器返回视图对象
-
前端控制器响应
获取请求参数
原生获取
-
request.getParam获取单个参数
-
request.getParams获取多个参数
MVC获取参数
原生方法
-
Aware获取原生API获取请求参数
直接封装
-
保证名称一致,字符串获取多值时的格式:a,b,c
-
保证名称一致,数组获取多值的格式:[a,b,c]
对象接收参数
-
保证属性名称和参数一致。
获取请求信息相关注解
-
@RequestParam注解,封装请求参数【别名,集合不创建对象接收参数】
-
@RequestHeader注解,封装请求头
-
@CookieValue注解,封装cookie信息
三个注解都有这三个属性 1. name:映射名称 2. required:必须赋值【默认】 3. defaultValue:默认值
解决乱码
处理要求:处理乱码需要在获取参数之前设置请求编码。
-
get乱码:属于tomcat乱码,server.xml配置文件设置urlEncoding编码解决。
-
post乱码:在前端控制器之前执行编码。
-
过滤器解决CharacterEncodingFilter处理器
-
初始化参数:设置请求编码encoding
-
设置【响应】编码:设置forceResponseEncoding为true就可以了
-
结果数据
-
原生ServletAPI向request域中存值。
-
ModelAndView【基本对象】
-
addObject:添加共享数据
-
setViewName:跳转页面
-
-
Model【Aware参数注入】
-
addAttribute:添加共享数据
-
-
Map【Aware参数注入】
-
put:添加共享数据
-
-
ModelMap【Aware参数注入】
-
addAttribute:向request中设置数据
-
【BindingAwareModelMap是根本实现类】
MVC注解驱动
需要注解驱动的情况<mvc:annotation-driven />
-
视图控制器:<mvc:view-controller path="/" view-name="success"/>【请求地址和视图的映射,走视图解析器】
-
默认的servlet:<mvc:default-servlet-handler/>【处理静态资源】
-
java对象转成json:HttpMessageConvertor
报文信息转换器
HttpMessageConverter
-
@RequestBody:请求体
-
@ResponseBody:响应体【返回值转换成响应体】
-
RequestEntiry:请求报文对象
-
ResponseEntiry:响应报文对象
Json格式转换支持
只需要jackson-(databind,core,annotations)依赖。
-
<mvc:annotation-driven />
-
@ResponseBody
上传下载
下载:使用ResponseEntiry
bytes = 文件读取的字节数组。 headers = new HttpHeaders().add("Context-Disposition","attachment;filename=1.jpg") statusCode = HttpStatus.OK。 return new ResponseEntiry(bytes,headers,statusCode)
上传:【multipartResolver自动注入到Spring容器中】
只需要commons-(io和fileupload)两个依赖。
-
发送form表单,method=post请求,encType=multipart/form-data
-
表单项type=file,name表单项名
-
配置文件上传解析器:<bean id="multipartResolver" class="org.spingframework.multipart.commons.CommonsMultipartResolver"/>
-
MultipartFile【参数封装】
-
MultipartFile.transferTo:转存方法。
前端控制器
xml配置
dispatcherServlet默认配置
<load-on-startup>1 springMVC的配置文件【默认】 WEB-INF下的【名称】<servlet-name>-servlet.xml
dispatcherServlet扩展配置
<init-param> param-name:contextConfigLocation param-value:classpath:springMVC.xml <load-on-startup>1
前端控制器处理/路径:表示的路径是除了JSP之外的处理,/*是所有处理。
映射器
使用
使用在类上
-
给Controller处理器方法加上前缀。
使用在方法上
@RequestMapping("/hello") public String hello(){ System.out.println("hello请求进入"); return "hello"; }
@RequestMapping
-
value(path):映射请求地址
-
可以是数组多个请求映射
-
-
method:映射请求方式
-
可以是数组多个请求方式
-
-
params:映射请求参数
-
param:必须携带该参数
-
!param:必须不携带该参数
-
param=value:该参数一定定于该值
-
param!=value:该参数不等于该值
-
-
headers:映射请求头
-
header:必须携带该参数
-
!header:必须不携带该参数
-
header=value:该参数一定定于该值
-
header!=value:该参数不等于该值
-
@RequestMapping派生注解
-
@GetMapping
-
@PosyMapping
ant风格路径
RequestMapping的映射路径。
-
?任意一个字符
-
*任意0-多个字符
-
**任意0-多层级目录
rest风格路径
-
路径传参
-
/{id}:映射接收路径
-
@PathVariable("id")取出参数
rest风格请求方式
-
页面请求:<input type="hidden" name="_method" value="put"/>
-
配置隐藏请求方式过滤器:HiddenHttpMethodFilter
-
【必须配置在乱码之后,因为此处获取了_method请求参数】
拦截器
使用
拦截器实现类
-
HandlerInterceptor接口的实现类
-
preHandler:处理之前拦截
-
postHandler:处理之后加强
-
afterComplation:视图渲染之后方法
配置拦截器
-
<mvc:interceptors>配置拦截器
-
<bean class=""/>:对所有请求拦截【通过类路径创建Bean】
-
<ref bean=""/>:对所有请求拦截【使用IOC中的对象】
-
<mvc:interceptor>:配置指定路径
-
<bean class=""/>:对指定请求拦截【通过类路径创建Bean】
-
<ref bean=""/>:对指定请求拦截【使用IOC中的对象】
-
<mvc:mapping path=""/>:包含指定路径
-
<mvc:exclude-mapping path=""/>:排除指定路径
-
执行顺序
正常执行
-
按配置顺序一顺执行完毕两个preHandler
-
处理器处理请求
-
按配置顺序反向执行两个postHandler
-
按配置顺序反向执行两个afterComplation
第二个拦截器拦截
-
按配置顺序一顺执行完毕两个preHandler
-
处理器和postHandler都【不执行】
-
执行第一个afterComplation
异常处理器
HandlerExceptionResolver接口实现类
-
DefaultHandlerExceptionResolver【mvc默认异常处理实现】
-
SimpleMappingExceptionResolver【自定义异常处理】
配置方式
-
SimpleMappingExceptionResolver配置bean
-
属性
-
exceptionMappings:K是异常,V是新的视图
-
exceptionAttribute:向请求域中存储错误信息
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="异常类">视图【过视图解析器】</prop> </props> </property> <property name="exceptionAttribute" value="ex"/>【异常信息key为ex存放到request域中】 </bean>
注解方式
-
@ControllererAdvice:标志类是异常处理组件
-
@ExceptionHandler(异常类):处理哪一个异常
-
方法上放Exception和Model
@ControllerAdvice public class MyExceptionController{ @ExceptionHandler(异常类) public String testException(Exception ex,Model model){ model.setAttribute("ex",ex); return "视图【过视图解析器】"; } }
适配器
控制器
-
使用在控制器类上:@Controller
-
使用在控制器类上:@RestController等同于给每个方法【额外加上@ResponseBody】
视图解析器
解析器种类
-
视图解析器:【JSTL:InternalResourceView】,ThymeleafView。
-
转发:InternalResourceView【forward:/testView】Servlet
-
重定向:RedirectView【Redirect:/testView】Servlet
配置JSP视图解析器
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 视图前缀 --> <property name="prefix" value="/WEB-INF/templates/"/> <!-- 视图后缀 --> <property name="suffix" value=".html"/> </bean>
配置thymeleaf
只需要thymeleaf-spring5依赖。
<!-- 配置Thymeleaf视图解析器 --> <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver"> <property name="order" value="1"/><!--视图优先级--> <property name="characterEncoding" value="UTF-8"/><!--编码--> <property name="templateEngine"><!--模板--> <bean class="org.thymeleaf.spring5.SpringTemplateEngine"><!--spring模板--> <property name="templateResolver"><!--模板解析器--> <!--spring资源模板解析器--> <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver"> <!-- 视图前缀 --> <property name="prefix" value="/WEB-INF/templates/"/> <!-- 视图后缀 --> <property name="suffix" value=".html"/> <property name="templateMode" value="HTML5"/><!--模板模式--> <property name="characterEncoding" value="UTF-8"/><!--编码--> </bean> </property> </bean> </property> </bean>
html使用thymeleaf
-
<html lang="en" xmlns:th="http://www.thymeleaf.org">:引入约束
th使用
-
<a th:href="@{/hello}">访问hello页面</a>:相对请求路径
-
servlet(username='admin',password=123456):设置参数
-
可以使用th的EL表达式。
欢迎页面
<welcom-file-list> <welcome-file>index.html\<welcome-file> </welcom-file-list>
页面异常
-
400,请求参数不匹配。
-
404,请求路径不匹配。
-
405,请求方式不匹配。
注解配置
注解配置本质
-
Servlet3.0会自动查找ServletContainerInitializer接口的实现类
-
Spring实现ServletContainerInitializer接口的类SpringServletContainerInitializer
-
SpringServletContainerInitializer查找WebApplicationInitializer接口的实现类
-
Spring3.2提供WebApplicationInitializer的实现抽象类AbstractAnnotationConfigDispatcherServletInitializer
web配置类使用
-
实现AbstractAnnotationConfigDispatcherServletInitializer
-
getRootConfigClasses:设置Spring配置
-
getServletConfigClasses:设置SpringMVC配置
-
getServletMappings:配置前端控制器路径
-
getServletFilters:设置过滤器
mvc配置类使用
-
实现WebMvcConfigurer
-
扫描组件:@ComponentScan("com.ycl")
-
注解驱动:@EnableWebMvc
-
视图解析器:ViewResolver【Bean】
-
视图控制器:addViewControllers
-
默认servlet:configureDefaultServletHandling.enable();
-
文件上传解析器:MultipartResolver【Bean】
-
拦截器:addInterceptors
-
异常处理:configureHandlerExceptionResolvers【bean】
Mybatis
只需要mybatis和数据区驱动。
调用方式
-
两个配置文件使用selectOne发送请求
-
两个配置文件加上接口使用getMapper获取代理类,调用对应方法执行
全局配置文件
解决mybatis核心配置文件。约束在官网拉取。
-
Conguration接口
基本实现
-
环境:事务处理器和数据源
-
找到映射文件
全局配置
-
propertis:引入外部资源【配合${}取数据】
-
优先级:1.方法参数。
-
优先级:2.外部文件引入。
-
优先级:3.标签里。】
-
-
settings:全局设置
-
mapUnderscoreToCamelCase:驼峰映射
-
jdbcTypeForNull:设置全局空值jdbc标识
-
lazyLoadingEnable:全局开启
-
aggressiveLazyLoading:关闭任何方法触发
-
cacheEnabled:全局缓存
-
-
typeAliases:给javaType起别名
-
1.直接指定。
-
2.包指定,别名为类名首字母小写或@Alias
-
-
typeHandler:类型处理器【源码】
-
plugins:拦截核心步骤【源码】
-
拦截Excutor。
-
拦截ParamenterHandler。
-
拦截StatementHandler。
-
拦截ResultSetHandler。
-
-
environments:环境配置
-
事务管理器
-
JDBC:jdbc的事务
-
MANAGED:容器事务
-
-
数据源
-
UNPOOL:不用池
-
POOL:使用池
-
JNDI:使用外部配置
-
-
-
databaseIdProvider:开启多数据库支持
-
mappers:找映射文件或注解
-
resource
-
url是全限定资源定位符
-
class是接口类的全限定类名。
-
-
package包下的所有映射文件或CRUD注解
-
-
objectFactory:对象工厂【创建结果对象时,通过该工厂实例化】
Mapper映射文件
解决mybatis核心配置文件。约束在官网拉取。
基本实现
-
mapper标注命名空间
-
CRUD的SQL语句标签
映射配置
-
CRUD【@Select,@Insert,@Update,@Delete】
-
#{}是预编译参数
-
flushCache清除一级二级缓存
-
timeout超时时间
-
statementType选择语句类型【非预编译,预编译,存储过程】
-
databaseId数据库厂商标识
-
-
resultMap:结果集映射
-
sql:抽取公共SQL
-
cache:开启二级缓存
-
cache-ref:引用外部缓存配置
增加修改
-
useCeneratedKeys:增加修改时生成值
-
keyProperty:主键值填充到属性
-
selectKey:增加修改【子标签】
-
keyProperty:替换增加修改字段值
-
resultType:返回值类型
-
order:增加修改之前或之后执行
-
查询
-
resultType封装结果集类型
-
resultMap引用外部的resultMap标签
-
useCache结果给二级缓存保存,
-
fetchSize返回结果条数限定建议
-
resultSetType结果集指针策略
typeHandler
参数处理
单个参数
-
直接取出:id=#{id}
多个参数
-
多个参数以arg0和param1作为key
-
参数起别名给arg0进行替换
POJO
-
属性名取值
Map
-
key取值
Collection
-
list和map都可以用collection作为key
-
list还可以用list作为key
数组
-
数组以array作为key
#和$
-
javaType
-
jdbcType
-
mode:存储过程
-
numericScale:数值范围
-
resultMap
-
typeHandler
-
jdbcTypeName
-
expression:未来扩展
结果处理
List
-
resultType类型为元素
POJO
-
resultType类型是类
Map
-
Map的key是列名,value是对应值【此处和OPJO相似】
-
resultType是map类型
Map
-
Map的key是主键,value是对应对象
-
resultType类型为元素
-
@MapKey("id"):标识Map集合的key
resultMap
映射类
<resultMap id="userMap" type="user"> <id property="" column=""/> <result property="" column=""/> </resultMap>
包含类属性
<resultMap id="userMap" type="user"> <id property="" column=""/> <result property="" column=""/> <result property="" column=""/>【属性类的属性表示】 </resultMap>
多表联查
一对一关联对象
<resultMap id="userMap" type="user"> <id property="" column=""/> <result property="" column=""/> <association property="属性" javaType="属性类型"> <id property="" column=""/> <result property="" column=""/> </association> </resultMap>
一对一分步查询
<resultMap id="userMap" type="user"> <id property="" column=""/> <result property="" column=""/> <association property="属性" select="关联查询的命名空间+id" column="列值传递"/> </resultMap>【分步查询是简单查询】
一对多关联查询
<resultMap id="userMap" type="user"> <id property="" column=""/> <result property="" column=""/> <collection property="" ofType=""> <id property="" column=""/> <result property="" column=""/> </collection> </resultMap>
一对多分步查询
<resultMap id="userMap" type="user"> <id property="" column=""/> <result property="" column=""/> <collection property="属性" select="关联查询的命名空间+id" column="列值传递"/> </resultMap>【分步查询是简单查询】
鉴别器
<discriminator javaType=""> <case value=""></case> </discriminator>【满足条件才会加上规则】
延迟加载
-
lazyLoadingEnable:全局开启
-
aggressiveLazyLoading:关闭任何方法触发
-
fetch="lazy"局部懒加载
多值传递
-
column="{deptId=id}"
动态SQL:OGNL
if
-
<if test=' '></if>
where
-
<where></where>包裹相当于where 1=1;
set
-
<set></set>包裹相当于去除尾部逗号
trim
-
<trim><trim>解决前缀和后缀规则
choose(when,otherwise)
-
<choose></choose>
-
<when test=""></when>
-
<otherwise></otherwise>
foreach
-
collection:集合
-
item:每一个遍历的元素
-
separator:每一个元素之间的分隔符
-
open:遍历结果开始字符
-
close:遍历结果结束字符
-
index:遍历List的时候是下标
-
遍历map
-
index:是key值
-
item:是value值
-
批量插入
-
遍历多条sql语句【allowmultiqueryies=true】
-
遍历values的值
内置参数
-
_parameter:
-
单个参数,这个内置参数就是它
-
多个参数,这个内置参数就是所有参数的map集合
-
-
_databaseId:
-
表示当前数据库
-
起别名之后,代表当前数据库的别名
-
变量绑定
参数拼接绑定 <bind name="_last" value="'%'+last+'%'"/>
缓存
一级缓存失效
-
不是同一个SqlSession
-
同一个SqlSession,查询条件不同
-
同一个SqlSession,执行了一次操作
-
同一个SqlSession,清除缓存了。【clearCache方法】
二级缓存数据来源
-
一级缓存关闭,就会存入二级缓存
二级缓存失效
-
cacheEnabled:关闭二级缓存
-
useCache:关闭SQL语句的二级缓存
-
flushCache:操作SQL刷新缓存
二级缓存查询顺序
-
二级缓存
-
一级缓存
-
查询数据库
二级缓存开启
-
cacheEnabled:全局缓存
-
<cache/>:配置二级缓存
整合二级缓存
只需要encache和mybatis-encache依赖
-
<cache type="配置上Encache就行"/>
逆向工程
只需要mybatis-generator-core依赖。MyBatis Generator Core – MyBatis Generator Quick Start Guide
运行原理
SqlSessionFactoryBuilder的build方法返回DefaultSqlSessionFactory
-
结合被解析对象返回XMLConfigBuilder
-
解析对象返回Configuration对象
-
CRUD标签解析:MappedStatements
-
接口信息:mapperRegistry:
-
-
执行build方法返回SqlSessionFactory
-
调用DefaultSqlSessionFactory(Configuration)
-
build.openSession()返回DefaultSqlSession对象
-
创建执行器this.configuration.newExecutor(tx, execType)
-
缓存执行器包装
-
excutor拦截器链【】【】【】
-
-
创建SqlSession对象new DefaultSqlSession(this.configuration, executor, autoCommit)
-
【】Executor的execType执行器类型取值【】
-
simple:简单
-
REUSE:重用
-
BATCH:批量
-
sqlSession.getMapper(UserMapper.class)
-
mapperRegistry根据接口类型获取MapperProxyFactory
-
创建MapperProxy对象
-
返回动态代理MapperProxy
mapper.findAll()
-
判断CRUD,判断返回结果集
-
参数转换成SQL参数
-
获取statement语句
-
SQL绑定成为完整句子
-
Query执行【二级缓存】
-
doQuery
-
创建StatementHandler
-
创建RoutingStatementHandler
-
paramer拦截器链【】【】【】
-
resultSet拦截器链【】【】【】
-
-
Statement拦截器链【】【】【】
-
-
处理预编译SQL语句
-
执行SQL语句
-
插件InterceptorChain
框架调用拦截器链原理
-
InterceptorChain遍历Interceptor
-
执行Interceptor的plugin(四个处理器对象)
自定义插件
-
实现Interceptor接口
Interceptor接口方法
plugin方法
return Plugin.wrap(target, this) 1. 获取签名映射 1. 获取Intercepts注解 2. 获取签名每一项Signature 3. 遍历每一个标签,Map<Class<?>, Set<Method>> 【签名中所有的类型和方法都封装到Map中】 2. 获取target类型 3. 获取所有接口 【目标类是所有接口和所有签名进行匹配】 4. 生成代理对象【匹配上生成增强对象,否则直接返回】 【给适配方法执行】 this.interceptor.intercept(new Invocation(this.target, method, args)) 调用当前的intercept方法
intercept方法
Invocation的proceed():是调用原始方法
使用
拦截器类书写
@Intercepts(@Signature(type = StatementHandler.class,method ="batch",args = {})) public class MyInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { Object proceed = invocation.proceed();//这里做增强 return proceed; } @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { Interceptor.super.setProperties(properties); } }
配置拦截器
<plugins> <plugin interceptor="com.ycl.interceptor.MyInterceptor"></plugin> </plugins>
多个插件
-
目标方法在intercept方法中嵌套。
分页
只需要pagehelper和jsqlparser两个依赖。
-
配置中添加拦截器PageInterceptor
调用
-
原生API:SqlSession(new RowBounds(0,10))【将RowBounds传到指定参数位置】
-
mapper方式一:查询之前使用PageHelper.startPage(0,10)
-
mapper方式二:查询之前使用PageHelper.offsetPage(0,10)
-
注解不需要xml处理:@Param("pageNum") pageNum和@Param("pageSize") pageSize
-
【只要请求参数中能取到这两个值就可以】
【PageInfo包装处理分页结果】
执行器
-
批量保存:BatchExcutor会让数据库保存预编译保存语句,修改参数值进行保存。
-
Spring中使用批量操作,注册SqlSessionTemplate【并且指定Excutor】
存储过程
解决多个sql语句的集合。
-
调用statementType="CALLABLE"
-
语法:{call 存储函数(#{名称,mode=,jdbcType=})}
TypeHandler
定义
-
实现TypeHandler接口或继承BaseTypeHandler类
-
@MapperType:定义java类型
-
@MapperJdbcType:定义jdbc类型
使用
-
使用方式一:自定义结果集,参数处理的时候【resultMap和#{id,typeHandler=xxxx}】
-
使用方式二:全局配置【handler使用类型处理器,javaType是某个类型时候使用】
MybatisPlus
只需要mybatisplus依赖。内部包含mybatis和mybatis-spring依赖。
【Mybatis3.5.0之后就不支持GlobalConfiguration了,支持yum】
使用
-
前提条件mybatis和spring整合完成。
-
将SqlSessionFactoryBean修改成MybatisSqlSessionFactoryBean
BaseMapper
-
Mapper接口继承BaseMapper<javaBean>接口
-
可以调用BaseMapper中的方法
方法
-
【增加】
-
insert:非空字段才会出现在sql语句中
-
insertAllColumn:所有的字段都会出现在sql语句中
-
【修改】
-
updatteById:非空字段才会出现在sql语句的修改字段中
-
updateAllColumnById:所有的字段都会出现在sql语句修改字段中
-
【查询】
-
selectById:传入序列化类型的id,id作为查询条件
-
selectOne:传入一个对象,非空字段作为条件
-
selectBatchIds:传入collection的id集合,id作为枚举查询条件
-
selectByMap:传入map集合,key=value作为条件
-
selectPage:传入的RowRounds和wrapper条件。逻辑分页查询
-
【删除】
-
deleteById:传入序列化类型的id,id作为条件
-
deleteByMap:传入map集合,key=value作为条件
-
deleteBatchIds:传入collection的id集合,id作为枚举查询条件
条件构造器
使用数据库的字段而不是java属性。EntityWrapper类
结构
-
wrapper和AbstractWrapper【抽象父类】
-
UpdateWrapper【查询】【删除】
-
QueryWrapper【修改】
-
【三元素:condition,column,param】
-
AbstractLambdaWrapper
-
LambdaUpdateWrapper
-
LambdaQueryWrapper
-
方式一
-
QueryWrapper qw= new QueryWrapper();
-
qw.eq();
-
【原始方式】
方式二
-
QueryWrapper<User> qw= new QueryWrapper();
-
qw.lambda().eq();
-
【使用Lambda表达式】
方式三
-
LambdaQueryWrapper<User> lqw= new LambdaQueryWrapper();
-
lqw.eq();
-
【使用Lambda表达式】
注解
-
@TableId:主键策略IdType【value和列名一致】
-
AUTO:自增
-
NONE:用户自己输入
-
INPUT:用户自己输入
-
ASSIGN_ID:全局唯一ID,自动填充
-
ASSIGN_UUID:全局唯一ID,自动填充
-
-
@TableName:主要起别名
-
@TableField:字段
-
value:字段名映射
-
exist:是否存在表字段
-
全局配置
核心API:GlobalConfiguration,加入到SqlSessionFactoryBean中。
-
驼峰映射:dbColumnUnderline
-
主键策略:idType
-
表的前缀:tablePrefix
其他使用
-
插入修改获取返回主键,直接获取就可以。
MP原理
-
MapperProxy:代理对象
-
SqlSessionFactory:会话工厂
-
Configuration:配置信息
-
MapperStatements:所有的SQL语句
BaseMapper的sql语句自动注入原理【AutoSqlInjector】
-
获取configuration中的sqlInjector配置(只能一个)
-
AutoSqlInjector的injectSql方法所有增强分发
-
最终用addMappedStatement方法【可以在该环节增强】模仿作业
LogicSqlInjector逻辑删除
-
将LogicSqlInjector注入到SqlSessionFacotry中
-
并且配置逻辑删除值,删除标签和非删除标签
-
@TableLogic逻辑删除delval表示逻辑删除标签
活动记录
ArtiveRecord
实体类去继承Model类就可以使用实体自己的CRUD操作
代码生成器
需要velocity-engine-core【模板引擎】或freemark依赖
可以生成domain,mapper,mapper映射,还可以生成service,controller。
-
全局配置:GlobalConfig
-
数据源配置:DataSourceConfig
-
策略配置:StrategyConfig
-
包名配置:PackageConfig
-
整合配置:AutoGenerator
-
执行:autoGenerator.execute();
示例
public static void main(String[] args) { // 1.全局配置 GlobalConfig config = new GlobalConfig(); config.setActiveRecord(true) .setAuthor("YCL") .setOutputDir("D:\\mybatis-plus\\mpg\\src\\main\\java") .setFileOverride(true) .setIdType(IdType.AUTO) .setServiceName("%Service") .setBaseResultMap(true) .setBaseColumnList(true); // 2.设置数据源 DataSourceConfig dataSourceConfig = new DataSourceConfig(); dataSourceConfig.setDbType(DbType.MYSQL) .setDriverName("com.mysql.cj.jdbc.Driver") .setUrl("jdbc:mysql:///jdbc_template?serverTimezone=Asia/Shanghai") .setUsername("root") .setPassword("root"); // 3.策略配置 StrategyConfig strategyConfig = new StrategyConfig(); strategyConfig.setCapitalMode(true) .setDbColumnUnderline(true) .setNaming(NamingStrategy.underline_to_camel) // .setTablePrefix("tb_") .setInclude("user"); // 4.包名配置 PackageConfig packageConfig = new PackageConfig(); packageConfig.setParent("com.ycl") .setMapper("mapper") .setService("service") .setController("controller") .setEntity("domain") .setXml("mapper"); // 5.整合配置 AutoGenerator autoGenerator = new AutoGenerator(); autoGenerator.setGlobalConfig(config) .setDataSource(dataSourceConfig) .setStrategy(strategyConfig) .setPackageInfo(packageConfig); // 6.执行 autoGenerator.execute(); }
ServiceImpl
分页插件
分页插件:PaginationInteceptor
配置
-
将PaginationInteceptor插件注册
-
并且将插件传入到Configuration中
使用
-
创建一个page对象传入分页查询方法中【page是RowBounds的子类】
-
page就可以直接获取所有page信息
其他插件
-
全表操作拦截
<bean class="com.baomidou.mybatisplus.plugins.SqlExplainInterceptor"> <property name="stopProceed" value="true"/> </bean>
-
慢SQL处理
<bean class="com.baomidou.mybatisplus.plugins.PerformanceInterceptor"> <property name="format" value="true"/> <property name="maxTime" value="1"/> </bean>
-
乐观锁插件
必须使用@Version标记版本 <bean class="com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor"/>
公共字段填充
元素据处理器接口MetaObjectHandler
-
注解填充@TableFile(fill=FieldFill.INSERT)
-
自定义公共字段填充器MetaObjectHandler子类
-
MP全局配置注入填充器
MybatisX插件
-
MybatisX代码生成器
-
MybatisX快速添加CRUD
Maven
安装配置
Mvaen工具也可以叫做软件的安装配置。
安装
-
Maven是apache的一个软件
配置
-
需要配置JAVA_HOME
-
设置自身的MAVEN_HOME
-
mvn -v检测安装成功
目录
-
bin:可执行命令
-
boot:Maven类加载器框架
-
conf:配置
-
lib:Maven所需要的依赖支持
-
LICENSE,NOTICE,README.tx:第三方软件介绍
功能配置
局部setting.xml放在repository同目录下
-
本地缓存位置【settings:<localRepository>】
-
maven下载镜像
-
maven选用jdk版本
镜像 <mirror> <id>aliyunmaven</id> <mirrorOf>*</mirrorOf> <name>阿里云公共仓库</name> <url>https://maven.aliyun.com/repository/public</url> </mirror> 或者 <mirror> <id>aliyunmaven</id> <mirrorOf>central</mirrorOf> <name>阿里云公共仓库</name> <url>https://maven.aliyun.com/nexus/content/groups/public</url> </mirror>
JDK版本 <profile> <id>jdk1.8</id> <activation> <activeByDefault>true</activeByDefault> <jdk>1.8</jdk> </activation> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion> </properties> </profile>
IDEA配置Maven
-
maven软件位置
-
settings.xml位置
-
localRepository位置
工作原理
-
pom.xml文件生成对应的pom对象
-
依赖管理模型,本地仓库管理jar包
-
私服仓库管理jar包
-
中央仓库下载jar包
-
Maven构建生命周期插件
Maven作用
-
依赖管理工具
-
依赖构建工具
-
依赖分享工具
-
自动部署环节
1. 依赖管理工具 【原来】使用jar包依赖,将jar包放入WEB-INF/libs下面 【现在】 1. Maven中央仓库下载到Maven本地仓库 2. 本地仓库导入jar包 2. 依赖构建工具 打包成jar包或war包 3. 依赖分享工具 Nexus私服传递依赖 4. 自动部署环节 从Maven推送到Git远程仓库 持续集成Jenkins 部署云原生kubernates到Docker实例
依赖管理工具
问题
-
jar包不规范
-
jar包之间依赖关系
-
必须存储到指定位置lib
GAVP属性
-
groupId:com.公司.主业务.子业务
-
artifactId:产品-模块
-
version:主版本.次版本.修订号.里程碑版本【API修改,功能增强,bug修复,RELEASE】
-
package:jar,war,pom【普通工程,web工程,父工程不打包】
依赖传递
-
直接依赖:配置文件中写了的依赖
-
间接依赖:配置文件的依赖,这个依赖还有依赖
-
依赖越直接层级越浅,优先级越高
-
依赖相同层级,前面配置的优先级高
-
同一个依赖配置,后面的依赖覆盖前面的依赖
-
<optional>true</optional>隐藏依赖不被传递
-
排除依赖<exclusion>GAV</exclusion>
-
【模块只有打包之后才能用】
依赖范围
Scope
-
主程序
-
测试程序
-
是否参与打包
选项
-
compile:主代码,测试,打包【log4j】
-
test:只测试【junit】
-
runtime:只打包【jdbc】
-
provided:不打包【servlet-api】
模块聚合
-
不打包pom
-
<modules>来引入聚合的项目【../项目名:同级目录】
继承依赖
-
模块继承<parent>GAV加上<relativePath>父工程pom文件</relativePath></parent>
-
父工程的<dependencyManager>管理依赖版本
属性管理
-
定义:<properties><spring.version>5.2.0.RELEASE</spring.version></properties>
-
使用:${spring.version}
-
还有:Maven内置属性,setting属性,java系统属性,env环境变量【mvn help:system】
properties使用POM配置属性
-
<resources>\将pom配置属性也用到properties【指向指定的resources目录】【过滤拦截true】</resources>
多环境
-
定义:<profile>
-
<id>dep_env
-
<activation>true默认配置
-
-
使用:Command line:install -P dep_env
项目构建工具
插件
使用IDEA的时候,构建是IDEA帮我们构建的。
Maven构建:清理,编译,测试,报告,打包,部署。
插件有包在官网查看
clean阶段
-
pre-clean:清理之前
-
clean:清理
-
post-clean:清理之后
default阶段
-
validata:校验
-
initialize:初始化
-
generate-sources:生成源码
-
process-sources:处理源码
-
generate-resources:生成源文件
-
process-resources:处理源文件
-
compile:源代码【编译】
-
process-classes:处理类文件
-
generate-test-sources:生成测试源码
-
process-test-sources:处理测试源码
-
generate-test-resources:生成测试源文件
-
process-test-resources:处理测试源文件
-
test-compile:测试源码【编译】
-
process-test-compile:处理测试类文件
-
test:执行测试代码【测试】
-
prepare-package:准备打包
-
package:【打包】
-
pre-integration-test:集成测试前
-
integration-test:集成测试
-
post-integration-test:集成测试后
-
verify:验证
-
install:打包上传到本地库【安装】
-
deploy:打包上传到远程库【部署】
site阶段
-
pre-site:生成站点文件前
-
site:生成站点文件
-
post-site:生成站点文件后
-
site-deploy:生成站点文档部署到服务器【服务器】
目录结构
web目录结构
1. 原始目录【项目】 1. src【源代码】之后会存放到WEB-INF下 2. web【静态文件】 1. WEB-INF【不被直接访问的资源】 1. libs【依赖包】 2. web.xml【配置文件】 2. 编译目录【out/artifacts/项目war包】 1. WEB-INF 1. classes 2. libs 3. web.xml
Maven目录
-
pom.xml
-
src(main,test)
-
main(java,reources)
-
webapp
-
WEB-INF
-
web.xml
-
-
index.html
-
-
-
test(java,resource)
-
跳过测试
解决场景
-
整体模块未开发完毕
-
模块某个功能为开发完毕
-
单个功能调试导致其他功能失败
-
打包加速
实现
-
mvn install -D skipTests【跳过所有测试】
-
点击test横线也可以跳过
Nexus私服
SpringBoot
只需要spring-boot-starter-web一个依赖
解决问题
-
提供大量默认配置
-
内嵌web服务器
-
监控健康检查
启动Boot
-
pom文件
-
parent:spring-boot-starter-parent
-
dependency:spring-boot-starter
-
主类
-
@SpringBootApplication
-
SpringApplication.run(主类,参数);
父依赖
-
最顶层父项目管理了依赖版本【主要依赖】
-
直接父项目管理插件版本【主要插件】
依赖配置
-
web场景启动器:spring-boot-starter-web
-
打jar包插件:spring-boot-maven-plugin
启动项目
-
java -jar springboot的jar包
启动类
main方法中SpringApplication运行返回的是IOC容器
spring-boot-autoconfigure
注解@SpringBootApplication
-
@SpringBootConfiguration
-
Configuration
-
proxyBeanMethods设置true:单例【Full模式】
-
proxyBeanMethods设置false:多例【Lite模式】
-
-
-
@EnableAutoConfiguration【自动配置选取】
-
@AutoConfigurationPackage
-
@Import(AutoConfigurationPackages.Registrar.class)【将启动类所在包下的组件全部导入到容器】
-
-
@Import(AutoConfigurationImportSelector.class)【筛选导入】
-
autoconfigure的META-INF/spring-factories文件的127个场景启动器
-
@Condition满足才生效,筛选组件
-
-
-
@ComponentScan
组件配置
-
@Import:引入配置类
-
@Conditional:条件注入组件
-
@ImportResource:导入资源【将xml加入进去】
-
@ConfigurationProperties:组件才能使用配置绑定【核心配置】
-
@EnableConfigurationProperties:有注入到容器和配置绑定【核心配置】
配置特性
-
自定义会覆盖
-
ServletWebServerFactoryCustomizer自定义器
相关工具
lombok
实体类的相关方法。
-
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
-
lombok插件
-
相关注解
-
@Slf4j
-
@Data
-
@Getter
-
@Setter
-
@ToString
-
@EqualsAndHashCode
-
@RequiredArgsConstructor
-
@AllArgsConstructor:全参构造
-
@NoArgsConstructor:无参构造
-
-
-
Dev-tools
热部署
-
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency>
yml配置
语法
-
【k: v】基本语法冒号后面有空格,不能tab缩进代替
-
缩进代表上下级关系
-
注释#
-
单引号转义
-
双引号不转义
表示
-
对象,map
-
k: {k1: v1,k2: v2,k3: v3}
-
k: k1: v1 k2: v2 k3: v3
-
-
数组,单列集合
-
k: {v1,v2,v3}
-
k: -v1 -v2 -v3
-
提示
-
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> </dependency>
MVC
静态资源
WebMvcAutoConfiguration
静态资源位置
-
默认classpath下:
-
/static
-
/public
-
/resources
-
/META-INF/resources
-
-
因为它使用ResourceHttpHandler
-
修改资源位置:spring.resource.static-locations=classpath/xxx/xx
静态资源访问
-
默认访问:/**
-
修改默认路径:spring.mvc.static-path-pattern=/xxx/xx
欢迎页
自定义静态资源路径会影响欢迎页面
-
默认在静态资源中找到:index.html
-
默认找到template处理:/index
-
默认图标:favicon.ico资源