Java实战班Lite
2024-12-26 17:08:04 0 举报
AI智能生成
comZhang
作者其他创作
大纲/内容
javaSE
基础知识点
介绍
三大技术平台
j2se
j2me
j2ee
CMD窗口
打开方式
win +R
win +e 搜索 cmd
常用命令
进盘符 根目录
D:
cd \
列出目录下所有内容
dir -->directory 目录
改变当前所在目录
cd -->change directory
cd .当前目录
cd .. 上级目录
cd .. 上级目录
cd \ 回到根目录
清除屏幕
cls --> clear screen
退出命令行
exit
Path环境变量
设置里找-环境变量-系统变量
Path里添加jdk17\bin,并且放到第一位
独自添加JAVA_HOME 地址-jdk17(没有bin)
注释
单行注释 // Ctrl+/
多行注释 /* CtrL+Shitft+/
文档注释 /**
多行注释 /* CtrL+Shitft+/
文档注释 /**
快捷键
Ctrl+Shilft-R 全文搜索文件
Ctrl+H 全局搜索文件里的内容
Ctrl+F 搜索和替换关键字
Ctrl+L 跳转到某行
Ctrl+E 快速切换文件
Ctrl+O 查看方法或属性
Ctrl+D 删除行
Ctrl+K 搜索前进
Ctrl+Shift+K 搜索后退
Alt+Shift +R 重命名文件和模块名 (重构)
Ctrl+Shift+Y 是大小写转换
命名约定
全小写
包名
小驼峰
变量名,方法名,形参名
大驼峰
类 (文件名),接口
全大写
常量
ASCLL码
- ‘0’ 48 0-9是连续的
- ‘A’ 65 A-Z是连续的
- ‘a’ 97 a-z是连续的
- ‘A’ 65 A-Z是连续的
- ‘a’ 97 a-z是连续的
字符串拼接
”+“ 从左到右只要接触到String后才是连接作用,否则一直是加法
是不断在开辟新空间,不断的在new ,效率低,所以就可以用StringBuider来拼接
是不断在开辟新空间,不断的在new ,效率低,所以就可以用StringBuider来拼接
基础语法
变量:存储区域(也是一个容器只是小)
没有应用指向,则就会被回收
没有应用指向,则就会被回收
字面量
运算符
赋值运算符
关系运算符
逻辑运算符
算数运算符
隐式转换
byte + byte = int
Short + short =int
Byte + short =int
char + 某 =int
Short + short =int
Byte + short =int
char + 某 =int
根据类型的容量范围(容量小自动升为容量大的数据类型)
byte、short、Int --> long --> float --> double
byte、short、Int --> long --> float --> double
强制类型转换
1.将容量大的类型转化为容量小的类型
子主题
三元运算符
例子
逢 7 过
取最值
标识符
· 标识符必须以字母(A-Z 或 a-z)、美元符号($)或下划线(_)开头,不能以数字开头。
· 除第一个字符外,标识符的其余部分可以是字母、美元符号、下划线或数字(0-9)。
· 标识符不能是 Java 的关键字(如 abstract、class 等)。
· 标识符区分大小写。
· 除第一个字符外,标识符的其余部分可以是字母、美元符号、下划线或数字(0-9)。
· 标识符不能是 Java 的关键字(如 abstract、class 等)。
· 标识符区分大小写。
小知识点
GUI开发
JFrame
setSize 设置窗口大小
setTitle 设置窗口标题
setLocationRelativeTo
设置窗口默认位置-->null--正中间展示
设置窗口默认位置-->null--正中间展示
setDefaultCloseOperation
设置运行窗口默认关闭的行为--> 3--点击关闭即可退出运行结果
设置运行窗口默认关闭的行为--> 3--点击关闭即可退出运行结果
setAlwaysOntop
设置窗口置顶
设置窗口置顶
setLayout
取消窗口的默认布局
取消窗口的默认布局
setVisible--是否显示
JF.add() 告诉此窗口应该添加什么东西
(放到最下边)
(放到最下边)
jf.repaint(); 重新绘制(刷新)
JButton
setSize 按钮大小
setLocation 按钮所处窗口位置
setBounds() 以上大小和位置 可以使用一个方法(API)来实现
对按钮绑定事件 jb.addActionListrner(new AbstractAction()){}
Jlable
setBounds
插入图片
ImageIcon icon = new ImageIcon("D:\\桌面\\D盘\\Idea.png");
用\\双斜杠 不然可能会成为转义字符
JLabel imgJl = new JLabel(icon);
ImageIcon icon = new ImageIcon("D:\\桌面\\D盘\\Idea.png");
用\\双斜杠 不然可能会成为转义字符
JLabel imgJl = new JLabel(icon);
JTextField
setBounds
JPanel
removeAll()
JOptionPane.showMessageDialog( Jframe,”提示语“)
给出提示弹窗 可放在事件里
给出提示弹窗 可放在事件里
事件监听
事件源,事件,事件绑定
main 方法先执行完了,但是每次点击都会有显示,所以每次点击都会执行一边main方法
所以 点击的生命周期比 main 方法时间长 (所以不能写普通的 total 类型)
所以 点击的生命周期比 main 方法时间长 (所以不能写普通的 total 类型)
关键词
new(实例化)
this
this-->s1(这个地址/引用) --对象--
static
abstract
--抽象类不能被实例化
--抽象类一定有构造器
--抽象类里可以没有抽象方法,
但是如果类里有抽象方法,则该类一定是抽象类
--抽象类的子类,要么实现父类的所有抽象方法,要么也定义成抽象类
--抽象类一定有构造器
--抽象类里可以没有抽象方法,
但是如果类里有抽象方法,则该类一定是抽象类
--抽象类的子类,要么实现父类的所有抽象方法,要么也定义成抽象类
final
final关键字可以修饰类、成员变量、成员方法
>>修饰类
则代表类不能被继承
>>修饰成员变量
则代表是一个常量【不能变的量】
不能变,指的是变量的值不能变,若变量为引用类
型,只要地址值不变则可以,其内容可以变化
>>修饰成员方法
代表方法不能被重写
>>修饰类
则代表类不能被继承
>>修饰成员变量
则代表是一个常量【不能变的量】
不能变,指的是变量的值不能变,若变量为引用类
型,只要地址值不变则可以,其内容可以变化
>>修饰成员方法
代表方法不能被重写
可变参数
1.概念:
可变参数又称参数个数可变,用作方法的形参
2.应用场景:
当你确定了某个方法参数是什么类型,但是不知道个数是多少个时候
可以考虑使用可变参数
3.当可变参数有重载的方法
JAVA遵循精确原则进行方法调用
4.可变参与只能写到最后一个方法参数上;
可变参数又称参数个数可变,用作方法的形参
2.应用场景:
当你确定了某个方法参数是什么类型,但是不知道个数是多少个时候
可以考虑使用可变参数
3.当可变参数有重载的方法
JAVA遵循精确原则进行方法调用
4.可变参与只能写到最后一个方法参数上;
lambda
【函数式编程接口】
【函数式编程接口】
>格式:
* (形式参数)->{代码块}
* 括号 --该接口中唯一方法的 形参列表
【如果参数只有一个】,可省略();参数类型可写可不写,顺序会对应
【如果代码执行体只有一行】,可省略 { };
【如果需要返回且只有一行】,可省略return和 { } 直接 ->返回值
>使用前提:
1.得有一个接口
2.接口中只能有一个方法
2.Lambda表达式的转换目标只能是接口,父类不可以
>也可以直接调用类里的方法 参数一个,只调用一个方法
values.forEach(System.out::println);不用加( );
* (形式参数)->{代码块}
* 括号 --该接口中唯一方法的 形参列表
【如果参数只有一个】,可省略();参数类型可写可不写,顺序会对应
【如果代码执行体只有一行】,可省略 { };
【如果需要返回且只有一行】,可省略return和 { } 直接 ->返回值
>使用前提:
1.得有一个接口
2.接口中只能有一个方法
2.Lambda表达式的转换目标只能是接口,父类不可以
>也可以直接调用类里的方法 参数一个,只调用一个方法
values.forEach(System.out::println);不用加( );
>函数式编程思想概述
>>函数--传个东西进来,返回一个值 <--> 方法 --传一个值 返回一个值 本质一样
* 在数学中,函数就是有输入量,输出量的一套计算方案或规划,也就是“拿数据做操作”
* 面向对象思想 强调“必须通过对象的形式来做事情”
* 函数式思想尽量忽略面向对象的复杂语法:“强调做什么,而不是以什么形式去做”
*而我们学习的Lambda 表达式就是函数式思想的一种体现。
--- lambda表达式 也叫【函数式编程】 不接受参数,不返回数值
使用Lambda表达式 形参为 Consumer<? super String>>action
--就是Lambda表达式 [消费性接口](只接收不返回)
>>接口分类
[消费性接口](只接收不返回)-----[提供型接口](不提供但输出)
[函数型接口](有进有出)----[断言型接口](只返回true或false)
>>>接口
Predicate<? super String> predicate <-->【断言型接口】 Predicate里有一个抽象方法
Consumer<? super String>>action <-->【消费性接口】 Consumer里有一个抽象方法
Supplier<T> <--> 【提供型接口】
Function<T, R> <--> 【函数型接口】
>>函数--传个东西进来,返回一个值 <--> 方法 --传一个值 返回一个值 本质一样
* 在数学中,函数就是有输入量,输出量的一套计算方案或规划,也就是“拿数据做操作”
* 面向对象思想 强调“必须通过对象的形式来做事情”
* 函数式思想尽量忽略面向对象的复杂语法:“强调做什么,而不是以什么形式去做”
*而我们学习的Lambda 表达式就是函数式思想的一种体现。
--- lambda表达式 也叫【函数式编程】 不接受参数,不返回数值
使用Lambda表达式 形参为 Consumer<? super String>>action
--就是Lambda表达式 [消费性接口](只接收不返回)
>>接口分类
[消费性接口](只接收不返回)-----[提供型接口](不提供但输出)
[函数型接口](有进有出)----[断言型接口](只返回true或false)
>>>接口
Predicate<? super String> predicate <-->【断言型接口】 Predicate里有一个抽象方法
Consumer<? super String>>action <-->【消费性接口】 Consumer里有一个抽象方法
Supplier<T> <--> 【提供型接口】
Function<T, R> <--> 【函数型接口】
数据类型
相互转换
理解
方法都是包装类的方法,基本类型没有方法
valueof(),哪种包装类调用则转成哪种对应基本类型--装箱
intvalue(),longVlaue(),调用者是包装类型对象,就用该对应 基本类型+Value() --拆装
String 转换成基本 用对应的包装类的parse+包装类型
字符串才涉及到parse ,
valueof(),哪种包装类调用则转成哪种对应基本类型--装箱
intvalue(),longVlaue(),调用者是包装类型对象,就用该对应 基本类型+Value() --拆装
String 转换成基本 用对应的包装类的parse+包装类型
字符串才涉及到parse ,
int age =18; long l=2L;
//Ingeger age =new Integer(18)-->报错,
jdk17之后不能这样写,所以换方式包装
//Ingeger age =new Integer(18)-->报错,
jdk17之后不能这样写,所以换方式包装
【显示】装箱
Integer num1=Integer.valueof(age)
Long l1=Long.valueof(l);
Long l1=Long.valueof(l);
【显示】拆箱
int num11=num1.intValue();
long l11=l1.longValue();
long l11=l1.longValue();
字符串转数值类型
如果想转成 int 则
int num2=Integer.parseInt(name);
如果想转成 long 则
long l2=Long.parseLong(name);
int num2=Integer.parseInt(name);
如果想转成 long 则
long l2=Long.parseLong(name);
数值类型转字符串
String str =String.valueOf(num2);
基本数据类型
数值型
整形
byte
short
int
long
浮点型
float
double
字符
char
非数值型
boolean
引用数据类型
类 Class
String
接口 interface
数组
枚举
集合
方法
格式、方法签名(方法名、形参)
权限修饰符 【其他关键符】 返回值类型 方法名(形参列表)【throws 异常类型】{
//方法体
}
//方法体
}
技术文档
方法重载
①在同一类
②相同方法名
③参数不同(类型或者数量不同)
②相同方法名
③参数不同(类型或者数量不同)
构造方法
当我们实例化对象的时候,JVM(java virtual machine ) 虚拟机自动会调用
有了构造方法才可以创造对象
可以做初始化(封装)
如果没有定义构造方法,系统会给出一个默认的无参数构造方法
如果定义了构造方法,系统不再提供默认的构造方法
return
退出方法,中止程序
在方法中返回给外界的数据
方法重写
- 1、方法重写概念
- 子类出现了和父类中一模一样的方法声明(方法名一样,参数列表也必须一样)
- 2、方法重写的应用场景
- 当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方
法,这样,即沿袭了父类的功能,又定义了子类特有的内容
- 3、Override注解
- 用来检测当前的方法,是否是重写的方法,起到【校验】的作用
【方法重写注意事项】
* 1.父类的private不能被重写,因为压根就没有继承过来.
* 2.子类的重写方法的权限不能比父类小
* 3.静态方法不参与重写,谁的静态方法就是谁的类
- 子类出现了和父类中一模一样的方法声明(方法名一样,参数列表也必须一样)
- 2、方法重写的应用场景
- 当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方
法,这样,即沿袭了父类的功能,又定义了子类特有的内容
- 3、Override注解
- 用来检测当前的方法,是否是重写的方法,起到【校验】的作用
【方法重写注意事项】
* 1.父类的private不能被重写,因为压根就没有继承过来.
* 2.子类的重写方法的权限不能比父类小
* 3.静态方法不参与重写,谁的静态方法就是谁的类
数据结构
栈 内存
堆 内存
常量区
队列
树
链表
图
哈希表
面向对象
成员变量与局部变量
区别
区别
① 类中位置不同
成员变量-->在 类 中方法外
局部变量-->在 方法/参数 中
成员变量-->在 类 中方法外
局部变量-->在 方法/参数 中
② 默认值
成员变量自动分配默认值
局部变量没有默认值(需要初始化)
成员变量自动分配默认值
局部变量没有默认值(需要初始化)
③ 内存区域不同
成员变量--> 堆
(可以是公共的,所以放在堆里,而不是方法里)
局部变量--> 栈
成员变量--> 堆
(可以是公共的,所以放在堆里,而不是方法里)
局部变量--> 栈
④ 生命周期不同
成员变量随 对象 的创建而存在,随 对象 的消失而消失
局部变量随 方法 的创建而存在,随 方法 的消失而消失
成员变量随 对象 的创建而存在,随 对象 的消失而消失
局部变量随 方法 的创建而存在,随 方法 的消失而消失
三大特征
封装
>封装好处
通过方法来控制成员变量的操作,提高了代码的安全性
把代码用方法进行封装,提高了代码的复用性
通过方法来控制成员变量的操作,提高了代码的安全性
把代码用方法进行封装,提高了代码的复用性
权限修饰符
public 公开
protected 可以子类 和同包
缺省 同包
private 只能自己类
protected 可以子类 和同包
缺省 同包
private 只能自己类
继承
1.使用 extends 关键字实现继承
2. java 单继承
3.继承当中的成员变量 遵循就近原则 先从局部范围找
4.当创建子类对象的时候,JVM默认先创建它的父对象
即 当子类调用构造方法之前隐式创建了父类的构造方法
super要放到第一行.
2. java 单继承
3.继承当中的成员变量 遵循就近原则 先从局部范围找
4.当创建子类对象的时候,JVM默认先创建它的父对象
即 当子类调用构造方法之前隐式创建了父类的构造方法
super要放到第一行.
- 继承好处
- 提高了代码的复用性(多个类相同的成员可以放到同一个类中)
- 提高了代码的维护性(如果方法的代码需要修改,修改一处即可)
- 继承弊端
- 继承让类与类之间产生了关系,类的耦合性增强了,当父类
发生变化时子类实现也不得不跟着变化,削弱了子类的独立性
- 提高了代码的复用性(多个类相同的成员可以放到同一个类中)
- 提高了代码的维护性(如果方法的代码需要修改,修改一处即可)
- 继承弊端
- 继承让类与类之间产生了关系,类的耦合性增强了,当父类
发生变化时子类实现也不得不跟着变化,削弱了子类的独立性
//概括面越广,说明【泛化】了,越父类,泛化度越大
//继承是一种is...a的关系 【is...a】翻译过来就是【是一个...】
//像班级、学生这种关系来说 [has...a] 【有一个...】 组合关系,整合部分关系、包含关系
//继承是一种is...a的关系 【is...a】翻译过来就是【是一个...】
//像班级、学生这种关系来说 [has...a] 【有一个...】 组合关系,整合部分关系、包含关系
多态
多态的前提:
* 1.要有继承(extends) 、或者实现(implements)关系
* 2.要有方法的重写;
* 3.要有父类应用指向子类对象;
* 满足以上条件即可出现多态
* 1.要有继承(extends) 、或者实现(implements)关系
* 2.要有方法的重写;
* 3.要有父类应用指向子类对象;
* 满足以上条件即可出现多态
成员属性在多态下的特点:编译、运行都看左边
成员方法在多态下的特点:编译看左边,运行看右边
成员方法在多态下的特点:编译看左边,运行看右边
三、多态的好处与坏处
* 好处:程序的扩展性增强了,定义方法的时候 ,可以使用父类
型作为参数,在使用的时候,使用具体的子类
* 坏处:不能使用子类特有的方法
* 好处:程序的扩展性增强了,定义方法的时候 ,可以使用父类
型作为参数,在使用的时候,使用具体的子类
* 坏处:不能使用子类特有的方法
四、转型
向上转型:一般是隐式转型,不需要手动参与
向下转型:一般是需要用子类的特有方法时候,先转为子类,在调用
向上转型:一般是隐式转型,不需要手动参与
向下转型:一般是需要用子类的特有方法时候,先转为子类,在调用
Stream流
一.如何获取Stream流
1.Collection体系的集合,使用stream()方法来生成流
2.Map体系集合得先把Map转成Set集合,间接生成流
3.数组使用Arrays工具类的stream()静态方法生成流
4.同种数据类型的多个数据,通过Stream接口中的静态方法of()生成流
二.流的中间操作方法
filter 过滤
limit 限制数量(从流里面拿几个出来)
skip 跳过
静态方法concat 拼接
【两个流进行拼接】
【两个流进行拼接】
distinct 去重
子主题
三.流的终结方法
forEach
count
toList
toArray
toSet
toMap
收集方式
collect
应用题
//找出list1中的偶数,并展示出来;[不能有重复元素]
将有格式的list转换为map键值对
在list0中,查询’张‘字,且长度为3的元素
【collect练习】根据一个任意类型的数组返回一个对应类型的集合
或者 ArrayList<E> arrayList =new ArrayList<>(List.of(arr));
调用集合的构造器
调用集合的构造器
map函数
子主题
map 方法
List<GameIdRelation> gameIdRelationList=mapper.getRelationById(Integer.parseInt(id));
List<String> typeList = gameIdRelationList.stream().map(s -> "" + S.getGameTypeId()).collect(Collectors.toList
List<GameIdRelation> gameIdRelationList=mapper.getRelationById(Integer.parseInt(id));
List<String> typeList = gameIdRelationList.stream().map(s -> "" + S.getGameTypeId()).collect(Collectors.toList
mapToDouble 方法
double amount = shoppingCartList.stream().mapToDouble(s -> s.getAmount() * s.getNumber()).sum();
double amount = shoppingCartList.stream().mapToDouble(s -> s.getAmount() * s.getNumber()).sum();
特殊类
interface接口
* 接口不能被实例化,接口是用来定义规范的
* 实现接口使用impements关键字
* 可以同时实现多个接口
* 实现了哪个接口,创建出来的对象就,就具备了哪个接口的类型
* 实现接口使用impements关键字
* 可以同时实现多个接口
* 实现了哪个接口,创建出来的对象就,就具备了哪个接口的类型
枚举类
一种特殊类,实例化的个数是有限的
特点:
1. 所有枚举类都是Enum子类
2. 我们可以通过“枚举类名。枚举项名称”去访问指定枚举项
3. 每个枚举项其实就是该枚举的一个对象
4.枚举也是一个类,也可以去定义成员变量及方法
5.枚举类的第一行必须是枚举项,最后一个枚举项后的分号也可以省略。
但是枚举类如果有其他东西,这个分号则不能省略。(所以不建议省略);
6.枚举类也可以有抽象方法,但是枚举项必须重写该方法
7.枚举类可以构造器,但必须是Private 的,而且它默认也是private的
特点:
1. 所有枚举类都是Enum子类
2. 我们可以通过“枚举类名。枚举项名称”去访问指定枚举项
3. 每个枚举项其实就是该枚举的一个对象
4.枚举也是一个类,也可以去定义成员变量及方法
5.枚举类的第一行必须是枚举项,最后一个枚举项后的分号也可以省略。
但是枚举类如果有其他东西,这个分号则不能省略。(所以不建议省略);
6.枚举类也可以有抽象方法,但是枚举项必须重写该方法
7.枚举类可以构造器,但必须是Private 的,而且它默认也是private的
注解
注解也是一个特殊类
不同的注解有不同的使用方法和场景;
注解根据实际情况可以应用在以下地方:
类上边、成员方法上边、成员属性上边、方法参数上边
不同的注解有不同的使用方法和场景;
注解根据实际情况可以应用在以下地方:
类上边、成员方法上边、成员属性上边、方法参数上边
//public// 属性类型 属性名称() default 默认值;
例如》》int age() default 18;
例如》》String value() default "张三";
如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义值即可
如果有多个属性就要写 value="" ,returning="",...
属性类型都可以设置成以下类型:
基本数据类型
String
Class【反射知识】
注解
枚举
以上类型的一堆数组
例如》》int age() default 18;
例如》》String value() default "张三";
如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义值即可
如果有多个属性就要写 value="" ,returning="",...
属性类型都可以设置成以下类型:
基本数据类型
String
Class【反射知识】
注解
枚举
以上类型的一堆数组
>>元注解<<
【@Target】元注解 用来规定自定义的注解可以在什么地方使用。
>ElementType.FIELD --成员属性上边
> ElementType.TYPE --类型上边,类上边,接口上边...
>ElementType.METHOD --方法上边
>ElementType.PARAMETER --形参上边
>ElementType.CONSTRUCTOR --构造器上边
【 @Retention 】元注解 代表注解保留到什么到阶段生效(源代码阶段,编译阶段,运行阶段)
>RetentionPolicy.SOURCE --源代码阶段
>RetentionPolicy.CLASS --编译阶段
>RetentionPolicy.RUNTIME --运行阶段,注解才能生效
【@Target】元注解 用来规定自定义的注解可以在什么地方使用。
>ElementType.FIELD --成员属性上边
> ElementType.TYPE --类型上边,类上边,接口上边...
>ElementType.METHOD --方法上边
>ElementType.PARAMETER --形参上边
>ElementType.CONSTRUCTOR --构造器上边
【 @Retention 】元注解 代表注解保留到什么到阶段生效(源代码阶段,编译阶段,运行阶段)
>RetentionPolicy.SOURCE --源代码阶段
>RetentionPolicy.CLASS --编译阶段
>RetentionPolicy.RUNTIME --运行阶段,注解才能生效
异常
t
常见异常类型
NullPointerException
IndexOutOfBoundsException
ClassCastException
InputMismatchException
ArithmeticException
ArrayIndexOutOfBoundsException
数组
静态初始化
int[]arr1=new int[]{1,3,4};
int[] arr2={50,90}
动态初始化
int[]arr3=new int[2]; 两个长度
int[]arr1=new int[]{1,3,4};
int[] arr2={50,90}
动态初始化
int[]arr3=new int[2]; 两个长度
局限性
数组内存图
数组的随机打乱
集合
Collection接口
【单列】
【单列】
List接口
【有顺序,可重复】
【有顺序,可重复】
ArrayList
方法
ArrayList<String> name=new ArrayList<>();
add()、(index、String)
set(index、String)
get(index)
remove(index)、(object)
size()
contains()
removeAll(ArrayList<>list2 )
removeif()
遍历
nameList.fori
nameList.for
nameList.forEach
迭代器循环
流式操作
LinkedList
add()、addFirst、addLast
get()、getFirst()、getLast
remove
Set接口
【无顺序,无重复】
【无顺序,无重复】
TreeSet
HashSet
不会重复
Map接口
【双列】
【双列】
TreeMap
HashMap
【键值对】
【键值对】
哈希值
put(key,value)
remove(key)
clear()
containsKey(key)
containsValue(value)
isEmpty()
size()
Set<String> keySet = map.keySet();
Collection<String> values = map.values();
Iterator迭代器
//获得该对象的迭代器
Iterator<String> it = collection.iterator();
while(it.hasNext()){
StringS=it.next();
System.out.println(s);
}
Iterator<String> it = collection.iterator();
while(it.hasNext()){
StringS=it.next();
System.out.println(s);
}
关键类及API
Scanner类
Scanner scan =new Scanner(System.in);
-->等用户输入才继续运行--> 阻塞
-->等用户输入才继续运行--> 阻塞
scan.close(); 手动关闭资源
next(); 方法接收的时候 ,会把空格当作接受的中断符
nextLine(); 只会把回车当作中断符
nextInt(); 接收整数类型
nextDouble()、nextFloat; 接收浮点型类型
Random类
Random rn=new Random()
int num1=rn.nextInt( bound);
获取 [0,bound)的随机数
后边在加 x-->[x,bound)
bound--有多少数
获取 [0,bound)的随机数
后边在加 x-->[x,bound)
bound--有多少数
rn.nextInt(origin ,bound)
获得 [origin,bound)的随机数
获得 [origin,bound)的随机数
String
StringBuider
StringBuffer
StringBuider
StringBuffer
String
String name1="Tom";
String name2="Tom";
name1==name2 -->true(都在常量区)
String name3=new String("Tom");
name1==name3 -->false
String name2="Tom";
name1==name2 -->true(都在常量区)
String name3=new String("Tom");
name1==name3 -->false
常用方法
length()
equals()
equalsIgnoreCase()
trim() 后续会有 hutool工具包
toCharArray()
substring()
repalce()
split()
contains() 包含
startsWith("张")---以’张‘开头
endsWith("天")---以’天‘结尾
endsWith("天")---以’天‘结尾
StringBuider
append()
toString()
reverse()
toString
replace
StringBuffer
Arrays数组工具类
toString()
Date类
日期格式化
* y 年(year)
* M 月(month)
* d 日(day)
* H 小时(hour)
* m 分(minute)
* s 秒(second)
* y 年(year)
* M 月(month)
* d 日(day)
* H 小时(hour)
* m 分(minute)
* s 秒(second)
date.getTime() 时间戳
在java 里 这个数字是从1970年1月1日 00:00:00过来的毫秒数 (比其他多三位数)
在java 里 这个数字是从1970年1月1日 00:00:00过来的毫秒数 (比其他多三位数)
Date date =new Date();
简单日期格式化
SimpleDateFormat sdf =new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss")
String dateFormat = sdf.format(date);输出即可(转为String类型)
--把日期字符串转成日期类型
Date parseDate=sdf.parse(dateString); [若Stirng类型和规定的sdf格式不同则会异常]
parse()-->解析
简单日期格式化
SimpleDateFormat sdf =new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss")
String dateFormat = sdf.format(date);输出即可(转为String类型)
--把日期字符串转成日期类型
Date parseDate=sdf.parse(dateString); [若Stirng类型和规定的sdf格式不同则会异常]
parse()-->解析
Math类
abs()
ceil()
floor()
round()
max() min()
pow()
random()
System
exit()
currentTimeMillis();
BigDecimal
add
subtract
multiply
divide
BigDecimal divide=num1.divide(参与运算的对象,小数点后精确到多少位,舍入模式);
参数1,表示参与运算的BigDecimal1 对象。
参数2,表示小数点后面精确到多少位
参数3,舍入模式
BigDecimal.ROUND_UP进一法
BigDecimal.ROUND_FLOOR 去尾法
BigDecimal.ROUND_HALF_UP 四舍五入
参数1,表示参与运算的BigDecimal1 对象。
参数2,表示小数点后面精确到多少位
参数3,舍入模式
BigDecimal.ROUND_UP进一法
BigDecimal.ROUND_FLOOR 去尾法
BigDecimal.ROUND_HALF_UP 四舍五入
LocalDateTime
now()
of
parse
getYear、getMonth、getDayOfMonth、
getHour、getMinute、getSecond、
getHour、getMinute、getSecond、
plusYears()、plusMonths、plusXXX
minusYears()、minusHours()、minMinutes()
minusYears()、minusHours()、minMinutes()
now.withYear()、now.withMonth()、withHour();
now.withDayOfMonth()---now.withDayOfYear();
now.withDayOfMonth()---now.withDayOfYear();
>>DateTimeFormatter 日期时间格式类<<
LocalDateTime ldt2 = LocalDateTime.now()
DateTimeFormatter dtf=DateTimeFormatter.ofPattern
("yyyy-MM-ddHH:mm:ss"); 【h-12 H-24】
String format = ldt2.format(dtf);//规定格式的日期字符串
LocalDateTime ldt2 = LocalDateTime.now()
DateTimeFormatter dtf=DateTimeFormatter.ofPattern
("yyyy-MM-ddHH:mm:ss"); 【h-12 H-24】
String format = ldt2.format(dtf);//规定格式的日期字符串
>>获取时间戳<<
//获得当前时间
LocalDateTimee now= LocalDateTime.now();
//获取时区内的时间
ZonedDateTime zonedDateTime=now.atZone(ZoneId.systemDefault());
//获取时区实例
Instant instant=zonedDateTime.toInstant();
//时区时间展示为毫秒数
long epochMilli = instant.toEpochMilli();
>>链式表达:
【return now.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();】
//获得当前时间
LocalDateTimee now= LocalDateTime.now();
//获取时区内的时间
ZonedDateTime zonedDateTime=now.atZone(ZoneId.systemDefault());
//获取时区实例
Instant instant=zonedDateTime.toInstant();
//时区时间展示为毫秒数
long epochMilli = instant.toEpochMilli();
>>链式表达:
【return now.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();】
MySQL
主机 -localhost -->127.0.0.1
报错方式
1045 - Access denied for user 'root'@'localhost' (using password: YES) 密码输入错误
1136-Column count doesn't matchvaluecount at row 1 添加的值的个数与对应字段的个数不一致
思想
某个库很重要的话 可以改颜色 红色啥的
sql语言--通用的查询语言,在不同数据库中应用,
开发中遇到困难就加一层
多对多--比如在同一时间可以买多个商品
一个商品可以有多个订单
一个订单也可以有多个商品
一个商品可以有多个订单
一个订单也可以有多个商品
数据库
主从架构
主从分离
分两个库来负责
主从分离
分两个库来负责
主库 UDI 负责增删改
从库 select 负责查询
一般是多台从库
一般是多台从库
追求 最终一致性
dirty data 脏数据 被约束不可添加的数据
小知识
字符集
utf8mb4 ---比utf8多一些表情符号啥的
coalesce(count(emp.id),0) --如果count 为null的话,则返回0
约束
非空 NOT NULL
唯一 UNIQUE
主键 PRIMARY KEY
默认 DEFAULT
自增 AUTO_INCREMENT
url
ORM
如果从数据库查询到的resultSet是多字段,可以将这些字段存入对象
该类的属性 ---> 每个字段
account对象 --->每一条记录
Account类 --> 表 --->对应一个javaBean
如果表中的字段是一个单词 字段名:name, 实体类属性: name
如果表中的字段是多个单词, 字段名: my_name 实体类属性: myName
my_english_score --> myEnglishScore
这种javaBean 我们又称之为 实体类(和表挂钩)
这种方式称之为 ORM --> object relation mapper 对象关系映射;
一个数据表对应一个实体类
表中的一个字段对应实体类的一个属性
表中的一条记录对应实体类的一个实例
如果从数据库查询到的resultSet是多字段,可以将这些字段存入对象
该类的属性 ---> 每个字段
account对象 --->每一条记录
Account类 --> 表 --->对应一个javaBean
如果表中的字段是一个单词 字段名:name, 实体类属性: name
如果表中的字段是多个单词, 字段名: my_name 实体类属性: myName
my_english_score --> myEnglishScore
这种javaBean 我们又称之为 实体类(和表挂钩)
这种方式称之为 ORM --> object relation mapper 对象关系映射;
一个数据表对应一个实体类
表中的一个字段对应实体类的一个属性
表中的一条记录对应实体类的一个实例
sql注入原因
密码输入的是 String pass="' or '1' = '1";
导致他跟源代码结合了,就无视密码直接进入了
导致他跟源代码结合了,就无视密码直接进入了
连接池了解
数据库连接池 --- 代理设计模式
连接池 池子里专门放数据库连接
只要打开数据库,就会预设几个连接,(预处理),
当需要用的时候,找空闲的连接,去连接数据库,
如果用完并不释放,而是将连接改成空闲状态;
考虑方向:初始化要多少连接,满了后策略有什么。。。。
国内性能高,使用量大的数据库连接池技术是阿里的德鲁伊
国外-- c3p0
国内--Druid -->德鲁伊
连接池 池子里专门放数据库连接
只要打开数据库,就会预设几个连接,(预处理),
当需要用的时候,找空闲的连接,去连接数据库,
如果用完并不释放,而是将连接改成空闲状态;
考虑方向:初始化要多少连接,满了后策略有什么。。。。
国内性能高,使用量大的数据库连接池技术是阿里的德鲁伊
国外-- c3p0
国内--Druid -->德鲁伊
JavaScript
框架
vue.js
angular.js
react
element
了解
脚本语言,要有运行环境,默认存在浏览器环境下,后来可以在 windows和linux
HTML 负责页面结构的编写 框架
CSS 负责页面样式的编写 装修,美观
JS 负责页面中一些动态效果的编写 更加完善
JAVA 负责灵魂--负责数组
CSS 负责页面样式的编写 装修,美观
JS 负责页面中一些动态效果的编写 更加完善
JAVA 负责灵魂--负责数组
输出语句
window.alert() 警告框
document.write() 里边可以写Html语句
console.log() 控制台
变量
var --作用域会穿透
let --推荐使用
数据类型
原始数据类型
String类型: 用单引号或双引号包裹起来的
number类型: 整数,小数,NaN (Not a Number)
boolean类型: true false
undefined类型: undefined (没有被定义)
number类型: 整数,小数,NaN (Not a Number)
boolean类型: true false
undefined类型: undefined (没有被定义)
引用数据类型
运算符
与java特殊的
=== 类型相同,值也相同
类型转换
将 string 转换为 number 有两种方式:
- 使用 + 正号运算符:
- 使用 parseInt() 函数(方法):
- boolean 转换为 number 类型:true 转为1,false转为0
- number 类型转换为 boolean 类型:0和NaN转为false,其他的数字转为true
- string 类型转换为 boolean 类型:空字符串转为false,其他的字符串转为true
- null类型转换为 boolean 类型是 false
- undefined 转换为 boolean 类型是 false
- string 类型转换为 boolean 类型:空字符串转为false,其他的字符串转为true
- null类型转换为 boolean 类型是 false
- undefined 转换为 boolean 类型是 false
函数
方法1
function 函数名(参数1,参数2..){
要执行的代码
}
要执行的代码
}
方法2
let 函数名 = function (参数列表){
要执行的代码
}
要执行的代码
}
调用方式
函数名称(实际参数列表);
例--let result = add(10,20);
例--let result = add(10,20);
子主题
数组
let 变量名 = [元素列表];
特点:
// 变长
let arr3 = [1,2,3];
arr3[10] = 10;
alert(arr3[10]); // 10
alert(arr3[9]); //undefined
let arr3 = [1,2,3];
arr3[10] = 10;
alert(arr3[10]); // 10
alert(arr3[9]); //undefined
类型可以不一样,长度可以不确定
方法
push(),add(),pop()
删除元素 splice
let arr5 = [1,2,3];
arr5.splice(0,1); //从 0 索引位置开始删除,删除一个元素
alert(arr5); // {2,3}
let arr5 = [1,2,3];
arr5.splice(0,1); //从 0 索引位置开始删除,删除一个元素
alert(arr5); // {2,3}
自定义对象
var 对象名称 = {
属性名称1:属性值1,
属性名称2:属性值2,
...,
函数名称:function (形参列表){},
...
};
属性名称1:属性值1,
属性名称2:属性值2,
...,
函数名称:function (形参列表){},
...
};
BOM
2.BOM >>>>> Browser object Model 浏览器对象模型
使用JS来控制浏览器相关的一些操作
常用对象
Window 对象 :浏览器窗口 [window可省略]
alert() 给窗口提示用的
confirm() 让用户做选择 【确认删除】
prompt() 提示用户输入用的
setTimeout 延迟函数
setInterval 周期函数
History对象 :浏览器历史
Localtion对象:浏览器的地址栏
localtion.href ='URL地址' 让浏览器跳转到指定地址
使用JS来控制浏览器相关的一些操作
常用对象
Window 对象 :浏览器窗口 [window可省略]
alert() 给窗口提示用的
confirm() 让用户做选择 【确认删除】
prompt() 提示用户输入用的
setTimeout 延迟函数
setInterval 周期函数
History对象 :浏览器历史
Localtion对象:浏览器的地址栏
localtion.href ='URL地址' 让浏览器跳转到指定地址
3.DOM >>>>> Document Object Model 文档对象模型
document对象
document.getElementById('ID名字')
document对象
document.getElementById('ID名字')
Maven 和 MyBatis
Maven
为什么要使用Maven
Maven是专门用于管理和构建Java项目的工具,它的主要功能有:
提供了一套标准化的项目结构
提供了一套标准化的构建流程(编译,测试,打包,发布.....)
提供了一套依赖管理机制
提供了一套标准化的项目结构
提供了一套标准化的构建流程(编译,测试,打包,发布.....)
提供了一套依赖管理机制
初始设置
1.Maven下载安装和配置
下载地址
https://maven.apache.org/download.cgi
创建 MAVEN-HOME
创建 MAVEN-HOME
布置Path
布置Path
布置 conf/settings.xml 设置
2.IDEA 创建项目注意点
构建工具选择Maven 指定组ID和工件ID
IDEA设置里面检查是否是自己的Maven
里边三个称为 ‘依赖坐标’GAV
子主题
解释
生命周期
Maven 的项目结构
src
pom.xml
自己的坐标
坐标
各种依赖
<dependencies>
<dependency>
里边三个称为 ‘依赖坐标’
"D:\桌面\D盘\2. sql注入演示\sql_inject\pom.xml"
思想
约定>规范
约定>配置
约定>配置
常用依赖
数据库依赖
mysql驱动依赖
<dependency> <!-- 每一个依赖放一个dependency -->
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
mybatis依赖
<dependency> <!-- 爆红说明目前本地库找不到 -->
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
日志相关依赖
<!-- 添加slf4j日志api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.20</version>
</dependency>
<!-- 添加logback-classic依赖 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- 添加logback-core依赖 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.20</version>
</dependency>
<!-- 添加logback-classic依赖 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- 添加logback-core依赖 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
单元测试依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
效率提升依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.34</version>
</dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.34</version>
</dependency>
MyBatis
开发环境配置
1.添加依赖
mybatis依赖
日志依赖[建议添加]
2.在resource目录下创建mybatis配置文件
mybatis-config.xml
logback.xml
放到resources目录下
mybatis-config.xml
logback.xml
放到resources目录下
3.创建Mapper接口和Mapper.xml
一张表对应一套Mapper
一张表对应一套Mapper
1.mian里面java包和resources包都创建com/zhang/mapper
2.根据表,main里的domain里建立实体类
3.在main里的mapper里创建接口___Mapper
4.在main里的resources的mapper粘贴 ___Mapper.xml文件
【里边 namespace="com.zhang.mapper.___Mapper"】
【记得改名字】
【里边 namespace="com.zhang.mapper.___Mapper"】
【记得改名字】
注意点
Mapper接口所咋在的包路径
和Mapper.xml所在的目录路径要一致
命名也要一致
和Mapper.xml所在的目录路径要一致
命名也要一致
检查mybatis-config中的配置
4开始使用mybatis进行CRUD数据库操作
Test测试
【测试类名字最好不要写Test】
【测试类名字最好不要写Test】
全方位使用MyBatis
进行数据库相关操作
进行数据库相关操作
查
解决数据库字段与JAVA实体类属性名称不匹配
1.给字段起别名,走起成和属性一致的名字
2.使用resultMap标签,让字段和属性名称做映射
3.配置mybatis的mapUnderscoreToCamelCase
参数传递占位符
${}
会引发SQL注入
使用Statement来执行SQL的
使用Statement来执行SQL的
#{}
底层是使用了预编译
使用PreparedStatment来执行SQL
使用PreparedStatment来执行SQL
sql语句
<include> 和 <sql>
<>
参数传递及获取
单个参数获取
直接获取
多个参数获取
使用@Param
将多个数据封装到实体类对象中
把多个数据保存到Map集合中
子主题
动态SQL
<where>标签
1.生成WHERE关键字
2.会动态的去掉第一个条件钱的AND
<if> 标签
<if test="s !=null"> sql语句 </if>
<choose> 标签
里边放 <when test=""> sql语句 </when>
增
获取插入之后自增的主键
返回给对象属性
返回给对象属性
<insert id="insertBrand" useGeneratedKeys="true" keyProperty="id">
INSERT INTO tb_brand
VALUES (NULL, #{brandName}, #{companyName}, #{ordered}, #{description}, #{status})
</insert>
【是数据库id是自增的,当添加成功后,又从数据库中去除id给这个实体类】
INSERT INTO tb_brand
VALUES (NULL, #{brandName}, #{companyName}, #{ordered}, #{description}, #{status})
</insert>
【是数据库id是自增的,当添加成功后,又从数据库中去除id给这个实体类】
子主题
改
数据回显
删
硬删
软删
软删除 --给表新增一个字段
is_delete
查询的时候条件多加一个
is_delete=0;
本质就是 更改字段
is_delete
查询的时候条件多加一个
is_delete=0;
本质就是 更改字段
批量删除
<forEach>
如果数据用数组存储,系统默认别名为 array,集合-->list
【要不用array,要不就用注解】
如果数据用数组存储,系统默认别名为 array,集合-->list
【要不用array,要不就用注解】
SQL注解可以直接进行 语句编写
@select
@update
项目
备选技术
展示层
Vue
ElementUI
数据库
MYSQL,Redis
数据框架
MP
ResdisTemplate
Web框架
Spring 拦截器
SpringBoot
Lombok
网关层
nginx -(Linux)
git 管理起来
MyBatisPlus [ MP ]
配置
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.7</version>
</dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.7</version>
</dependency>
<!--使用德鲁伊Druid数据库连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.23</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.23</version>
</dependency>
Mp配置 加上 日志配置
设置上传时候单个文件大小限制
CRUD
selectList
selectPage
selectPage
selectById
insert
updateById
deleteById
deleteByIds
注解
@TableName("tb_brand")
table-prefix: tb_
@TableField(select = false)
@TableField("brand_name")
@TableField(exist = false)
@TableLogic
查询
查询内容
QueryWrapper<Brand> qw=new QueryWrapper<>();
LambdaQueryWrapper<XXXX> lqw = new LambdaQueryWrapper<>();
子主题
Lambda查询对象的API
lt
gt
le
lqw.le(Brand::getOrdered,20);
ge
between
OR()
like()
in()
brandMapper.selectList(lqw2);
查询投影
lqw.select(Brand::getId,Brand::getBrandName);
分组查询
QueryWrapper<Brand> qw =new QueryWrapper<>();
qw.select("status,COUNT(*) AS total");
qw.groupBy("status");
List<Map<String, Object>> maps = brandMapper.selectMaps(qw);
System.out.println(maps);
qw.select("status,COUNT(*) AS total");
qw.groupBy("status");
List<Map<String, Object>> maps = brandMapper.selectMaps(qw);
System.out.println(maps);
lqw的条件
luw的条件
mapper
Mapper集成方式
Service
Service集成方法
updateById
save 添加 而且会自动将id赋值返回给实体类
saveBatch
remove
list(lqw)
getOne
小知识
分页拦截器
如果想用分页 需要先配置 实例化分页拦截器
其实就是先 new MybtisPlusInterceptor()
获取 mp的拦截器,在给mp的拦截器 加内联功能
加一个 paginationInnerInterceptor() 对象
然后 通过@Bean 添加到容器里 就可以用分页功能
其实就是先 new MybtisPlusInterceptor()
获取 mp的拦截器,在给mp的拦截器 加内联功能
加一个 paginationInnerInterceptor() 对象
然后 通过@Bean 添加到容器里 就可以用分页功能
一个myBatisPlusConfig类即可,不用继承
2.
IPage<Brand> page =new Page<>(2,3);//(第几页,一页显示几条)
mapper.selectPage(page,null)
ServiceImpl 中可以返回 IPage<实体类>
IPage<Brand> page =new Page<>(2,3);//(第几页,一页显示几条)
mapper.selectPage(page,null)
ServiceImpl 中可以返回 IPage<实体类>
page.getPages
page.getTotal()
page.getRecords()
当设置不查询该字段时候,可以通过lqw.select再查
分区场景
判断分区 用@Validated
hutool工具
JSON <=> 字符串 JSONUtiil
List<Dish>转List<DishVo> Beanutil
spring框架为了解决频繁属性拷贝的问题
spring框架为了解决频繁属性拷贝的问题
路径匹配
使用路径匹配 为了迎合 /**
编码解码
或者 Base64
URL
String encode = URLEncoder.encode(jsonStr, StandardCharsets.UTF_8);
String decode = URLDecoder.decode(jsonString, StandardCharsets.UTF_8);
MD5加密
不可逆
String encodePassword = DigestUtils.md5DigestAsHex(defaultPasswrod.getBytes());
【org.springframework.util.DigestUtils;包下】
【org.springframework.util.DigestUtils;包下】
静态资源的访问地址设置
写一个配置类 继承 WebMvc
RescourceHandler
配置后台【静态资源】的访问方式 //表明要处理哪些资源 //** -->子及孙
【第一个add表明要处理哪些资源 ,/backend/**】
把backend资源目录下的所有静态内容,都映射到/backend这个地址
【第二个add表明哪些文件来映射 (因为是本地所以要加上classpath:/backend/)】
加上 classpath: ,,前后 / 都加上
RescourceHandler
配置后台【静态资源】的访问方式 //表明要处理哪些资源 //** -->子及孙
【第一个add表明要处理哪些资源 ,/backend/**】
把backend资源目录下的所有静态内容,都映射到/backend这个地址
【第二个add表明哪些文件来映射 (因为是本地所以要加上classpath:/backend/)】
加上 classpath: ,,前后 / 都加上
雪花算法
需要用Long来接收 【由于长度太长,在前后段交互的时候要考虑精度 加注解】
#如果配置了全局,默认都按全局走,如果你额外进行了配置,就按额外配置走
在mybatis-plus下边添加 id-type: assign_id
# ID策略有以下几种:
none:看数据库设计 随数据表是自增就自增,没有设置主键,就需要手动设置
input:ID必须手动指定,不指定就报错
auto,自动递增,要求数据表id必须设置自增
assign_id使用[雪花算法]自动生成ID
assign_uuid使用uuid算法自动生成Id
#如果配置了全局,默认都按全局走,如果你额外进行了配置,就按额外配置走
在mybatis-plus下边添加 id-type: assign_id
# ID策略有以下几种:
none:看数据库设计 随数据表是自增就自增,没有设置主键,就需要手动设置
input:ID必须手动指定,不指定就报错
auto,自动递增,要求数据表id必须设置自增
assign_id使用[雪花算法]自动生成ID
assign_uuid使用uuid算法自动生成Id
逻辑删除/软删
配置即可,API还是DELETE相关
1.
2.
@TableLogic
private int isDelete;
@TableLogic
private int isDelete;
随机转换会话技术
@ConditionalonProperty(prefix = "combat-class"nameogtype' havingValue = "session")
自动填充
先写一个AtuoFillConfig类继承MetaObjectHandler
当多个表又相同的属性的时候,可以
获取文件扩展名
不带 “ . ”的扩展名 jpg png
事务
MP的事务
@EnableTransactionManagement
@Transactional
不能分割的两步操作放在Service里面加事务
当需要封装的时候,也放在Service
SQL约束获取报错信息
子主题
IO 图片展示
上传图片和下载图片
UUTID
String uuid = UUID.randomUUID().toString();
需要翻JS代码的问题
---前端回显不出来,接收不到数据的可能
1.名字和前端不一样
2.穿过来的属性不够
3.【压根就没查询到数据】
4.【没有接收到参数】
1.名字和前端不一样
2.穿过来的属性不够
3.【压根就没查询到数据】
4.【没有接收到参数】
找JS在哪里赋值给属性
在 async init()这个函数里
在 async init()这个函数里
分页不显示,就是没有给total赋上值
列表图片展示不出来可能是
下载请求地址参数错误
[可以试着找el-image]
下载请求地址参数错误
[可以试着找el-image]
图片不展示
没有传过去图片名
前端展示有问题
单选框默认有问题
可能就是判断有问题,看返回的是不是跟前端
判断的不一致,可以序列化对应的类型
判断的不一致,可以序列化对应的类型
获取前端判断逻辑有误
看需要传什么数据,先找 async
拦截器跳转不过去,可能是跟前端判断的逻辑不一致
就是没有符合跳转逻辑
尝试全局搜索【拦截器、request拦截器、响应拦截器】
就是没有符合跳转逻辑
尝试全局搜索【拦截器、request拦截器、响应拦截器】
没有达到,想要的效果,
可能就是传的数据不够
可能就是传的数据不够
提到Service的理由
业务逻辑
可能会服用
多个表格操作
可能会服用
多个表格操作
Linux
命令
top
任务管理器
q
quit 退出
clear
mkdir
mkdir -p /sss/aaa/bb
直接创建多级目录
直接创建多级目录
cd
pwd
ls
ls -l 其他文件
touch
--help man 帮助和文档
rm
rm -f 强制删除
rm -rf 递归删除文件,极其危险
删库跑路
删库跑路
mv
换名、移动
将 当前目录下的a.txt 放到 当前目录下的ccc文件下边
并且换名字为abc.txt
将 当前目录下的a.txt 放到 当前目录下的ccc文件下边
并且换名字为abc.txt
echo 输出
echo "我很好">>a.txt 【追加】
echo "我不好" > a.txt【覆盖】
yum -y install 包名
cat 查看
tail
从尾部查看
tail -2 a.txt 看末尾两行
tail -f 实时观察文档
tail -2 a.txt 看末尾两行
tail -f 实时观察文档
cp
cp -r 文件及其子文件都复制
cp -r ccc ./ddd
将 ccc文件下的所有文件递归复制到
当前文件下的ddd文件
将 ccc文件下的所有文件递归复制到
当前文件下的ddd文件
wget 下载 网址
ls -l
l
文件所有者
文件所属组
其他人
r read
子主题
子主题
小知识
挂载
Ctrl+U 删除该行
vim
k
上
j
下
h
左
l
右
a
追加
i
插入
A
插末尾
I
插行首
o
插入空行
x
先往后删除
X
往前删除
dd
删除整行
r
替换
:wq
。 当前目录
压缩
.tar 打包文件
.gz 压缩文件
.tar.gz 打包压缩后的文件
.gz 压缩文件
.tar.gz 打包压缩后的文件
tar -cvf hello.tar ./*
c -- 打包
v --打包过程
f --指定文件命名
hello.tar --新包名
c -- 打包
v --打包过程
f --指定文件命名
hello.tar --新包名
解压
tar -zxvf a.tar.gz
tar -zxvf a.tar.gz
思想
职位
CEO 首席经营管
CTO 首席技术官 管理架构师
互联网历史
李彦宏 -百度创始人
王坚 -被派创建阿里云
张一鸣 -字节跳动创始人 推荐系统
柳传志 -联想
CSDN 创始人 蒋涛
求伯君 -第一代WPS 雷军的伯乐
专业术语
bad smell
code review
CRUD Create Retrieve Update Delete
抽离
泛化与实例化
结对编程
社会中
竞价排名
灰色产业链
避免重复造轮子
增量小于存量
deadline
加 salt /加盐
加密方式
加密方式
MD5
不可逆
String encodePassword = DigestUtils.md5DigestAsHex(defaultPasswrod.getBytes());
代码侵入性
解耦
事务冒泡
封装
一个类的内聚性越好,越稳定
安全性,可以设置限制
安全性,可以设置限制
JavaBean
-就是一个Java中的类,其对象可以用于在程序中封装数据
成员变量 用 private 修饰
提供每一个成员变量对getXXX/setXXX方法
提供一个无参构造方法
开闭原则
对扩展开放,对修改关闭
链式语法
方法 返回值 是自己的类型,return this
三层开发思想
controller 控制器层
该层的类主要负责接收用户输入、给用户展示内容
service 服务层
处理 【业务逻辑】层 --必须要接口
放异常
功能性需求
>service接口>Impl包>
放异常
功能性需求
>service接口>Impl包>
dao 数据层
处理数据存储 (dao->data access object)--必须要接口
进行三层开发时候,以上三个包是必须的。其他以下的包,是根据项目情况,灵活选择的:
domain包 专门用来存放 JavaBean 【领域/实体类->POJO】
GameVo-->给前端的页面 view object 试图对象 页面要展示什么就传输什么
GameBo--> Business object 业务对象
GameDTO --> Data Transfer Object数据传输对象 【复合型数据】
GamePoJO--> plain old Java Object 普通的java 对象 类似 javaBean
domain包 专门用来存放 JavaBean 【领域/实体类->POJO】
GameVo-->给前端的页面 view object 试图对象 页面要展示什么就传输什么
GameBo--> Business object 业务对象
GameDTO --> Data Transfer Object数据传输对象 【复合型数据】
GamePoJO--> plain old Java Object 普通的java 对象 类似 javaBean
命名:
对应某某类+什么包 如 StudentService、StudentController
>规范
controller只能调用service,不能直接调用dao
service 只能调用 dao
controller ->service<->dao
对应某某类+什么包 如 StudentService、StudentController
>规范
controller只能调用service,不能直接调用dao
service 只能调用 dao
controller ->service<->dao
子主题
constant包 存放全局常量 接口 使用的时候直接调用接口
mapper包
util
exception
servlet
运行在服务器里的Java程序
server applet
不要接口
filter
组合
公钥 public Key 非对称加密
retrieval 检索 加密连接
模式
单例模式
(用private修饰无参构造方法)固定对象数量,
不可私自实例化对象,或者实例化对象也都指向同意区域
不可私自实例化对象,或者实例化对象也都指向同意区域
模板模式
可变动的用抽象方法,不变的则固定,然后继承抽象类
装饰器模式
可组合
代理设计模式
工厂模式
策略模式
JWT技术
好用的会话技术
JSON Web Token
非功能性需求
脏读
在转账和查账交叉的时候,如果不处理默认 读未提交 --可能会出现 脏读 问题 ,是扣钱还是不扣钱
处理方式就是 读可提交---但是就会遇到 不可重复读的 问题 ,在批量插入和查询条数 会有问题 ,还需要在把级别提高
--->可重复度 ---> 串行化
搜索
在有关键词搜索条件的时候往往需要 OR 来连接
但是要注意优先级 括号>AND>OR
注意关键词的搜索语句的多个OR
但是要注意优先级 括号>AND>OR
注意关键词的搜索语句的多个OR
map传参 --->这样后需要改动的少
GameBo business object 业务对象
硬编码
ORM
object relation mapper
对象关系映射;
object relation mapper
对象关系映射;
半自动ORM
全自动ORM
规范
如果从数据库查询到的resultSet是多字段,可以将这些字段存入对象
该类的属性 ---> 每个字段
account对象 --->每一条记录
Account类 --> 表 --->对应一个javaBean
如果表中的字段是一个单词 字段名:name, 实体类属性: name
如果表中的字段是多个单词, 字段名: my_name 实体类属性: myName
my_english_score --> myEnglishScore
这种javaBean 我们又称之为 实体类(和表挂钩)
这种方式称之为 ORM --> object relation mapper 对象关系映射;
一个数据表对应一个实体类
表中的一个字段对应实体类的一个属性
表中的一条记录对应实体类的一个实例
如果从数据库查询到的resultSet是多字段,可以将这些字段存入对象
该类的属性 ---> 每个字段
account对象 --->每一条记录
Account类 --> 表 --->对应一个javaBean
如果表中的字段是一个单词 字段名:name, 实体类属性: name
如果表中的字段是多个单词, 字段名: my_name 实体类属性: myName
my_english_score --> myEnglishScore
这种javaBean 我们又称之为 实体类(和表挂钩)
这种方式称之为 ORM --> object relation mapper 对象关系映射;
一个数据表对应一个实体类
表中的一个字段对应实体类的一个属性
表中的一条记录对应实体类的一个实例
SSM 主流技术栈
Spring + SpringMVC + Mybatis
Std
>限流
>容错
>熔断
>容错
>熔断
CDN
乐观锁
悲观锁
悲观锁
解决并发问题
假设不会出错,到了的时候在枷锁
上来就加锁
假设不会出错,到了的时候在枷锁
上来就加锁
公司设计流程
项目评审会
能不能做
多久能做完
成本最低
子主题
需求评审会
分多少模块
1.产品 讲需求
UI 后端 测试 运维 听
认知拉平
UI 后端 测试 运维 听
认知拉平
2. 前/后端工程师 去讲
从技术角度讲解理解的是不是一致
从技术角度讲解理解的是不是一致
3. 测试 讲其他人听
4. 确定后,各个部门 Leader
规定每个节点完成多少任务
规定每个节点完成多少任务
前端部门
前端技术部门
市场、运营、客服
后端部门
后端技术部门
CTO
总监
1. 产品经理
项目经理
0. 后端工程师
UI设计
2. 前端工程师
3. 测试工程师
4. 运维工程师
网络工程师
安全工程师
技术、财务、人事、行政、公关
1. 权衡 2. 银弹
属性拷贝
流量 的成本> 存储成本
存储身高、体重、钱这种单位的用常用的最小单位来存储来数据库
等保测评
SDK
SoftWare Development Kits
软件开发工具包
软件开发工具包
短信
验证码
营销短信
五险一金
养老
子主题
医疗
不能断
生育
工伤
失业
住房公积金
Tomcat容器
javaWeb配置tomcat
1.
2.
3.
乱码
-Dfile.encoding=UTF-8
架构
C/S架构的应用程序 Client/Server 客户端/服务器 mysql,redis,rabiitmq
B/S架构的应用程序 Browser/Server 浏览器/服务器
B/S架构的应用程序 Browser/Server 浏览器/服务器
----Request --->
浏览器 百度服务器
<--Response---
浏览器 百度服务器
<--Response---
http 协议 明文数据
https 协议 密文数据
http -->超文本传输协议
--> HyperTest Transer Protocol
s--> Secure
http 1.0 1.1-->缺点 健忘,记不住用户
https 协议 密文数据
http -->超文本传输协议
--> HyperTest Transer Protocol
s--> Secure
http 1.0 1.1-->缺点 健忘,记不住用户
请求数据据格式
请求类型
get 查
无请求体,需要写参数的话,写在地址栏
post 增
用的时候
>先解决乱码问题
req.setCharacterEncoding("UTF-8");
>先解决乱码问题
req.setCharacterEncoding("UTF-8");
put 改
delete删
请求格式
请求行
请求头
请求体
可以放一写参数去服务端
子主题
响应数据格式
响应行
状态码
200 --OK
404 --不存在 Not Found
500 --源码有问题 server Unavaiable
405 --方法不允许,有地址但是,请求方法类型不对
503 --服务器宕机或不能提供服务
404 --不存在 Not Found
500 --源码有问题 server Unavaiable
405 --方法不允许,有地址但是,请求方法类型不对
503 --服务器宕机或不能提供服务
响应头
响应体
子主题
HTTP协议
HyperText Transfer Protocol,超文本传输协议,HyperText Transfer Protocol,超文本传输协议
- HTTP协议:主要定义通信规则
- 浏览器发送请求给服务器,服务器响应数据给浏览器,这整个过程都需要遵守一定的规则,之前
大家学习过TCP、UDP,这些都属于规则,这里我们需要使用的是HTTP协议,这也是一种规则。
-数据传输的规则指的是请求数据和响应数据需要按照指定的格式进行传输
- HTTP协议:主要定义通信规则
- 浏览器发送请求给服务器,服务器响应数据给浏览器,这整个过程都需要遵守一定的规则,之前
大家学习过TCP、UDP,这些都属于规则,这里我们需要使用的是HTTP协议,这也是一种规则。
-数据传输的规则指的是请求数据和响应数据需要按照指定的格式进行传输
补充
子主题
>>生命周期<
loadOnStartup默认负数--> 当访问地址的时候,servlet才创建
当请求后,先看有没有/hello的实例,如果没有,
就先创建实例【init】--servlet则被创建
-业务逻辑【service】
--当再次请求,发现有实例,就不会创建,直接输出
--当结束的时候,会销毁实例,收尾【destroy】
当loadOnStartup为>=0的数的时候,
代表只要一启动就实例化servlet
loadOnStartup默认负数--> 当访问地址的时候,servlet才创建
当请求后,先看有没有/hello的实例,如果没有,
就先创建实例【init】--servlet则被创建
-业务逻辑【service】
--当再次请求,发现有实例,就不会创建,直接输出
--当结束的时候,会销毁实例,收尾【destroy】
当loadOnStartup为>=0的数的时候,
代表只要一启动就实例化servlet
Web开发技术
servlet
依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope> <!--当开发的时候,有当部署的时候就不需要了 -->
</dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope> <!--当开发的时候,有当部署的时候就不需要了 -->
</dependency>
@WebServlet("/demo1") 【斜杠不要丢,别重,别用大写】
public class Dome1Servlet extends HttpServlet {
public class Dome1Servlet extends HttpServlet {
请求对象 req
获取请求行数据
getMethod() 获取请求方式
getRequestURL 获取url地址
getRequestURI 获取URI
getQueryString 获取请求参数字符串
获取请求头数据
getHeader(User-Agent)
获取查询参数
getParameter()
如果请求中没有名为 id 的参数,该方法返回 null。
如果请求中有名为 id 的参数,但该参数没有值,该方法返回空字符串 ""。
如果请求中没有名为 id 的参数,该方法返回 null。
如果请求中有名为 id 的参数,但该参数没有值,该方法返回空字符串 ""。
req.getParameterValues()
返回一个字符串数组。如果请求中没有对应的参数,返回null;
如果参数存在但没有值,返回一个长度为 0 的字符串数组([])。
返回一个字符串数组。如果请求中没有对应的参数,返回null;
如果参数存在但没有值,返回一个长度为 0 的字符串数组([])。
响应对象 resp
在接受参数之前,要规定字符集
设置响应的数据内容类型,这里响应一个HTML类型的内容
setContentType("text/html;charset=UTF-8")
【plain---文本】
设置响应的数据内容类型,这里响应一个HTML类型的内容
setContentType("text/html;charset=UTF-8")
【plain---文本】
getWriter().write("<h1>响应内容</h1>")
请求转发
req.getRequestDispatcher("/demo2").forward(req,resp);
存储给req req.setAttribute(String name,String boject)
根据key获取值 req.getAttribute(String name)
根据key删除键值对 req.removeAttribute(String name);
>>请求转发最佳实践
1.不要在请求转发之前生成响应
2.不要在请求转发之后再写其他逻辑
3.在请求转发之后,添加一条 return语句
1.不要在请求转发之前生成响应
2.不要在请求转发之后再写其他逻辑
3.在请求转发之后,添加一条 return语句
>>>>请求转发三个特点
1.请求转发不管转发多少次,始终是一个请求
2.请求转发是在服务器内部完成的
3.请求转发不能转发到外部资源 同一项目就是内部资源,可以转发但不一定能处理
【地址栏不变】
1.请求转发不管转发多少次,始终是一个请求
2.请求转发是在服务器内部完成的
3.请求转发不能转发到外部资源 同一项目就是内部资源,可以转发但不一定能处理
【地址栏不变】
重定向
resp.sendRedirect("http://www.baidu.com");
>>>>重定向三个特点
1.重定向是两次请求(浏览器地址栏地址发生变化,网络面板捕获到两次请求,不能在请求中共享数据了)
2.重定向第一次请求实在内部完成的,响应后后续是否请求内部资源得看自己逻辑了
3.重定向可以是内部或者外部资源
1.重定向是两次请求(浏览器地址栏地址发生变化,网络面板捕获到两次请求,不能在请求中共享数据了)
2.重定向第一次请求实在内部完成的,响应后后续是否请求内部资源得看自己逻辑了
3.重定向可以是内部或者外部资源
Jsp
input
要想让其必填 可以加上 required="required"
默认值 用 value=”“承载
textarea
要想让其必填 可以加上 required
默认值 直接放在开闭标签之间即可
select
默认值 加上 selected
注意点
ids 需要forEach ,id.checked ,,push 的是 value
Servlet+JSP 开发模式
在servlet中将数据转发给 XXX.jsp
在 XXX.jsp 中 加上 isELIgnored="false" 配置
要想用 ${ }
要想用 ${ }
添加依赖
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
要想用<c:if>标签
要想用<c:if>标签
${ req中携带的对象名 }
【注意】
所遇到的问题/规范
所遇到的问题/规范
style后边带分号
EL表达式注意格式 不要多空格
通过隐藏域提交 id
默认值 int类型最好为 -1 不要为0
当传过来的属性只有一个,才可以直接写属性
列表项目
//列表项目
1.增
2.删
3.改
4.查
5.软删
6.批量删除
7.状态显示
8.快捷操作状态
9.搜索
10.分页 上下一页 首尾页;一页展示几条 ;兼容搜索,更改,快捷操作 ;显示几个第几页;
1.增
2.删
3.改
4.查
5.软删
6.批量删除
7.状态显示
8.快捷操作状态
9.搜索
10.分页 上下一页 首尾页;一页展示几条 ;兼容搜索,更改,快捷操作 ;显示几个第几页;
git
linux
linux 创始人托瓦兹创立的
分布式
分布式
理念
没有结果就是最好的结果
没有结果就是最好的结果
以 . 开头的 为隐藏目录
~ 家目录
cat 查看
:wq
write quit
write quit
touch 创建文件
-l
list
list
-a
all
all
-r 递归
java -version = java.exe -version
后边不写默认带.exe
后边不写默认带.exe
介绍
之前用 SVN 文件版本管理
中心化 ---- 不安全 --效率高
去中心化趋势 【区块链】【比特币】
中心化 ---- 不安全 --效率高
去中心化趋势 【区块链】【比特币】
适合管理文本文件
VIM 神的编辑器
Emacs 编辑器之神
状态
Git工作区中的文件存在两种状态:
- untracked 未跟踪(未被纳入版本控制)
- tracked 已跟踪(被纳入版本控制)
1)Unmodified 未修改状态
2)Modified 已修改状态
3)Staged 已暂存状态
- untracked 未跟踪(未被纳入版本控制)
- tracked 已跟踪(被纳入版本控制)
1)Unmodified 未修改状态
2)Modified 已修改状态
3)Staged 已暂存状态
命令
>>先表明身份
>git config --global user.name "zhangHaoMeng"
>git config --global user.email "15614333036@163.com"
>git config --global user.name "zhangHaoMeng"
>git config --global user.email "15614333036@163.com"
>>初始化
>git init
.git文件 --本地版本库
>git init
.git文件 --本地版本库
>清空
git clear
git clear
>状态
git status
git status
. 当前目录
>回到指定版本
git reset --hard XXXXX
git reset --hard XXXXX
换支节
git branch 新分支名字 新建
git checkout master 切换
git chekout -b 新建 和切换
日志
git log
git reflog
提交到远程代码库
公私钥/生成指纹
一台电脑一个指纹 获取信任 之后就不用了
创建数据库以及提交
子主题
git remote add origin ssh地址
git remote -v
git push -u origin master
接收远程代码库
Ⅰ. git clone 远程地址
idea打开
idea打开
git fetch +远程地址
git merge
合并 前提自己得有名字一样的分支
合并 前提自己得有名字一样的分支
git branch -r 查看远程所有分支
remote
git branch -a 查看所有本地及远程分支
all
git branch -D 分支名 彻底删除分支
remote
git branch -a 查看所有本地及远程分支
all
git branch -D 分支名 彻底删除分支
子主题
git stask
git stask pop
临时清空工作台
git stask pop
临时清空工作台
步骤
1. git init
2. git clone +ssh地址
3. 托给idea打开
4.生成自己的分支
git branch 查看分支
git checkout -b 分支名
5.开始在自己分支写代码
写完 提交
写完 提交
先获取远程来远程连接
git remote add origin ssh地址
git remote add origin ssh地址
git remote -v 查看是否连接
git fetch 拉取保证最新
git status
git add .
git commit -m "备注"
git push -u origin 分支名字
如果需要merge
前提是最新的你fetch过
前提是最新的你fetch过
-m " "规范
feat: [一个新功能]
feature --特性
feature --特性
fix:
修复bug
修复bug
test:
style:
会话技术
Cookie
1.cookie 是生成在客户端的,保存在浏览器里的
2.可以设置有效期 setMaxAge()
默认负值: 代表浏览器的关闭而消失
可以设置0: 代表直接让cookie 失效
正数 : 代表cookie存活的秒数
获取-->得先new
Cookie cookie = new Cookie("loginStatus",user.getUserName());
Cookie cookie = new Cookie("loginStatus",user.getUserName());
resp.addCookie(newCookie);
cookie.getName
cookie.getValue
展示->${cookie.loginStatus.value}
Cookie 不能直接存储中文
如需要存储,则需要进行转码:URL编码
如需要存储,则需要进行转码:URL编码
编码
String encode = URLEncoder.encode(jsonStr, StandardCharsets.UTF_8);
解码
String decode = URLDecoder.decode(jsonString, StandardCharsets.UTF_8);
或者 Base64
cookie.setPath("/")
步骤
/game/login
子主题
LoginFilter
子主题
JSP
子主题
/game/logout
子主题
要想关闭,
1.先设置同名的cookie
2.再设置 maxAge(0)
3.最后记得 响应回去覆盖
1.先设置同名的cookie
2.再设置 maxAge(0)
3.最后记得 响应回去覆盖
session
展示->${sessionScope.loginStatus}
获取-->不用new 直接获取
HttpSession session = req.getSession();
HttpSession session = req.getSession();
setAttribute
1.存在服务器,但是也依赖cookie技术,客户端
2.随浏览器关闭而消失
设置多少秒后不和服务器交互(不发请求),session就失效
session.setMaxInactiveInterval(10);
session.setMaxInactiveInterval(10);
步骤
/game/login
子主题
LoginFilter
子主题
JSP
子主题
/game/logout
子主题
session.removeAttribute(label); 指定删除
session.invalidate(); 全部删除
session.invalidate(); 全部删除
ChatUtil
过滤器
解决什么问题?
一些请求都需要进行处理,就可以考虑使用过滤器了
给请求过滤,符合要求才进入servlet
登录页和注册页不能拦截
Filter
优先级是按照过滤器的类名自由排序
拦截器
spring 特有的
spring 特有的
Spring
介绍
是什么 -->基础框架
为什么要用-->新启项目 都用这个100%
他解决什么问题 --> [两个精髓/思想/技术块]
1. IOC [ Inversion of Control] 控制反转 -->不用new了,控制权交给框架
2. AOP [Aspect orient Programming ]面向切面编程
[之前学的是 OOP object orient programming] 面向对象编程 -->会有 紧耦合
[还有 POP Procedure - Oriented Programming ]面向过程编程
3.空间换时间
1. IOC [ Inversion of Control] 控制反转 -->不用new了,控制权交给框架
2. AOP [Aspect orient Programming ]面向切面编程
[之前学的是 OOP object orient programming] 面向对象编程 -->会有 紧耦合
[还有 POP Procedure - Oriented Programming ]面向过程编程
3.空间换时间
大家族/全家桶
springBoot
springAI
依赖
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.27</version>
</dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.27</version>
</dependency>
IOC
在Spring 里让 IOC(思想) 落地/实现的方式为
DI -->Dependency Injection 【依赖注入】
DI -->Dependency Injection 【依赖注入】
依赖
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.7</version>
<artifactId>spring-context</artifactId>
<version>5.3.7</version>
Spring注解
@Configuration
>修饰类
>表明为配置类,加载到容器里,同时也会被实例化放到容器里边
>表明为配置类,加载到容器里,同时也会被实例化放到容器里边
@Component
@Repository
用来修饰类,是一个特殊的@Component组件,代表业务逻辑层组件,比@Component更具语义化。
@Controller
用来修饰类,是一个特殊的@Component组件,代表 控制器 层组件,比@Component更具语义化。
@Service
用来修饰类,是一个特殊的@Component组件,代表持久层组件,比@Component更具语义化
>修饰类
代表为组件类,可以被Spring扫描并实例化,以Bean的方式在容易里管理起来
代表为组件类,可以被Spring扫描并实例化,以Bean的方式在容易里管理起来
@ComponentScan("包名")
>修饰类
>参数指定包名,用于Spring实例化时,去哪个包下扫描组件。
组件扫描包路径com.zhang ,扫描有@componet 的类, 如果有就会
将他实例化好,以Bean的形式放到容器里边 名字默认为首字母小写的类名
>参数指定包名,用于Spring实例化时,去哪个包下扫描组件。
组件扫描包路径com.zhang ,扫描有@componet 的类, 如果有就会
将他实例化好,以Bean的形式放到容器里边 名字默认为首字母小写的类名
@Autowired
或者
@Resource【如果是一个】
或者
@Resource【如果是一个】
自动注入 【修饰属性/方法】 用于从容器中找到合适的对象,注入到属性上
@Qualifier("默认名字")
【修饰属性】 指定哪个实现类的对象
一般和@Autowired配合使用,当容器中包含两个及以上
相同类型的对象时,使用该注解明确指定使用容器中的哪个对象
一般和@Autowired配合使用,当容器中包含两个及以上
相同类型的对象时,使用该注解明确指定使用容器中的哪个对象
@Scope("singleton")
单例 默认 【修饰属性】 指定哪个实现类的对象, 当容器被new的时候,就实例化一个放到了容器里
@Scope("prototype")
原型--> 当getBean 一次就new 一个实例放到容器里 【修饰注解】
@PostConstruct
【修饰方法】 被修饰的方法在构造之后立即运行
@PreDestroy
【修饰方法】 被修饰的方法在Bean 销毁之立即运行
@PropertySource("classpath:XX.properties")
@PropertySource("classpath:config.properties")
//类路径 -->类变量 :当jvm一打开,就找这个类路径
public class MyConfig {}【一般放在配置类上边】
//类路径 -->类变量 :当jvm一打开,就找这个类路径
public class MyConfig {}【一般放在配置类上边】
配置文件在resources包下命名为 XXXX.properties
配置文件里边书写格式为 键=对 换行 键=对
@Value("${name}")
spring Expression Language Spring表达式 SpEL
修饰一个属性,获取配置文件中的参数值并赋值给该属性,需要
提前由@PropertySource注解将配置文件加载。
例如properties配置文件有一项数据: username=leoxuchao
则可以使用@Value("${username}") 来获取参数值leoxuchao
修饰一个属性,获取配置文件中的参数值并赋值给该属性,需要
提前由@PropertySource注解将配置文件加载。
例如properties配置文件有一项数据: username=leoxuchao
则可以使用@Value("${username}") 来获取参数值leoxuchao
@Bean
被@Bean修饰的方法,Spring会把该方法的放回值作为一个Bean,放到容器里管理起来
将Bean存入容器的方法
1.包扫描
@Bean
思路
把需要用的对象,一打开就放到容器里,用的时候用注解注入
AnnotationConfigApplicationContext (MyConfig.class)类名
Spring上下文/容器 存储一些实体类的容器
AOP
依赖
<!--引入和AOP相关的依赖-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.22.1</version>
</dependency>
advice通知
前置通知 Before Advice
子主题
后置通知 After Advice
子主题
环绕通知 Around Advice
//如果被切的方法有返回值,除返回值为数组和集合外,可以写对应返回值的类型
1.环绕通知必须依赖形参ProceedingJoinPoint才能实现对原始方法的调用,进而实现原始方法调用前后同时添加通知
2。通知中如果未使用ProceedingJoinPonit对原始方法进行调用将跳过原始方法的执行
3。对原始方法的调用可以不接收返回值,通知方法设置成void即可。如果接收返回值,【必须/不必须】设定为Object类型
4。原始方法的返回值如果是void类型,通知方法的返回值类型可以设置为void,也可以设置为Object
5。由于无法预知原始方法运行后是否会抛出异常,因此环绕通知方法必须抛出Throwable对象
ProceedingJoinPoint 对象的方法
pjp.getTarget().getClass().getName(); 获取类名
pjp.getSignature(); 获取方法签名
pjp.getSignature().getDeclaringType(); 通过方法签名获取类名
pjp.getSignature().getName(); 通过方法签名获取方法名
返回通知 AfterRetrning Advice
@AfterReturning( value = "execution(String com..StudentService.niHao(..))",returning ="rt" )
异常返回通知After Throwing Advice
@AfterThrowing(value = "pt()",throwing = "t")
注解
@Aspect
@Component
@Component
代表为切面类
但是也得加上
@Component
但是也得加上
@Component
@EnableAspectJAutoProxy
@EnableAspectJAutoProxy
public class MyConfig {
}
@pointcut ("execution(切入表达式 )")
子主题
@Pointcut("execution(public void com.shizhanban.service.Impl.StudentServiceImpl.say*())")
注意点
切入点: 要进行增加的方法
切入点表达式:要进行增加的方法的描述方式
//表达式 : 权限控制符 ,返回值,包路径,类/接口 方法名(参数)
//可以加 niHao(..) 或者 niHao(*) 或者 niHao() 或者具体 int String 但是只写类型
@AfterReturning( value = "execution(String com..StudentService.niHao(..))",returning ="rt" )
切入点表达式:要进行增加的方法的描述方式
//表达式 : 权限控制符 ,返回值,包路径,类/接口 方法名(参数)
//可以加 niHao(..) 或者 niHao(*) 或者 niHao() 或者具体 int String 但是只写类型
@AfterReturning( value = "execution(String com..StudentService.niHao(..))",returning ="rt" )
配置文件
介绍
xml
properties
yml
配置文件优势>常量
在单体项目中都可以,但是如果是多体文件
通过 配置文件相互发送,就不用因为要改动一个
常量而改动整个代码库,只需要发给配置中心
Apollo 配置管理中心
在单体项目中都可以,但是如果是多体文件
通过 配置文件相互发送,就不用因为要改动一个
常量而改动整个代码库,只需要发给配置中心
Apollo 配置管理中心
配置文件里的配置项需要映射 application.ym
@Autowired
yml文件
介绍
YAML(YAMLAin'tMarkupLanguage)
,一种数据序列化格式
,一种数据序列化格式
优点
容易阅读
容易与脚本语言交互
以数据为核心,重数据轻格式
容易与脚本语言交互
以数据为核心,重数据轻格式
扩展名
.yml[主流]
.yaml
规范
举例
大小写敏感
属性层级关系使用多行描述,每行结尾使用冒号结束
使用缩进表示层级关系,同层级左侧对齐,只允许使用空格(不允许使用Tab键)
属性值前面添加空格(属性名与属性值之间使用冒号+空格作为分隔)
表示注释
核心规则:数据前面要加空格与冒号隔开
数组数据格式
数组数据在数据书写位置的下方使用减号作为数据开
始符号,每行书写一个数据,减号与数据间空格分隔
始符号,每行书写一个数据,减号与数据间空格分隔
核心配置文件名
application.yml
常用后缀
.yml
-prod.yml
-test.yml
-dev.yml
SpringBoot
介绍
约定>配置
配置
新建项目
子主题
子主题
子主题
包
pom.xml
JAVA版本
指定Java版本
设置编译前后的版本
依赖特点
前缀判断时候需要写version
依赖管理器
<dependencyManagement>
<dependencyManagement>
官方集成好的,不用写<version>
默认不加载到项目里的
需要什么依赖,就从管理器里找对应版本加载
记得修改 <skip>false</skip>
能有提示是因为有依赖
a< spring-boot-configuration-processor>
多环境启动配置
1. 对SpringBoot项目打包(执行Maven构建指令package)
2.带参数启动SpringBoot
参数获取优先级为:
命令行中的参数 > 指定环境的参数 > application.yml中的参数
命令行中的参数 > 指定环境的参数 > application.yml中的参数
Java -jar springboot.jar --spring.profiles.active=test
Java -jar springboot.jar --server.port=88
Java -jar springboot.jar --server.port=8888 --spring.profiles.active=test
注解
@controller
只要是springboot里边,有这个注解,就可以响应,接收请求了
但是得有页面来支撑否则报错,,主流开发,前后分离,所以用以下注解
@ResponseBody
>修饰类/方法
>会把修饰的方法的返回值作为响应给到浏览器
>以JSON 格式响应回去
>会把修饰的方法的返回值作为响应给到浏览器
>以JSON 格式响应回去
@RestController
@Controller+@ResponseBody=
@RequestMapping("/test")
@ConfigurationProperties(prefix = "shizhanban")
当用配置类里的配置项的时候,映射需要用到
当用配置类里的配置项的时候,映射需要用到
>封装/映射成Bean
>还要记得这样注解标识对应哪个配置项
>还要记得这样注解标识对应哪个配置项
@RequestParam
>修饰形参
>当请求参数名与形参变量名不同,
使用@RequestParam绑定参数关系
>指定用集合接收
@RequestBody
需要接收JSON添加
需要接收JSON添加
请求体当作一个整体,以JSON格式接收
@PathVariable
当需要用到路径变量的时候
当需要用到路径变量的时候
路径变量
@DateTimeFormat(pattern = "YYYY-MM-dd HH:mm:ss")
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@Valid
验证器
验证器
@Validated
框架的验证器
框架的验证器
@RestControllerAdvice
修饰全局异常处理器
修饰全局异常处理器
修饰异常处理器
@ExceptionHandler
在处理器中详细指定哪种异常
在处理器中详细指定哪种异常
子主题
请求与响应
请求参数获取
-普通参数
-POJO类型参数
-嵌套POJO类型参数
-数组类型参数
-集合类型参数
-POJO类型参数
-嵌套POJO类型参数
-数组类型参数
-集合类型参数
子主题
接收日期类型数据
springboot里自带转换器,里自带有Date类型
public void test(@DateTimeFormat(pattern = "YYYY-MM-dd HH:mm:ss") Date date) {
System.out.println(date.getYear());
} //【不过不推荐使用Date有问题,之后会有更合适的转日期工具】
System.out.println(date.getYear());
} //【不过不推荐使用Date有问题,之后会有更合适的转日期工具】
接收JSON类型的参数
@RequestBody
记得在参数前添加注解
记得在参数前添加注解
子主题
RESTful风格
定义不同的功能操作,URL地址应该是什么样子的
学生列表的URL
GET/students
添加学生的URL地址
POST/students
获取学生ID是1的学生信息
GET/students/1
子主题
提交修改信息
PUT/students
删除学生ID是1的学生
DELETE/students/1
整合Mybatis
配置数据源/统一配置
Spring操作是数据库配置文件
全局异常处理类
@RestControllerAdvice
@ExceptionHandler
命名规范
全局异常处理类
GlobalExceptionHandler
全局异常
自定义系统异常
SystemException
自定义业务异常
BusinessException
@Getter
@Setter
private Integer code
@Setter
private Integer code
升级版处理异常
@ExceptionHandler(BusinessException.class)
public ResponseEntity<R> businessException(BusinessException e){
//需要干涉 页面的状态码
return new ResponseEntity<>(R.error(e.getCode(), e.getMessage()), HttpStatus.OK);
}
public ResponseEntity<R> businessException(BusinessException e){
//需要干涉 页面的状态码
return new ResponseEntity<>(R.error(e.getCode(), e.getMessage()), HttpStatus.OK);
}
验证器
目的:验证不能为空
位置:实体类的每个属性上边
位置:实体类的每个属性上边
1. 加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2. 实体类上注解
@NotBlank
@NotEmpty
@NotNull
@Email(message="XXX")
@Min(value=XX,)message="XX"
@max()
@Size(min=2,max=30,message="XXX")
@Pattern(正则)
@Positive或@PositiveOrZero
3. 在需要验证的方法上加上@Valid
4. 获取Valid的msg
e.getBindingResult().getFieldError().getDefaultMessage()
5. 在全局异常处理器处 MethodArgumentNotValidException
String msg =e.getBindingResult().getFieldError().getDefaultMessage();
String msg =e.getBindingResult().getFieldError().getDefaultMessage();
拦截器
介绍
在正式处理Controller方法之前/之后进行一个处理
AOP技术
执行顺序
API
preHandle
该方法在进入原始方法之前会执行
如果该方法返回true,代表放行,会执行原始方法
会 false,代表拦截成功,不会执行原始方法
如果该方法返回true,代表放行,会执行原始方法
会 false,代表拦截成功,不会执行原始方法
postHandle
当原始方法正常执行完以后,会被调用
如果原始 方法出异常,那么此方法就不会调用了
如果原始 方法出异常,那么此方法就不会调用了
AfterCompletion
会在原始方法之后会调用,不管原始方法有无异常,始终被调用
如果postHandle正常执行,那它就在postHandle之后被调用
如果postHandle正常执行,那它就在postHandle之后被调用
普通拦截器
1. 先建一个interceptor 包
细说拦截器的细节
细说拦截器的细节
1.定义一个自己的拦截器,用于拦截系统中的请求
自定义的拦截器需要【实现HandlerInterceptor】
@Component
public class MyInterceptor implements HandlerInterceptor {}
自定义的拦截器需要【实现HandlerInterceptor】
@Component
public class MyInterceptor implements HandlerInterceptor {}
2.config包下写一个配置类
说web需要哪些拦截器
说web需要哪些拦截器
想配置Web框架的默认行为,可以有以下两种方式
方式1。继承 WebMvcConfigurationSupport类,重写里面需要的方法去【之前配拦截器用的方法】
方式2。实现WebMvcConfigurere接口,实现里面需要的方法
方式1。继承 WebMvcConfigurationSupport类,重写里面需要的方法去【之前配拦截器用的方法】
方式2。实现WebMvcConfigurere接口,实现里面需要的方法
MyWebConfig 类 管理Web默认行为
分页拦截器
看MP [特有]
收藏
0 条评论
下一页