文章目录
- 一、基础知识
- 二、类
- 三、Web
- 四、JavaWeb
一、基础知识
1、基本内存数据大小
byte:1字节 short:2字节 int:4字节 long:8字节 float:4字节 double:8字节 char:2字节 boolean:1bit
1字节 = 8bit
2、数据类型转换
2.1、隐式
范围从小到大 byte<short<int<long<float<double
2.2、显式
强制类型换 int num =(int) 100L; 范围小的类型 变量名 = (范围小的类型) 范围大的数据
char类型进行数学运算,字符会变成数据进行运算
byte/short/char数据运算时提升为int,然后再进行计算
3、ASCII
(美国信息交换标准代码)
0:48 A:65 a:97
输出对应的ASCII对应的值
System.out.println('A'+0);
4、Unicode码表
(万国码)
开头0-127与ASCII一致 后面包含更多字符 Emoji
5、自增和自减
i++:先赋值再自增
++i:先自增再赋值
6、赋值运算符
隐含了强制类型转换
byte num = 30;
num += 5;
//num = num + 5;
//num = byte + int;
//num = int + int;
//num = int;
//num = (byte) int;
short a = 5;
short b = 8;
short result = a + b;//错误写法 左侧需要int类型
//short + short -> int + int ->int
short result = 5 + 8;
//在给变量进行赋值的时候,如果右侧的表达式当中全是常量,没有任何变量,那么Java将会直接把若干个常量表达式计算直接得到结果,只要右侧的常量结果数值没有超过左侧范围,就是正确的
//称为“编译器的常量优化”
7、逻辑运算符
&&,|| 具有短路效果 如果左边已经得出结论 便不再执行
int a = 10;
System.out.ptintln(3>4 && ++a <100);
System.out.ptintln(a);//a = 10
int b = 20;
System.out.ptintln(3<4 && ++b <100);
System.out.ptintln(a);//b = 20
8、三目运算符
int a = 10;
int b = 20;
int max = a > b ? a : b;
//判断a>b是否成立,如果成立则将a的值赋值给max,否则赋值给b
//a,b必须符合数据类型
//错误写法
//int result = 3 > 4 ? 2.5 : 10;
9、Switch语句
switch后面小括号当中只能是以下数据类型:
9.1、基本数据
byte/short/char/int
9.2、引用数据
String字符串,enmu枚举
10、数组创建
10.1、动态创建:
数据类型[ ] 数组名称 = new 数据类型[数组长度]
动态创建也可拆分成两个步骤
int[] array = new int[100];
其中元素拥有一个默认值:
整数类型默认为0,浮点类型默认0.0,
字符类型默认’\u0000’,布尔类型默认值为false,引用类型默认为null
10.2、静态创建
(标准格式):
数据类型[ ] 数组名称 = new 数据类型[]{元素1,元素2…}
静态创建标准格式也可拆分成两个步骤
int[] array = new int[] {5,15,25};
10.3、静态创建数组
(省略格式):
数据类型[ ] 数组名称 = {元素1,元素2…}
int[] array = {5,15,25};
静态初始化其实也有一个默认值的过程,只不过系统马上将默认值替换成了大括号的具体数值
11、java 内存划分
11.1、栈
(Stack):
存放方法的局部变量,方法的运行一定要在栈中
局部变量:方法的参数,或者是方法{}内部的变量
作用域:一旦超出作用域,都在堆当中
11.2、堆
(Heap):
凡是new出来的东西,都在堆当中
堆内存的东西都有一个地址值:16进制
堆内存里的数据,都有默认值,规则如创建数组数组默认值
11.3、方法区
(Method Area):
存储 .class相关信息,包含方法的信息
11.4、本地方法栈
(Native Method Stack):
与操作系统相关
11.5、寄存器
(PC Register):
与CPU相关
12、S/Getter方法
Boolean类型
private boolean male;
public void setMale(boolean b){
male = b;
}
public boolean isMale(){
return male;
}
13、java 标准类
JavaBean
①所有的成员都要使用private关键字修饰
②为每一位成员变量都变写一对Setter和Getter方法
③编写一个无参数的构造方法
④编写一个全参数的构造方法
14、for循环
14.1、生成for循环
X.fori;
//X可以为数字或集合对象
X.forr;
//逆序
14.2、增强for循环
底层也是迭代器,使用了for循环的格式,简化了迭代器的书写
for(集合/数组的数据类型 变量名:集合名/数组名){
sout(变量名);
}
int[] arr = {1,2,3,4,5};
for(int i:arr){
System.out.println(i);
}
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
for(String s:list){
System.out.println(s);
}
15、ArrayList
尖括号里面的是泛型数据
泛型只能是引用数据,不能是基本类型,因为集合保存的是地址值,基本类型没有地址值
如果希望向集合中存储基本类型数据,必须使用基本类型对应的“包装类”
Long
,Integer,Short,Byte,Float,Double,
Character,Boolean
基本类型:
a.整数类型:long、int、short、byte
b.浮点类型:float、double
c.字符类型:char
d.布尔类型:boolean
引用类型:
大致包括:类、 接口类型、 数组类型、 枚举类型、 注解类型、 字符串型
String
15.1、创建
ArrayList<String> list = new ArrayList<>();
//从jdk1.7+开始,右侧的尖括号内部可以不写内容
//对于ArrayList集合来说,直接打印的不是地址而是内容
15.2、添加
public boolean add(E e);
//参数类型与泛型一致
list.add(e);
15.3、获取
public E get(int index);
//参数索引编号,返回值对应位置的元素
list.get(index);
15.4、删除
public E remove(int index);
//从集合当中删除元素,返回值为删掉元素
list.remove(index);
15.5、长度
public int size();
//获取集合的尺寸长度,返回值是集合中所包含的元素个数
list.size();
16、字符串
字符串的内容永不可变!
//字符串内容并没有发生变化
//是存在有两个字符串
//str存储的是地址值
//本来存的是hello的地址,后来变成了word的地址
String str = "hello";
System.out.println(str);//hello
str = "world";
System.out.println(str);//world
①字符串效果上相当于Char[ ]字符数组,但是底层原理是byte[ ]字节数组
②字符串常量池:程序当中直接写上的双引号字符串,就在地址常量池当中
对于基本类型来说,= =是进行数值的比较
对于引用类型来说,= =是进行地址值值的比较
③字符串比较方法:
str1.equals(str2);
str1 = "hello";
System.out.println("abc".equals(str1));//推荐写法
System.out.println(str1.equals("abc"));//不推荐写法
//如果str1为null,第二种方式会报空指针异常错误NullPointException
//忽略大小写进行字符串比较
str1.equalsIgnoreCase(str2);
④字符串获取方法:
长度
//获取字符串的长度
str1.length();
拼接
//当前字符串和参数字符串拼接返回新的字符串
String str3 = str1.concat(str2)
查找字符
//获取指定索引位置的单个字符
char ch = str1.charAt(1);
//在一号索引位置的字符是...
查找索引
//查找参数字符串在本字符串中首次出现的索引位置,如果没有返回-1
int i = originStr.indexOf(findStr);
//第一次索引值是...
⑤字符串截取方法:
从指定索引截取字符串
//截取从索引位置一直到字符串末尾,返回新字符串
String str2 = str1.substring(index);
从指定索引到指定索引截取字符串
//从begin开始,一直到end结束,返回中间的字符串作为新字符串,左闭右开
String str2 = str1.substring(begin,end);
⑥字符串中的转换方法:
拆分为字符数组
//将当前字符串拆分成字符数组作为返回值
char[] chars = "hello".toCharArray();
//[h,e,l,l,o]
拆分为字节数组
//获得当前字符串底层的字节数组
byte[] bytes = "abc".getBytes();
//97,98,99
字符串的替换
//将就字符串所有的该字符替换成一个新字符,并返回一个新字符串
String str2 = str1.replace(oldStr,newStr);
⑦字符串分割方法:
按参数规则将字符串切分为若干部分
//返回一个字符串数组
String[] array = str.split(",");
//split方法的参数其实是一个正则表达式
//如果按照英文句号“.”进行切割,必须写为“\\.”(反斜杠)
17、Static
17.1、静态代码块
当第一次用到本类时执行,静态总是优先于非静态
static{
}
//用来一次性对静态成员变量进行赋值
17.2、java.util.Arrays
-
将参数数组变成字符串(按照默认格式:[元素一,元素二,元素三…])
public static String toString(数组)int [] intArray = {10,20,30}; String intStr = Arrays.toString(intArray); System.out.println(intStr);//[10,20,30]
-
按照从小到大的顺序进行数组排序
public static void sort(数组)- 如果是数值,默认从小到大
- 如果是字符串,默认字母升序
- 如果为自定义类型,那么这个自定义的类需要有Comparable或者Comparator接口的支持
int[] Array = {1,5,3,4,2}; Arrays.sort(Array);
17.3、java.util.Math
-
获取绝对值
pubic static double abs(double num)Math.obs(-3.14);//3.14
-
向上取整
public static double ceil(double num)Math.ceil(3.14);//4.0 //向正方向取整
-
向下取整
public staric double floor(double num)Math.floor(3.14);//3.0
-
四舍五入
public static long round(double num)
Math.round(3.14);//3.0
18、继承
18.1、使用
子类名称 extends 父类名称
18.2、重名
-
父子类成员变量重名(编译和运行都看右边)
-
通过子类对象访问成员变量
左边等号是谁,则优先用谁,没有则向上找
-
间接通过成员方法访问成员变量
- 该成员方法属于什么类则优先用什么类,没有则向上找
-
-
父类,子类成员变量和局部变量重名
public class Fu{
int num = 10;
}
public class Zi extends Fu{
int num = 20;
public void method(){
int num = 30;
System.out.println(num);//局部变量
System.out.println(this.num);//本类的成员变量
System.out.println(super.num);//父类的成员变量
}
}
- 父类子类成员方法重名(编译看左边,运行看右边)
- 创建的对象是谁,就优先用谁,没有则向上找
18.3、子类方法重写
-
@Override:写在方法前面,用来检测是不是有效的的正确覆盖重写
-
子类方法的返回值必须小于等于父类方法的返回值范围
例:java.long.Object类是所有类的公共最高父类(祖宗类),java.lang.String就是Object的子类
-
子类方法的权限必须大于等于父类方法的权限修饰符
public > protected > (default) >private
不为关键字default,而是什么都不写,留空
19、抽象类/抽象方法
- 不能直接new抽象类对象
- 必须用一个子类来继承抽象父类
- 子类必须覆盖重写抽象父类所有的抽象方法
public abstract class Animal{
public abstract void eat();
}
public class Cat extends Animal{
public void eat(){
System.out.println("猫吃鱼");
}
}
20、接口
20.1、定义
public interface 接口名称{
//接口内容
}
20.2、方法内容
- 常量
//接口当中也可以定义”成员变量“,但是必须使用public static final三个关键字来修饰,从效果上来看,其实就是接口中的常量
public static final int NUM = 10;
//这就是一个常量,一旦赋值,不可修改
//三个关键字可省略
//常量名称用完全大写字母,用下划线进行分隔
- 抽象方法
public abstract 返回值类型 方法名称(参数列表);
//接口内的抽象方法修饰符必须是public abstract(可省略不写)
- 默认方法
public default 返回值类型 方法名称(参数列表){
//...方法体
}
- 静态方法
//不能通过实现类的对象调用接口的静态方法,可以直接接口名称点方法名称进行使用
public static 返回值类型 方法名称(参数列表){
//...方法体
}
- 私有方法
抽取公共方法,解决两个方法之间重复代码的问题,但是这个方法不应该由实现类来完成,应该是私有的
- 普通私有方法
//解决方法重复代码
private 返回值类型 方法名称(参数列表){
//...方法体
}
- 静态私有方法
//解决静态方法代码重复
private static 返回值类型 方法名称(参数列表){
//...方法体
}
20.3、使用步骤
==注意:==如果实现类没有对接口的所有抽象方法进行覆盖重写,那么这个实现类必须是抽象类
- 接口不能直接使用,必须有一个实现类来实现该接口
public class 实现类名称 implements 接口名称 {
//...方法体
}
- 接口的实现类必须通过覆盖重写实现接口的抽象方法
去掉abstract关键字,加上方法体大括号 - 创建实现类的对象,进行使用
- 如果实现类所实现的多个接口当中,存在重复的抽象方法,那么只需要覆盖重写一次即可
- 如果实现类的多个接口当中,都存在重复的默认方法,则实现类必须对冲突的默认方法进行覆盖重写
- 如果实现类的父类中的方法与接口当中的默认方法起了冲突,那么,优先用父类当中的方法
21、对象转型
21.1、向上转型
右侧创建一个子类对象,把它当成父类看做使用
父类名称 对象名 = new 子类名称();
Animal animal = new Cat();
21.2、向下转型
将父类对象还原成本来的子类对象
子类名称 对象名 = (子类名称) 父类对象;
Cat cat = (Cat) animal;
对象 instanceof 类名称
将会得到一个Boolean值结果,判断前面的对象能不能当作后面类型的实例
22、final
22.1、修饰类
这个类不能有任何子类
22.2、修饰方法
这个方法不能够被覆盖重写,是最终方法
22.3、修饰局部变量
一次赋值,终身不变
对于基本类型来说,不可变说的是变量当中数据不可变
对于引用类型来说,不可变说的是变量当中的地址值不可变
22.4、修饰成员变量
一次赋值,终身不变
成员变量具有默认值,所以添加final必须进行赋值
要么直接赋值,要么通过构造函数赋值
23、成员内部类
内用外,随意用,外用内,必须借助对象
23.1、间接方式
在外部类的方法当中,使用内部类,然后main调用外部的方法
23.2、直接方式
外部类名称 点 内部类名称 对象名 = new 外部类名称() 点 new 内部类名称();
23.3、内部外部类变量重名
访问外部类:外部类名称 点 this 点 外部类变量名
24、匿名内部类
如果接口的实现类(或者父类的子类)只需要使用一次
那么这种情况下就可以省掉该类的定义,改使用匿名内部类
24.1、使用
接口名称 对象名 = new 接口名称(){
//覆盖重写接口对象方法
};
24.2、注意事项
- 匿名内部类在创建对象时只能使用一次
- 匿名对象在调用方法时只能调用一次
- 匿名内部类是省略了实现类/子类名称,匿名对象是省略了对象名称
二、类
1、Object类
1.1、toString
直接打印对象名默认调用toString方法
如果一个类重写了toString方法,直接打印这个类的对象即可
如果没有重写,则打印的是对象的地址值
Random没有重写,String,Scanner和ArrayList重写了方法
1.2、equals
基本类型比较数据,引用类型比较地址
2、Objects类
提供了一些方法来操作对象,是静态的,直接类名点方法就可调用
2.1、equals
允许空指针传入
String s1 = null;
String s2 = "abc";
boolean b1 = s1.equals(s2);//不能调用,空指针异常
//NullPointerException
boolean b2 = Objects.equals(s1,s2);//false
2.2、requireNonNull
判断对象是否为空,如果为空,抛出空指针异常,不为空,则返回该对象
public static T requireNonNull(T obj)
3、Date类
表示时间和日期的类,精确到毫秒
3.1、Date
无参:Date() 表示当前系统的日期和时间,精确到毫秒
有参:Date(long time) (0L)将毫秒转换为date日期
3.2、getTime
long getTime():获取当前日期对象的毫秒值时间
3.3、toLocalString
String toLocalString():根据传入的毫秒值时间按本地格式创建日期对象
4、DateFormat类
抽象类,完成日期和文本的转换,可以在date对象和String对象来回切换,由于是抽象类无法直接使用,需要使用它的子类SimpleDateFormat
4.1、SimpleDateFormat
SimpleDateFormat(String pattern):
pattern:
y:年 M:月 d:日 H:时 m:分 s:秒
yyyy–MM–dd HH:mm:ss
4.2、format
String format(Date d):
按照指定的模式,把Date日期转换为符合模式的字符串
//创建SimpleDateFormat对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy--MM--dd HH:mm:ss");
//创建Date对象
Date date = new Date();
//格式化日期
String text = sdf.format(date);
4.3、parse
Date parse(String s)
把符合模式的字符串转换为Date日期
//创建SimpleDateFormat对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy--MM--dd HH:mm:ss");
//解析符合模式的字符串
Date date = sdf.parse(textStr);
//try catch如果字符串和构造方法中的模式不一样,会抛出异常
5、Calendar类
日历类,也是抽象类,提供了很多操作日历字段的方法,由于是抽象类,无法创建对象,但是里面有一个静态方法getInstance(),该方法返回了calendar类的子类对象
5.1、get
public int get(int field):返回给定日历字段的值
Calendar c = Calender.getInstance();
int year = c.get(Calendar.YRAR)
5.2、set
public void set(int field,int value):将给定的日历字段设置为给定值
Calendar c = Calender.getInstance();
//设置年为9999
c.set(Calendar.YRAR,9999);
//可以同时设置年月日
c.set(8888,8,8);
5.3、add
public abstract void add(int field,int amount):根据日历的规则,为给定的日历字段添加或减去指定的时间量
Calendar c = Calender.getInstance();
//把年增加量两年
c.add(Calendar.YRAR,2);
5.4、getTime
public Date getTime():返回一个表示此Calendar的时间值(从历元到现在的毫秒偏移量)的date对象
Calendar c = Calender.getInstance();
//获取时间,返回值为Date对象
Date date = c. getTime();
6、System类
静态类
6.1、currentTimeMillis
public static long currentTimeMillis():返回以毫秒为单位的当前时间
long time = System.currentTimeMillis();
//获取当前系统时间到1970年1月1日00:00:00(英国格林威治)经历了多少毫秒
//中国属于东八区,会把时间增加八个小时1970年1月1日08:00:00
//可以用于测试程序效率
6.2、arraycopy
public static void arraycopy(Object src, int srcPos, Object dest,int destPos,int length):将数组中的指定的数据拷贝到另一个数组中
源数组 源数组中的起始位置 目标数组 对标数据中的起始位置 要复制数组元素的数量
int src = {1,2,3,4,5};
int dest = {6,7,8,9,10};
System.arraycopy(src,0,dest,0,3);
System.out.println(Arrays.toString(dest));
//[1,2,3,9,10]
7、StringBuilder类
字符串缓冲区,是可以改变的,底层是一个没有被final修饰的数组
字符串的底层是被final修饰的数组,不能改变,是一个常量
7.1、构造方法
-
public StringBuilder():
构建一个空的StringBuilder容器
-
public StringBulider(String str):
构建一个StringBulider容器,并将字符串添加进去
7.2、append
public StringBuilder append(…):添加任意类型数据的字符串形式,并返回当前对象自身
StringBuilder bu1 = new StringBuilder();
StringBuilder bu2 = bu1.append("abc");
System.out.println(bu1==bu2);//true,说明是同一个对象
//直接写
bu1.append("abc");
7.3、toString
String和StringBuilder方法可以相互转换:
-
String–>StringBuilder:
StringBuilder(String str):构建一个字符串生成器,初始化为指定的字符串内容
-
StringBuilder–>String:
public String toString():将当前StringBuilder转换为String对象
String str2 = str1.toSring();
8、Collection集合
Collection集合常用方法 | |
---|---|
boolean add(E e) | 向集合中添加元素 |
boolean remove(E e) | 删除集合中的某个元素 |
void clear() | 清空集合中的所有元素 |
boolean contains(E e) | 判断集合中是否包含某一元素 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 获取集合的长度 |
Object[] toArray() | 将集合转换成一个数组 |
Collection<String> coll = new ArrayList<>();
8.1、list接口
- 有序的集合,存储元素取出元素一致
- 有索引,包含了一些带索引的方法
- 允许存储重复的元素
list接口中带索引的方法(特有) | |
---|---|
public void add(int index ,E element) | 将元素添加到指定位置上 |
public E get(int index) | 返回集合中指定位置的元素 |
public E remove(int index) | 移除列表中指定位置的元素 |
public E set(int index,E element) | 替换集合中指定位置的元素 |
ArrayList:
- 底层是一个数组
- 查询快,增删慢
LinkedList:
- 底层是一个链表结构
- 查询慢,增删快
- 包含大量操作首尾元素的方法
- 不能使用多态
LinkedList的方法 | |
---|---|
public void addFirst(E e ) | 指定元素插入开头,等效push() |
public void addLast(E e) | 指定元素插入末尾,等效add() |
public E getFirst() | 返回列表第一个元素 |
public E getLast() | 返回列表最后一个元素 |
public E removeFirst() | 删除并返回第一个元素 |
public E removeLast() | 删除并返回最后一个元素 |
public E pop() | 弹出一个元素,相当于removeFirst() |
public void push(E e) | 将元素推入此列表所表示的堆栈 |
public boolean isEmpty() | 如果列表不包含元素 |
8.2、set接口
- 不允许存储重复的元素
- 没有带索引的方法,也不能使用普通的for循环遍历
HashSet:
- 无序的集合,存储与元素和取出元素可能不一致
- 底层是一个哈希表结构(查询速度非常快)
使用HashSet集合存储自定义类型元素
HashSet<person> set = new HashSet<>();
//不重写hashCode和equals方法则可以重复添加相同元素
LinkedHashSet:
- 继承自HashSet
- 底层是一个哈希表(数组+链表/红黑树(>8))+链表(记录元素存储顺序,保证元素有序)
- 有序且不允许重复
8.3、Collections
集合工具类部分方法 | |
---|---|
public static boolean addAll(Collection c,T… elements) | 往集合中添加一些元素 |
public static void shuffle(List<?> list) | 打乱集合顺序 |
public static void sort(List list) | 将集合元素按默认规则排序(升序) |
public static void sort(List list,Comparator<? super T>) | 将集合元素按指定规则排序 |
Collections.addAll(list,"a","b","c");
Collections.shuffle(list);
Collections.sort(list);//升序
//对象调用sort方法需要重写compareTo方法
public class Person implements Comparable<Person>
public int compareTo(Person o){
return this.getAge() - o.getAge();
}
/*Comparable接口的排序规则:
自己(this)-参数:升序
*/
/*Comparator和Comparable的区别:
Comparable:自己(this)和别人(参数)比较,自己需要实现Comparable接口,重写比较的规则
Comparator:相当于找个第三方裁判,比较两个*/
Collections.sort(list,new Comparator<Student>(){
@Override
public int compare(Student o1,Student o2){
//按照年龄升序排序
return o1.getAge()-o2.getAge();//升序
}
});
9、Iterator迭代器
可以用迭代器对集合进行遍历
boolean hasNext():判断集合中还有没有元素
E next():返回迭代的下一个元素
Iterator迭代器,是一个接口,需要用实现类
需要用Iterator iterator ()返回在此Collection的元素上进行的迭代器
Collection <String> coll = new ArrayList<>();
coll.add("aAA")
//1.先使用集合中的iterator()获取迭代器的实现类对象
Iterator<String> it= coll.iterator();
//多态 接口 实现类对象
//2.使用Iterator接口中的方法hasNext()判断还有没有下一个元素
boolean b = it.hasNext();
System.out.println(b);//true
//3.使用Iterator接口中的方法next()取出集合中的下一个元素
String s = it.next();
System.out.println(s);//aAA
while(it.hasNext()){
System.out.println(it.next());
}
10、泛型
一种未知的数据类型,也可以看成一个变量用来接受数据类型,是没有继承概念的
10.1、泛型类/泛型方法
public class MyClass<T>{
public void print(T t){
System.out.println(t);
}
}
MyClass<String> my = new MyClass<>();
my.print(str);
10.2、泛型接口/泛型方法
//泛型接口
public interface MyInterface<o>{
public abstract void print(O o);
}
//抽象类
public interface MyInterfaceImp<o> implements MyInterface<o>{
@Override
public void print(O o){
System.out.println(o);
}
}
MyInterfaceImp<String> mi = new MyInterfaceImp<>();
mi.print(str);
10.3、泛型通配符
ArrayList<String> list1 = new ArrayList<>();
ArrayList<Integer> list2 = new ArrayList<>();
print(list1);
pring(list2);
public static void print(ArrayList<?> list){
Iterator<?> it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
Object o = it.next();
System.out.println(o);
}
for(int i = 0; i < list.size(); i++){
System.out.println(list.get(i));
}
}
11、可变参数
11.1、使用前提
当方法的参数列表数据类型已经确定,但是参数个数不确定,就可以使用可变参数
11.2、使用方法
修饰符 返回值类型 方法名(数据类型 … 变量名){}
11.3、可变原理
底层是一个数组,根据传递参数个数不同,会创建不同长度的数组,存储这些参数
//计算o-n整数和
public static int add(int...arr){
//初始化变量
int sum = 0;
for(int i : arr){
sun += i;
}
return sum;
}
//终极写法
public static void method(Object...ob)
11.4、注意事项
- 一个可变方法的参数列表,只能有一个可变参数
- 如果方法的参数有很多个,那么可变参数必须写在参数列表的末尾
12、Map集合
双列集合,一个key,一个value
Map常用方法 | |
---|---|
public V put(K key,V value) | 将指定键与值插入到集合中(如果key不重复,返回null,重复则进行替换,返回被替换的值) |
public V remove(Object key) | 把指定键对应元素进行删除,key存在返回该元素的值,不存在返回null |
public V get(Object key) | 根据指定的键,在Map集合中获取对应的值,不存在返回null |
boolean containKey(Object key) | 判断集合中是否包含指定key,没有则返回false |
Set keySet() | 把Map集合中所有的key存储到Set集合中 |
Set<Map.Entey<K,V>>enteySet() | 把Map集合内部的多个Entry对象取出来存储到一个Set集合当中 |
Map.Entry<K,v>在Map接口中有一个内部接口Entry
作用:当Map集合一创建,那么就会在Map集合中创建一个Entry对象,用来记录键与值(键值对对象,键与值的映射关系)
Entry常用方法 | |
---|---|
getKey() | 获取键 |
getValue() | 获取value |
12.1、HashMap
- java.util.HashMap<k,v> implements Map<k,v>
- 底层哈希表,查找快
- jdk1.8以前,数组+单向列表 jdk1.8以后,数组+单向链表/红黑树(>8)
- 无序集合,存储取出顺序可能不一致
- 可以存储null键,null值
- 是线程不安全的的集合,多线程
12.2、LinkedHashMap
- java.util.LinkedHashMap<k,v> extends HashMap<k,v>
- 底层是一个哈希表+链表,有序
12.3、Hashtable
- java.util.Hashtable<k,v> implements Map<k,v>
- 底层一个哈希表,是一个线程安全的集合,单线程,速度慢
- 不可以存储null键,null值
- 但是它的子类Properties是唯一一个和IO流相结合的集合
13、集合添加元素
jdk9新特性:List接口,Set接口,Map接口,增加了静态方法of
,可以给集合一次性添加多个元素
static list of (E… elements)
使用前提:当集合中存储元素的个数已经确定了并且不再改变时使用
注意事项:
- of方法只适用于List接口,Set接口,Map接口,不适用于接口的实现类
- of方法的返回值是一个不能改变的集合,集合不能再使用add,put方法,否则抛出异常
- Set接口和Map接口在调用of方法时候,不能有重复元素,否则抛出异常
14、Throwable类
Throwable类常用方法 | |
---|---|
String getMessage() | 返回throwable的简短描述 |
String toString() | 返回throwable的详情信息字符串 |
void printStackTrace() | JVM打印异常对象,异常信息最全面 |
14.1、Exception
编译器异常,进行编译(写代码) java程序时产生的异常
-
RuntimeException
java运行过程中产生的异常,把异常处理掉,可以继续工作,可以不处理
-
IOException
必须处理的异常,要么throws,要么try…catch
14.2、Error
无法治愈的毛病,必须修改源代码
异常产生的过程
15、处理异常
15.1、throw
-
作用:在指定的方法抛出指定的异常
-
使用格式:
throw new xxxException(“异常产生的原因”)
-
注意事项:
- 必须写在方法内部
- new的关键字必须是Exception或者Exception的子类对象
- 抛出异常后,必须进行处理,如果为RuntimeException,可以不处理,默认交给JVM来处理这个异常
15.2、throws
-
作用:自己不处理,把异常对象声明抛出给方法的调用者处理,最终交给JVM处理
-
使用格式:
修饰符 返回值类型 方法名(参数列表) throws AAAException,BBBException{
throw new AAAException(“异常产生原因”);
throw new BBBException(“异常产生原因”);
}
-
注意事项:
- 必须写在方法声明处
- 关键字后面生成的异常必须是Exception或Exception的子类
- 方法抛出多个异常对象,关键字后面也要声明多个异常
- 如果抛出异常对象有父子关系,直接声明父类异常即可
- 调用声明抛出异常的方法,就必须进行处理
- 要么throws继续进行抛出,交给方法的调用者处理,最终交给JVM
- 要么try…catch进行处理
15.3、try…catch
-
作用:自己处理异常
-
使用格式:
try{
可能产生异常的代码
}catch(定义一个异常的变量,用来接收try中所抛出的异常对象){
异常的处理逻辑,怎么处理异常对象
一般会写到一个日志中
}
…
catch(异常类名 变量名){
}
-
注意事项:
- try可能会抛出多个异常对象,可以使用多个catch处理这些异常对象
- 多个catch处理异常对象,如果存在子父类关系,则子对象必须写在上面
15.4、finally
- 作用:无论是否出现异常都会执行
- 注意事项:
- 不能单独使用,需要配合try…catch
- 一般用于资源释放(资源回收),无论程序是否出现异常,最后都要进行资源释放(I/O)
15.5、自定义异常类
- 格式:
public class XXXException extends Exception | RuntimeException{
//空参数的构造方法
//带异常信息的构造方法
//String message
//super(message)
}
- 注意事项:
- 自定义异常类一般都以Exception结尾,说明该类是一个异常类
- 必须继承Exception 或 RuntimeException
- Exception:编译器异常,如果方法内部抛出了该异常,就必须进行处理,要么throws,要么try…catch
- RuntimeException:运行时异常,无需处理,交给虚拟机处理(中断处理)
16、Thread类
构造方法 | |
---|---|
public Thread() | 分配一个新的线程对象 |
public Thread(String name) | 分配一个带指定名称的线程对象 |
public Thread(Runnable target) | 分配一个带指定目标的线程对象 |
public Thread(Runnable target,String name) | 分配一个带有指定目标,指定名字的新对象 |
成员方法 | |
---|---|
public String getName() | 获取当前线程名称 |
public void setName(String name) | 改变线程名称 |
public void start() | 此线程开始执行,java虚拟机调用此线程的run方法 |
public void run() | 此线程要执行的任务在此定义代码 |
public static void sleep(long millis) | 使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行) |
public static Thread currentThread() | 返回对当前执行的线程对象的引用 |
创建多线程的方式
16.1、创建线程类
定义线程类,继承自Thread,重写run()方法
16.2、实现Runnable接口
- 创建接口实现类
- 实现类重写run()方法,设置线程任务
- 创建实现类对象
- 创建Thread类对象,构造方法中传递实现类对象
- 调用Thread中的start方法,开启新的线程实现run()方法
17、线程安全
解决:在一个线程在进行访问共享数据的时候,无论是否失去了CPU的执行权,其他的线程都只能等待
17.1、同步代码块
- 使用格式:
synchronized(锁对象){
可能会出现线程安全问题的代码(访问了共享数据的代码)
}
-
注意事项:
- 通过代码块中的锁对象,可以使用任意的对象
- 必须保证多个线程中使用的锁对象是唯一一个
- 锁对象作用:把同步代码块锁住,只让一个线程在同步代码块中运行
- 频繁的判断锁,获取锁,释放锁,程序的效率会变低
-
原理:
- 使用了一个锁对象,这个锁对象叫同步锁,也叫对象锁或者对象监视器
- 同步中的线程,没有执行完毕不会释放锁,同步外的线程没有锁进不去同步
17.2、同步方法
-
使用格式:
-
普通同步方法
修饰符 synchronized 返回值类型 方法名(参数列表){
可能会出现线程安全问题的代码(访问了共享数据的代码)
}
-
静态同步方法
修饰符 static synchronized 返回值类型 方法名(参数列表){
可能会出现线程安全问题的代码(访问了共享数据的代码)
}
访问的共享数据也必须是静态的,静态方法访问静态变量
-
-
注意事项:
- 普通同步方法的锁对象就是Runnable的实现类,也就是this
- 静态同步方法的锁对象是本身的class属性---->class文件对象(反射)
- 静态同步方法的产生优先于实现类对象的产生
17.3、Lock锁
- 使用格式:
- 在成员位置创建实现类对象ReentrantLock对象
- 在可能会出现安全问题的代码前调用lock()方法获取锁
- 在可能会出现安全问题的代码后调用unlock()方法释放锁
lock接口常用方法 | |
---|---|
public void lock() | 获取锁 |
public void unlock() | 释放锁 |
17.4、线程存在的状态
18、线程间的通信
希望线程之间有规律地执行
18.1、等待与唤醒机制
没有包子---->消费者线程唤醒包子铺线程---->消费者线程等待---->包子铺线程开始做包子---->做好包子---->修改包子的状态为:有
有包子---->包子铺线程唤醒消费者进程---->包子铺线程等待---->消费者吃包子---->吃完包子---->修改包子的状态为:没有
……
18.2、线程池
-
生产线程池方法:
- static ExecutorService newFixedThreadPool(int nThread)
- 创建一个可重用固定线程数的线程池
- 返回值是一个ExecutorService接口的实现类对象
-
从线程池中获取线程,调用start方法,执行线程任务:
- Feature <?> submit(Runnable task)
- 提交一个Runnable任务用于执行
-
关闭/销毁线程池:
- void shutdown()
-
使用步骤
- 使用线程池的工厂类Executors里面的静态方法newFixedThreadPool生产一个带指定线程数量的线程池
- 创建一个类,实现Runnable接口,重写run方法,设置线程任务
- 调用ExecutorService里面的submit方法,传递线程任务(实现类),开启线程,执行run方法
- 调用ExecutorService中的方法shutdown销毁线程池(不建议执行)
19、Lambda表达式
不关注中间过程用什么来实现,只关注结果
()->{}有参数小括号内写上参数
表达式延迟执行
19.1、省略前提
- 必须具有接口,且要求接口有且仅有一个抽象方法(有且仅有一个抽象方法的接口也叫做“函数式接口”)
- 必须具有上下文推断,也就是方法的参数或局部变量类型必须为Lambda对应的接口类型
19.2、可以省略的内容
- (参数列表):括号中的参数列表的数据类型,可以省略不写
- (参数列表):括号的参数列表如果只有一个,那么类型和()都可以省略不写
- {一些代码}:如果{}的代码只有一行,无论是否有返回值,都可以省略({},return,分号),但是要省略必须三个同时省略
20、File类
静态变量 | |
---|---|
static String pathSeparator | 与系统相关的路径分隔符 |
static Char pathSeparatorChar | ……windows:分号 linux:冒号 |
static String separator | 与系统相关的默认名称分隔符 |
static char separatorChar | ……windows:反斜杠\ linux:正斜杠/ |
获取功能的方法 | |
---|---|
public String getAbsolutePath() | 返回此File的绝对路径字符串 |
public String getPath() | 将此File转换为路径名字字符串 |
public String getName() | 返回由此File表示的文件或目录的名称 |
public long length() | 返回由此File表示的文件的大小 |
判断功能的方法 | |
---|---|
public boolean exists() | 判断目录或文件是否真实存在 |
public boolean isDirectory() | 判断是否为目录 |
public boolean isFile() | 判断是否为文件 |
创建删除功能的方法 | |
---|---|
public boolean creatNewFile() | 当且仅当该名称的文件不存在时创建 |
public boolean delete() | 删除由此File表示的文件或目录 |
public boolean mkdir() | 创建由此File表示的目录 |
public boolean mkdirs() | 创建由此File表示的目录,包括任何必需但不存在的父目录 |
目录的遍历 | |
---|---|
public String[] list() | 返回一个String数组,表示该File目录中所有的子文件或目录 |
public File[] listFiles() | 返回一个File数组,表示该File目录中所有的子文件或目录 |
21、字节字符流
21.1、字节输出流
OutputStream
基本共性方法 | |
---|---|
public void close() | 关闭此输出流并释放与此流相关的任何系统资源 |
public void flush() | 刷新此输出流并强制任何缓冲的输出字节被写出 |
public void write(byte[] b) | 将b.length字节从指定的字节数组写入此输出流 |
public void write(byte[] b,int off ,int len) | 从指定的字节数组引入len字节,从偏移量off开始输出到此输出流 |
public abstract void write(int b) | 将指定的字节写入此输出流 |
FileOutputStream extends OutputStream
把内存中的数据写入硬盘中的文件中
文件追加写 | |
---|---|
FileOutputStream(String name,Boolean append) | 创建一个向具有指定name的文件写入数据的输出文件流 |
FileOutputStream(File file,Boolean append) | 创建一个向指定File对象表示的文件中写入数据的文件输出流 |
windows:\r\n Linux:/n mac:/r | 换行符写入 |
21.2、字节输入流
InputStream
基本共性方法 | |
---|---|
int read() | 从输入流中读取数据的下一个字节 |
int read(byte[] b) | 从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中 |
void close() | 关闭从输入流并释放与该流关联的所有系统 |
FileInputStream extends InputStream
把硬盘文件中数据读取到内存中
注意事项
使用字节流读取中文文件:
一个中文GBK占两个字节,UTF-8占三个字节
21.3、字符输出流
Writer
共性成员方法 | |
---|---|
void write(int c) | 写入单个字符 |
void write(char[] cbuf) | 写入字符数组 |
abstract void write(char[] cbuf, int off , int len) | 写入字符数组的某一部分,off数组表示开始索引,len表示写的个数 |
void write(String str) | 写入字符串 |
void write(String str,int off,int len) | 写入字符串的某一部分,off字符串表示开始索引,len表示写的个数 |
void flush() | 刷新该流的缓冲 |
void close() | 关闭此流,先刷新它 |
FileWriter Extends OutputStreamReader Extends Writer
把内存中的字符数据写入到硬盘文件中
21.4、字符输入流
Reader
共性成员方法 | |
---|---|
int read() | 读取一个字符并返回 |
int read(char[] cbuf) | 一次读取多个字符,将字符读入数组 |
void close() | 关闭该流并释放与之关联的所有资源 |
FileReader Extends InputStreamReader Extends Reader
把硬盘文件中的数据以字符的的方式读取到内存中
JDK7和JDK9流中异常的处理
-
JDK7新特性
- try的括号里可以定义流对象
- try(流对象1;流对象2;流对象3……)
- 和JDK9类似
-
JDK9新特性
-
try的前边可以定义流对象
-
try的后边()可以直接引入流对象的名称(变量名)
-
在try代码执行完毕后,流对象可以释放掉,而不用写finally
-
格式:
A a = new A();
B b = new B();
try(a,b){
可能会出现异常的代码
}catch(异常类变量 变量名){
异常的处理逻辑
}
-
22、Properties类
-
extends Hashtable<k,v> implements Map<k,v>
-
表示了一个持久的属性集,可保存在流中或从流中加载
-
双列集合默认都是字符串,不用写泛型
常用方法 | |
---|---|
Object setProperty(String key,String value) | 添加集合元素,相当于调用Hashtable的方法put |
String getProperty(String key) | 通过key找到value值,此方法相当于Map集合中的get(key)方法 |
Set stringPropertyNames() | 返回此属性列表的键集,该键及其对应值是字符串,此方法相当于Map集合中的keySet方法 |
void store(OutputStream out,String comments) | 参数为字节流,不能写入中文,commens用于解释说明保存的文件是做什么的,默认Unicode编码,中文会乱码,一般使用空字符串 |
void store(Writer writer,String comments) | 参数为字符流,可以写入中文 |
void Load(InputStream inStream) | 字节输入流,不能读取含有中文的键值对 |
void Load(Reader reader) | 字符输入流,可以读取含有中文的键值对 |
23、缓冲流
23.1、字节缓冲输出流
BufferedOutputStream extends OutputStream
构造方法 | |
---|---|
(OutputStream out) | 创建一个新的缓冲输出流,并写入指定的底层输出流 |
(OutputStream out,int size) | 创建一个新的缓冲输出流,并将指定缓冲区大小的数据写入指定的底层输出流 |
23.2、字节缓冲输入流
BufferedInputStream extends InputStream
构造方法与字节缓冲输出流类似
23.3、字符缓冲输出流
BufferedWriter extends Writer
构造方法 | |
---|---|
(Writer out) | 创建一个使用默认大小输出缓冲区的缓冲字符输出流 |
(Writer out,int size) | 创建一个使用给定大小输出缓冲区的新缓冲字符输出流 |
特有成员方法 | |
---|---|
void newLine() | 会根据不同操作系统获取不同的行分隔符,写入 |
23.4、字符缓冲输入流
BufferedReader extends Reader
构造方法与字符缓冲输出流类似
特有成员方法 | |
---|---|
String readLine() | 读取一个文本行,读取一行数据,行的终止符号:换行(’\n’),回车(’\r’),回车后跟换行(’\r\n’) |
24、转换流
24.1、字节–>字符输入转换流
- InputStreamReader extends Reader
- 把字节按指定编码转换为字符(解码)
构造方法 | |
---|---|
(InputStream in) | 创建一个使用默认字符集的InputStreamReader |
(InputStream in ,String charsetName) | 创建一个使用指定字符集的InputStreamReader |
24.2、字符–>字节输出转换流
- OutputStreamWriter extends Writer
- 把字符按指定编码转换为字节(编码)
构造方法 | |
---|---|
(OutputStream out) | 创建使用默认字符编码的OutputStreamWriter |
(OutputStream out,String charsetName) | 创建使用指定字符编码的OutputStreamWriter |
25、序列/反序列化流
序列化和反序列化的类都要实现Serializable接口(标记型接口),否则会抛出异常
25.1、序列化流
- 把对象以流的方式写入到文件中,叫写对象,也叫对象的序列化
- 对象中包含的不仅仅是字符,使用字节流
- ObjectOutputStream extends OutputStream
构造方法 | |
---|---|
(OutputStream out) | 创建写入指定OutputStream的ObjectOutputStream对象 |
成员方法 | |
void writeObject(Object obj) | 将指定的对象写入ObjectOutputStream |
25.2、反序列化流
- 把文件中保存的对象以流的方式读取进来,叫读对象,也叫对象的反序列化
- 读取的文件保存的都是字节,使用字节流
- ObjectInputStream extends InputStream
构造方法 | |
---|---|
(InputStream in) | 创建从指定的InputStream读取的ObjectInputStream |
成员方法 | |
Object readObject() | 从ObjectInputStream读取对象 |
- readObject():读对象
25.3、类序列号
private static final long serialVersionUID = xxL;(long类型)
定义序列号可以在类成员修饰符改变后还能进行反序列化
26、Transient
- 瞬态关键字
- 和static一样,被关键字修饰的变量不能被序列化
三、Web
1、TCP/IP
-
传输控制协议 (Transmission Control Protocol)。TCP协议是面向连接的通信协议,即传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。
在TCP连接中必须要明确客户端与服务器端,由客户端向服务端发出连接请求,每次连接的创建都需要经过“三次握手”。
- 三次握手:TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠。
- 第一次握手,客户端向服务器端发出连接请求,等待服务器确认。
- 第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求。
- 第三次握手,客户端再次向服务器端发送确认信息,确认连接。整个交互过程如下图所示。
- 三次握手:TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠。
完成三次握手,连接建立后,客户端和服务器就可以开始进行数据传输了。由于这种面向连接的特性,TCP协议可以保证传输数据的安全,所以应用十分广泛,例如下载文件、浏览网页等。
2、UDP
-
用户数据报协议(User Datagram Protocol)。UDP是无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接。简单来说,当一台计算机向另外一台计算机发送数据时,发送端不会确认接收端是否存在,就会发出数据,同样接收端在收到数据时,也不会向发送端反馈是否收到数据。
由于使用UDP协议消耗资源小,通信效率高,所以通常都会用于音频、视频和普通数据的传输例如视频会议都使用UDP协议,因为这种情况即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。
但是在使用UDP协议传送数据时,由于UDP的面向无连接性,不能保证数据的完整性,因此在传输重要数据时不建议使用UDP协议。UDP的交换过程如下图所示。
特点:数据被限制在64kb以内,超出这个范围就不能发送了。
数据报(Datagram):网络传输的基本单位
3、Socket类
3.1、构造方法
Socket(String host,int port):创建一个流套接字并将其连接到指定主机上的指定端口号
String host:服务器主机的名称/服务器的ip地址
int port:服务器的端口号
3.2、成员方法
- OutputStream getOutputStream():返回此套接字的网络字节输出流
- InputStream getInputStream():返回此套接字的网络字节输入流
- void close():关闭此套接字
- void shutdownOutput():禁用此套接字的输出流(文件上传服务器写入结束标记)
4、ServerSocket类
4.1、构造方法
ServerSocket(int port):创建绑定到特定端口的服务器套接字
4.2、成员方法
Socket accept():侦听并接收到此套接字的连接
5、函数式接口
注解:@FunctionalInterface
匿名内部类会生成class文件,但是使用lambda表达式不会
5.1、Supplier接口
- java.util.function.Supplier
- T get():获取一个泛型参数指定类型的对象数据
- 生产型接口:指定接口的泛型是什么数据,那么接口中的get方法就会产生什么类型的数据
5.2、Consumer接口
- java.util.function.Consumer
- void accept(T t):消费一个指定泛型的数据
- 默认方法:andThen(Consumer2):把两个Consumer接口的数据组合进行消费
- 消费型接口:泛型执行什么类型,就可以使用accept方法消费什么类型的数据
5.3、Predicate接口
- java.util.function.Predicate
- boolean test(T t):对某种数据的类型进行判断
- 默认方法:
- and:表示并且关系,也可以用于连接两个判断条件
- or:表示或
- negate:表示非
5.4、Function接口
- java.util.function.Function<T,R>
- R apply(T t):根据参数T的类型获取类型R的结果
- 默认方法:andThen(Function2):组合操作
6、Stream流
JDK1.8后出现,只关注做什么,而不关注怎么做
java.util.stream.Stream
6.1、获取流
- Collection获取流
- default Stream stream()
- 静态方法of获取流
- static Stream of (T…values),可变参数
6.2、常用方法
- 延迟方法:
- 返回值仍然还是Stream接口自身类型的方法
- 终结方法
- 返回值不再时Stream接口类型的方法(count和forEach方法)
延迟方法 | |
---|---|
Stream filter(Predicate<? super T> predicate) | 将一个流转换为另一个子集流 |
Stream map(Function<? super T,extends R> mapper) | 将流中的元素映射到另一个流中(映射) |
Stream limit(long maxsize) | 对流进行截取,只取用前几个 |
Stream skip(long n) | 跳过前n个元素,截取返回之后元素的新流 |
static Stream concat(Stream<? extends T> a,Stream<? extends T>b) | 将两个流合成一个流 |
终结方法 | |
---|---|
void forEach(Consumer<? super T>action) | 接受一个Consumer接口函数,将每一个流元素交给该函数进行处理 |
long count() | 返回流中元素个数 |
7、方法引用
对Lambda表达式进行优化
7.1、方法引用符
- ::(双冒号)
- 如果Lambda要表达的函数方案已经存在于某个方法的实现中,就可以通过双冒号替换Lambda表达式
- Lambda写法:s->System.out.println(s);
- 方法引用写法:System.out::println
7.2、方法引用途径
-
通过对象名引用成员方法(obj::XXX)
-
通过类名引用静态成员方法(Math::abs)
-
通过super引用父类成员方法(super::XXX)
-
通过this引用本类成员方法(this::XXX)
-
类的构造器(构造方法)引用(Person::new)
-
数组的构造器引用(int[]::new)
8、Junit单元测试
使用步骤
-
定义一个测试类(建议类名基本类名+Test,包名xxx.xxx.xx.test)
-
定义测试方法:可以独立运行(建议方法名为test方法名,返回值为void,参数列表为空参)
-
给方法加注解@Test
-
断言Assert.assertEquals(long expect,long result)
-
初始化方法:用于资源申请,所有测试方法执行之前都执行该方法
-
@Before
public void init(){
}
-
-
释放资源方法:在所有测试方法执行完后自动执行该方法
-
@After
public void close(){
}
-
9、反射
将类的各个组成部分封装为其他对象
Java代码在计算机中的过程
Class personClass = Person.class;
//获取类加载器
ClassLoader classloader = Person.class.getClasssLoader();
//获取资源对应的字节流
classloader.getResourceAsStream("xxx(配置文件)")
//加载该类进缓存
Class cls = class.forName(className);
//创建对象
Object obj = cls.newInstance();
9.1、获取成员变量们
- Field[ ] getFields():获取所有的public修饰的成员变量
- Field getField(String name):获取指定名称的public成员变量
- Field[ ] getDeclaredFields():获取所有的成员变量,不考虑修饰符
- Field getDeclaredField(String name):获取指定名称的成员变量,不考虑修饰符
成员变量操作值
- 设置值:void set(Object obj,Object value)
- 获取值:get(Object obj)
- 忽略访问权限修饰符的安全检查:setAccessable(true)…暴力反射
9.2、获取构造方法们
- Constructor<?>[ ] getConstructors():
- Constructor getConstructor(类<?>…paramterTypes):
- Constructor getDeclaredConstructor(类<?>…paramterTypes):
- Constructor<?>[ ] getDeclaredConstructors():
构造器Constructor创建对象
- 创建对象:T newInstance(Object…initargs)
- 空参构造器创建对象(可以使用class里面的newInstance方法):personClass .newInstance()
9.3、获取成员方法们
- Method[ ] getMethods()
- Method getMethod(String name,类<?>… paramterTypes)
- Method[ ] getDeclaredMethods()
- Method getDeclaredMethod(String name,类<?>… paramterTypes)
执行方法
- 执行方法:Object invoke(Object obj,Object… args)
- 获取方法名称:String getName()
9.4、获取类名
- String getName()
9.5、获取class对象
- Class.forName(“全类名”):将字节码文件加载进内存中,返回Class对象(多用于配置文件,将类名定义在配置文件中,读取文件,加载类)
- 类名.class:通过类名的属性class获取(多用于参数的传递)
- 对象.getClass():getClass()方法在Object类中(多用于对象获取字节码的方式)
- 注意:同一个字节码文件(*.class)在一次程序运行的过程中,只会被加载一次,不论通过哪一种方式获得的Class类对象都是同一个
9.6、使用class对象
- 获取成员变量们
- 获取构造方法们
- 获取成员方法们
- 获取类名
9.7、框架
- 将需要创建的对象的全类名和需要执行的方法定义在配置文件中
- 在程序中加载读取配置文件
- 使用反射技术来加载类文件进内存
- 创建对象
- 执行方法
10、注解
Annotation
10.1、JDK预定义注解
- @Override:检测被该注解表示的方法是否继承自父类(接口)的
- @Deprecated:表示该注解标注的内容,表示已过时
- @SuppressWarnings:压制警告SuppressWarnings(“all”)
10.2、自定义注解
-
格式
-
元注解:用于描述注解的注解
- @Target:表示注解能够作用的位置
- (value={ElementType.TYPE})表示该注解只能作用于类上
- (value={ElementType.METHOD})表示该注解只能作用于方法上
- (value={ElementType.FIELD})表示该注解只能作用于成员变量上
- @Retention:描述注解被保留的阶段
- (RetentionPolicy.RUNTIME):当前被描述的注解,会保留到class字节码文件中,并被JVM读取到
- @Documented:描述注解是否被抽取到api文档中
- @Inherited:描述注解是否被子类继承
- @Target:表示注解能够作用的位置
-
public @interface 注解名称{
属性列表;
}
-
-
本质:
- 本质是一个接口,该接口默认继承Annotation接口
- public interface MyAnno extends java.lang.annotation.Annotation{ }
-
属性:接口中的抽象方法
要求:
- 属性的返回值类型
- 基本数据类型
- String
- 枚举(Enum)
- 注解
- 以上类型的数组
- 定义了属性,需要给属性赋值
- 定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以省略该属性的赋值
- 如果只有一个属性需要赋值,并且属性的名称为value,则使用注解进行属性赋值的时候,可以省略注解的名称value
- 给数组类型的属性赋值时,右侧为大括号{ },如果数组只有一个成员,则大括号可以省略不写
- 属性的返回值类型
10.3、在程序中使用(解析)注解
获取注解中定义的属性值
解析注释
- 获取该类的字节码文件对象/注解定义位置的对象(Class,Method,Field)
Class<ReflectTest> reflectTestClass = ReflectTest.class;
- 获取上边的注解对象(实际上就是在内存中生成了一个该注解接口的子类实现对象)
Pro an = reflectTestClass.getAnnotation(Pro.class);
- 调用注解对象中定义的抽象方法,获取返回值
String className = an.className();
String methodName = an.methodName();
- 加载该类进内存
Class cls = Class.forName(className);
- 创建对象
Object obj = cls.newInstance();
- 获取方法对象
Method method = cls.getMethod(methodName);
- 执行方法
method.invoke(obj)
11、MySQL
11.1、控制台服务启动,关闭
- net start mysql
- net stop mysql
11.2、控制台登录
- mysql -u用户名 -p密码
- mysql -h连接目标的ip地址 -u用户名 -p密码
- mysql --host=ip --user=用户名 --password=密码
11.3、Sql注释
- 单行:
- –注释
- #注释(MySQL特有)
- 多行:
- /* 注释 */
12、Sql
12.1、DDL
操作数据和表:数据定义语言(create,drop,alter等)
-
操作数据库
-
创建数据库:
create database 数据库名称;
-
创建数据库之前判断是否存在:
create database if not exists 数据库名称;
-
创建数据库之前指定字符集:
create database 数据库名称 character set 字符集名称;
-
查询所有数据库:
show databases;
-
查询某个数据库名称的字符集(查询某个数据库的创建语句):
show create database 数据库名称;
-
修改数据库的字符集:
alter database 数据库名称 character set 字符集名称;
-
删除数据库:
drop database 数据库名称;
-
删除数据库之前判断数据库是否存在:
drop database if exists 数据库名称;
-
查询当前正在使用的数据库名称:
selet database();
-
使用数据库:
use 数据库名称;
-
-
操作表
-
创建表:
create table 表名(
列表1 数据类型1,
列表2 数据类型2,
......,
列表n 数据类型n
)
-
复制表:
create table 表名 like 被复制的表名;
-
查询一个数据库所有表的名称:
show tables;
-
查询表结构:
desc 表名;
-
查询表的字符集:
show create table 表名;
-
修改表名:
alter table 表名 rename to 新的表名;
-
修改表的字符集:
alter table 表名 character set 字符集名称;
-
添加一列:
alter table 表名 add 列名 数据类型;
-
修改列名称,类型:
alter table 表名 change 列名 新列名 新数据类型;
(修改列名和数据类型)alter table 表名 modify 列名 新数据类型;
(修改数据类型)
-
删除列:
alter table 表名 drop 列;
-
删除表:
drop table 表名;
-
删除表之前判断是否存在:
drop table if exists 表名;
-
12.2、DML
增删改表中数据:数据操作语言(insert,delete,update等)
- 表中添加数据:
insert into 表名(列名1,列名2,...列名n) values(值1,指2,...值n);
- 注意:如果表名后不定义列名,则默认给所有列添加值
- 表中删除数据:
delete from 表名 [where条件];
- 注意:如果不加where条件,则删除表中所有记录(有多少记录,执行多少次删除操作,效率低)
- 删除表:
truncate table 表名;
(先删除表,再创建一个一模一样的空表) - 修改表数据:
update 表名 set 列名1 = 值1 , 列名2 = 值2...[where条件];
- 注意:如果不加where条件,则默认修改表中所有数据
12.3、DQL
查询表中数据:数据查询语言(select,where等)
- 查询表中所有列表:
select * from 表名;
- 查询表指定列记录:
select 字段列1,字段列2... from 表名;
- 计算列:可以使用四则运算
- 去掉重复的结果集:字段列表前加
distinct
- ifnull(表达式1,表达式2):null参与的运算,结果都为null
- 表达式1:哪个字段需要判断是否为null
- 表达式2:如果为null的替换值
- 取别名:as 或 空字符和别名
- 运算符:
- 大于,小于,大于等于,小于等于,等于,<>/!=(不等于)
- between…and
- in(X,X)
- like
- is null(null值不能用等号来判断)
- and / &&
- or / ||
- not / !
- 模糊查询:like
- 占位符:
- _:单个字符
- %:多个字符
- 占位符:
- 排序:
select * from 表名 order by 排序字段1 排序方式1,排序字段2 排序方式2...
- 排序方式:
- 升序:ASC(默认)
- 降序:DESC
- 如果有多个排序条件,则当前面的排序条件一样时,才会判断下一个条件
- 排序方式:
- 计算个数:
select count(计算列的名称) from 表名;
- 一般用选择主键列
- count(*)
- 计算最大值:
select max(统计列的名称) from 表名;
- 计算最小值:
select min(统计列的名称) from 表名;
- 计算和:
select sum(统计列的名称) from 表名;
- 计算平均值:
select avg(统计列的名称) from 表名;
- 所有计算函数的计算都忽略null的值:
- 选择不包括非空的列
- ifnull函数
select count(ifnull(计算列的名称,0) from 表名;
- 分组查询:
select 分组字段,聚合函数 from 表名 group by 分组字段;
- 分组前加条件:表名后,group前加where条件或分组后加having条件
- where和having区别:
- where在分组之前限定,不满足不参与分组
- having在分组后限定,不满足不会被查询
- where后不可以跟聚合函数
- having后可以进行聚合函数的判断
- 分页查询:
select * from 表名 limit 开始索引,每页显示的条数
- 开始的索引 = (当前的页码-1)*每页显示的条数
12.4、DCL
管理用户,授权:数据控制语言
- 管理用户:
- 添加用户:
create user '用户名'@'主机名' identified by '密码' ;
- 主机名写通配符
%
则表示任意主机均可登录
- 主机名写通配符
- 删除用户:
drop user '用户名'@'主机名';
- 修改用户密码:
update user set password = password('新密码') where user = '用户名';
set password for '用户名'@'主机名' = password('新密码');
- 忘记root密码:
- 停止MySQL服务:
cmd -->net stop mysql
(管理员运行权限) - 使用无验证方式启动MySQL服务:
mysqld --skip-grant-tables
- 打开新命令行,直接输入mysql登录,改密码
- 关掉两个cmd窗口
- 打开任务管理器,结束mysqld.exe进程
- 启动MySQL服务:
cmd -->net start mysql
(管理员运行权限)
- 停止MySQL服务:
- 查询用户:
- 切换到MySql数据库
- 查询user表
- 添加用户:
- 授权:
- 查询权限:
show grants for '用户名'@'主机名';
- 授予权限:
grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';
- 赋予所有权限:
grant all on *.* to '用户名'@'主机名';
- 撤销权限:
revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';
- 撤销所有权限:revoke all on . to ‘用户名’@‘主机名’;`
- 查询权限:
12.5、数据类型
常用类型 | |
---|---|
int | 整数类型 |
double(最多几位,小数点后保留几位) | 小数类型 |
date(yyyy-MM–dd) | 只包含年月日的日期 |
datetime(yyyy-MM–dd HH:mm:ss) | 包含年月日,时分秒的日期 |
timestamp(yyyy-MM–dd HH:mm:ss) | 时间戳类型(如果将来不给这个字段赋值,或者赋值为null,会自动使用系统时间) |
varchar(最大支持字符) | 字符串 |
13、约束
对表中的数据进行限定,从而保证数据的正确性,有效性,完整性
13.1、主键约束
primary key(非空且唯一),一张表只能有一个字段为主键,表中记录的唯一标识
- 创建表时添加约束:
列表 数据类型 primary key
- 在创建表之后添加主键:
alter table 表名 modify 列表名 数据类型 primary key;
- 删除主键:
alter table 表名 drop primary key;
- 自动增长:
- 如果某一列是数值类型的,可以使用auto_increment完成值的自动增长
- 创建表时,添加主键约束,并且完成主键自增长
- 创建表时添加自动增长:
id int primary key auto_increment
- 创建表之后添加自动增长:
alter table 表名 modify 字段名 数据类型 auto_increment
- 删除自动增长:
alter table 表名 modify 字段名 数据类型
13.2、非空约束
not null
- 创建表时添加约束:
列表 数据类型 not null
- 在创建表之后添加非空约束:
alter table 表名 modify 列表名 数据类型 not null;
- 删除非空约束:
alter table 表名 modify 列表名 数据类型;
13.3、唯一约束
unique
- 创建表时添加唯一约束:
列表 数据类型 unique
- 在创建表之后添加唯一约束:
alter table 表名 modify 列表名 数据类型 unique;
- 删除唯一约束:
alter table 表名 drop index 列表名;
13.4、外键约束
foreign key
- 创建表时,添加外键:
constraint 外键名称 foreign key (外键列名称) references 主表名称(主表列名称)
- 创建表之后添加外键:
alter table 表名 add constraint 外键名称 foreign key (外键列名称) references 主表名称(主表列名称);
- 删除外键:
alter table 表名 drop foreign key 外键名称;
- 级联操作:添加外键,设置级联
- 级联更新:
XXXXX on update cascade;
- 级联删除:
XXXXX on delete cascade;
- 级联更新:
14、多表之间的关系
14.1、一对一
实现方式:
- 任意一方添加唯一unique外键指向另一方的主键
- 设置相同主键
14.2、一对多(多对一)
实现方式:在多的一方建立外键,指向一的一方的主键
14.3、多对多
实现方式:借助中间表,至少包含两个字段,这两个字段作为第三张表的外键,分别指向两张表的主键,同时也为联合主键
15、范式
设置数据库时需要遵循的规范
15.1、第一范式
每一列都是不可分割的原子数据项
15.2、第二范式
在第一范式的基础上,非码属性必须完全依赖于码(在1NF基础上消除主属性对主码的部分函数依赖)
- 函数依赖:A->B,如果通过A属性(属性组:多个属性确定一个别的属性)的值,可以确定唯一B属性的值,则称B依赖于A
- 完全函数依赖:A–>B,如果A是一个属性组,则B属性值的确定依赖于A属性组的所有属性值(学号,课程名称–>分数)
- 部分函数依赖:A–>B,如果A是一个属性组,则B属性值的确定只需要依赖于A属性组的某一些值即可(学号,课程名称–>姓名)
- 传递函数依赖:A–>B,B–>C,如果通过A属性(属性组)的值,可以确定唯一B属性的值,再通过B属性(属性组)的值可以唯一确定C属性的值,则称为传递函数依赖于A(学号–>系名,系名–>系主任)
- 码:如果在一张表中,一个属性或属性组被其他所有属性所完全依赖,则成为这个属性(属性组)为该表的码
- 主属性:码属性组中的所有属性
- 非主属性:除过码属性组的属性
15.3、第三范式
在第二范式的基础上,任何非主属性不依赖其他非主属性(在2NF基础上消除传递依赖)
16、数据库备份还原
16.1、命令行
-
备份:mysqldump -u用户名 -p密码 数据库名称 > 保存的路径
-
还原:
- 登录数据库
- 创建数据库
- 使用数据库
- 执行文件 source 文件路径
16.2、图形化工具
- 备份:右键备份
- 还原:执行Sql脚本
17、多表查询
笛卡尔积:有两个集合A,B,取这两个集合的所有组成情况为笛卡尔积
要完成多表查询,要消除无用的数据
17.1、内连接
查询交集部分
- 隐式:使用
where
条件消除无用的数据 - 显示:
select 字段列表 from 表名1 (inner可省略) join 表名2 on 条件;
- 注意事项:
- 从哪些表中查数据
- 条件要确定
- 查询哪些字段
17.2、外连接
查询X表所有数据以及交集部分
- 左外连接:
select 字段列表 from 表1 left (outer) join 表2 on 条件;
- 右外连接:
select 字段列表 from 表1 right (outer) join 表2 on 条件;
17.3、子查询
查询中嵌套查询,则称嵌套查询为子查询
- 结果单行单列:
- 子查询作为条件,使用运算符(> >= < <= =)去判断
select XX from 表名 where XXX = (select XXX from 表名);
- 结果单行多列:
- 子查询作为条件,使用运算符
in
判断 select XX from 表名 where XXX in (select XXX from 表名 where XX = XX or XX = XX);
- 子查询作为条件,使用运算符
- 结果多行多列:
- 子查询作为虚拟表
select XX from 表名 别名 (select XX from 表名) 别名 where 别名.XX = 别名.XX
- 也可以用普通内连接
18、事务
18.1、基本介绍
- 概念:如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败
- 操作:
- 开启事务:
start transaction
- 回滚:
rollback
- 提交:
commit
- 开启事务:
- MySQL数据库中事务默认自动提交:一条DML(增删改)语句会自动提交一次事务
- 查看事物的提交方式:
select @@autocommit;-- 1代表自动提交,-- 0代表手动提交
- 修改事务提交方式:
set @@autocommit = X
18.2、四大特征
- 原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败
- 持久性:当事务提交或回滚后,数据库会持久化的保存数据
- 隔离性:多个事物之间相互独立
- 一致性:事务操作前后数据总量不变
18.3、隔离级别
-
概念:多个事物之间隔离的,是相互独立的,但是多个事务操作同一批数据,会引发一些问题,设置不同的隔离级别就可以解决这些问题
-
存在问题:
- 脏读:一个事务读到了另一个事务中没有提交的事务
- 不可重复读:在同一个事务中,两次读取到的数据不一样
- 幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一条事务查询不到自己的修改
-
隔离级别:
-
read uncommited:读未提交
- 产生的问题:脏读,不可重复读,幻读
-
read commited:读已提交(Oracle默认)
- 产生的问题:不可重复读,幻读
-
repeatable read:可重复读(MySQL默认)
- 产生的问题:幻读
-
serializable:串行化
- 可以解决所有的问题
-
隔离级别从小到大安全性越来越高,但是效率越来越低
-
-
查询隔离级别:
select @@tx_isolation;
-
设置隔离级别:
set global transaction isolation level 级别字符串;
19、JDBC
19.1、Java DataBase Connectivity :
Java连接数据库,Java语言操作数据库
19.2、本质:
官方定义的一套操作所有关系型数据库的规则,即接口,各个数据库厂商去实现这套接口,提供数据库驱动jar包,我们可以使用这套(JDBC)编程,真正执行的代码是驱动jar包中的实现类
19.3、快速入门:
- 导入驱动jar包
- 复制jar包到目录下
- 右键 add as library
- 注册驱动
- 获取数据库连接对象Connection
- 定义sql
- 获取执行sql语句的对象 Statement
- 执行sql,接受返回结果
- 处理结果
- 释放资源
19.4、各个对象:
-
DriverManger:驱动管理对象
- 注册驱动
- 注册与给定的驱动程序DriverManager:
static void registerDriver(Driver driver);
- 通常用:
Class.forName("com.mysql.jdbc.Driver")
- 中有静态代码块,注册驱动
- MySQL5之后的驱动jar包可以省略注册驱动的步骤
- 注册与给定的驱动程序DriverManager:
- 获取数据库连接
- 方法:
static Connection getConnection(String url, String user ,String password);
- 参数:
- url:指定连接的路径
jdbc:mysql://ip地址(域名):端口号/数据库名称
- 如果连接本机MySQL服务器,并且端口号是3306,则url可以简写
jdbc:mysql:///数据库名称;
- user:用户名
- password:密码
- url:指定连接的路径
- 参数:
- 注册驱动
-
Connection:数据库连接对象
- 获取执行sql的对象
Statement createStatement()
Prepared Statement prepareStatement(String sql)
- 管理事务
- 开启事务:
void setAutoCommit(boolean autoCommit)
:设置参数为false开启事务 - 提交事务:
commit()
- 回滚事务:
rollbace()
- 开启事务:
- 获取执行sql的对象
-
Statement:执行静态sql的对象
- 执行sql
- 执行DML(insert,update,delete),DDL(create,alter,drop)语句:
int executeUpdate(String sql)
- 返回值是影响的行数,可以通过返回值判断函数是否执行成功(>0)
- 执行DQL(select)语句:
ResultSet executeQuery(String sql)
- 执行任意sql:
boolean execute(String sql):
- 执行DML(insert,update,delete),DDL(create,alter,drop)语句:
- 执行sql
-
ResultSet:结果集对象(封装查询结果)
-
游标向下移动一行:
next()
-
获取内容:
getXxx(参数)
- xxx代表数据类型
- 参数:
- int:代表列的编号
- String:代表列的名称
-
while(rs.next()){
//数据类型 变量名 = re.getXXX(int/String);
}
-
PreparedStatement:执行动态sql的对象
-
SQL注入问题:在拼接sql时,有sql的一些特殊关键字参与字符串的拼接,造成安全性问题
select * from user where username = 'XXX' and password = 'XXX' or 'a'='a'
-
解决:PreparedStatement预编译sql
- 预编译sql:参数使用?作为占位符,需要在执行sql给?赋值
-
String sql = "select * from user where username = ? and password=?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1,username);
pstmt.setString(2,password);
rs = pstmt.executeQuery();
20、JDBC工具类
简化书写
-
抽取注册驱动
-
抽取连接(使用配置文件方式)
- 不想传递参数,还得保证工具类的通用性
- 配置文件(文件的读取只需要一次):
- jdbc.properties
- url =
- user =
- password =
- driver =
private static String url;
private static String user;
private static String password;
private static String Driver;
static {
//加载文件
try {
//创建Properties
Properties pro = new Properties();
//获取src路径下文件的方式:ClassLoader类加载器
//ClassLoader classLoader = JDBCUtils.class.getClassLoader();
//获取Url统一资源定义符
//中文路径
//URI resource = null;
//try {
//resource = classLoader.getResource("jdbc.properties").toURI();
//} catch (URISyntaxException e) {
//e.printStackTrace();
//}
//英文路径
//URL resource = classLoader.getResource("jdbc.properties");
//String path = resource.getPath();
//pro.load(new FileReader(path));
//简写列式编程
pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties"));
//获取数据,赋值
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
Driver = pro.getProperty("Driver");
//加载驱动
Class.forName(Driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection(){
try {
return DriverManager.getConnection(url, user, password);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
- 抽取释放资源
public static void close(Statement stmt, Connection conn){
close(null,stmt,conn);
}
public static void close(ResultSet rs, Statement stmt, Connection conn){
if(rs != null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(stmt != null){
try{
stmt.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(conn != null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
21、JDBC控制事务
使用Connection来管理事务
- 开启事务:
void setAutoCommit(boolean autoCommit)
:设置参数为false开启事务 - 提交事务:
commit()
- 回滚事务:
rollback()
if(conn != null){
conn.rollback();
}
22、JDBCTemplate
JDBC Template–Spring框架的简单封装(提供了一个JDBCTemplate对象简化JDBC的开发)
-
导入jar包
-
创建对象jdbcTemplate,依赖于数据源DataSource
JdbcTemplate template = new JdbcTemplate(ds);
-
调用jdbcTemplate完成增删改查操作
update():执行DML语句
queryForMap():查询结果将结果封装为Map集合
- 返回键值对,查询的结果集长度只能为一
queryForList():查询结果将结果封装为List集合
queryForObject():查询结果,将结果封装为对象
- 一般执行聚合函数
Long total = template.queryForObject(sql3, Long.class);
query():查询结果,将结果封装为JavaBean对象
- 参数RowMapper,用BeanPropertyRowMapper实现类,完成数据到JavaBean的自动封装
new BeanPropertyRowMapper <类型>(类型的字节码文件 类型.class)
List<demo1> list = template.query(sql2, new BeanPropertyRowMapper<demo1>(demo1.class));
23、数据库连接池
23.1、C3P0
- 导入jar包(两个):c3p0-0.9.5.5.jar,mchange-commons-java-0.2.19.jar
- 定义配置文件:
- 名称:c3p0.properties 或 c3p0-config.xml
- 路径:直接将文件放在src目录下
- 获取数据库池连接对象:
ComboPooledDataSource
- 获取连接:getConnection
//1.创建数据库连接池对象
//默认配置
//DataSource ds = new ComboPooledDataSource();
//指定名称配置
DataSource ds = new ComboPooledDataSource("c3p0");
//2.获取连接对象
try {
Connection conn = ds.getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
23.2、Druid
- 导入jar包:druid-1.0.9.jar
- 定义配置文件:
- properties形式的
- 可以叫任意名称,可以放到任意目录下
- 获取数据库池连接对象:通过工厂类来获取 DruidDataSourceFactory
//1.加载配置文件
Properties pro = new Properties();
InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
//2.获取连接池对象
DataSource ds = DruidDataSourceFactory.createDataSource(pro);
//3.获取连接
Connection conn = ds.getConnection();
23.3、Druid工具类
- 提供静态代码块加载配置文件,初始化连接池对象
- 获取连接:通过数据库连接池获取连接
- 释放资源
- 获取连接池方法
private static DataSource ds;
static {
try {
//1.加载配置文件
Properties pro = new Properties();
pro.load(DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
//2.获取DataSource
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
//释放资源
public static void close(Statement stmt, Connection conn){
close(null,stmt,conn);
}
public static void close(ResultSet rs ,Statement stmt, Connection conn){
if(rs != null){
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(stmt != null){
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(conn != null){
try {
conn.close();//归还连接
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
//获取连接池
public static DataSource getDataSource(){
return ds;
}
四、JavaWeb
1、ECMAScript
1.1、数据类型
- 原始数据类型
- number:数字/小数/Nan(not a number)
- string:字符串
- boolean:true/false
- null:一个对象为空的占位符
- undefined:未定义,如果一个变量没有初始化值,则默认赋值为undefined
- 引用数据类型:对象
1.2、变量
- 定义:
var 变量名 = 初始值;
- 获取变量类型
typeof(变量名)
1.3、对象
- Function
- 创建:
function 方法名称(形式参数列表){方法体}
var 方法名 = function(形式参数列表){方法体}
- lenth方法:参数的个数
- 内置对象arguments,类型是一个数组
- 创建:
- Array
- 创建:
var arr = new Array(元素列表);
var arr = new Array(默认长度);
var arr = [元素列表];
- 方法:
- join(参数):将数组中的元素按照指定分隔符进行拼接成字符串
- push(参数):将数组的末尾添加一个或更多元素,返回新数组的长度
- 创建:
- Date
- 创建:
var date = new Date()
- 方法:
- toLocaleString:返回当前对象对应时间的本地字符串格式
- getTime():返回当前时间到1970年1月1日的毫秒值差
- 创建:
- Math
- 创建:
- 不用创建,直接Math.方法
- 方法:
- PI
- random():返回0~1之间的随机数(含0不含1)
- ceil(X):对数进行上取整
- floor(X):对数进行下取整
- round(X):四舍五入
- 创建:
- RegExp
- 正则表达式:
- 单个字符:[ ]
- 例:[a] [ab] [a-zA-Z0-9_]
- \d:单个数字字符[0-9]
- \w:单个单词字符[a-zA-Z0-9_]
- 量词符号:
- ?:表示出现0次或1次
- *:表示出现0次或多次
- +:表示出现1次或多次
- {m,n}:m<= 数量 <= n
- m缺省表示最多n次
- n缺省表示最少m次
- ^:开始
- $:结束
- 单个字符:[ ]
- 正则对象:
- 创建:
var reg = new RegExp("正则表达式")
- var reg =
/正则表达式/
- 方法:
- test(参数):验证指定字符串是否符合正则规范
- 创建:
- 正则表达式:
- Global
- 特点:
- 全局对象,Global中的方法不需要对象就可以直接使用
- 方法:
- encodeURI():url编码
- decodeURI():url解码
- encodeURIComponent():url编码,编码字符更多
- decodeURIComponent():url解码
- parseInt():将字符串转换为数字(逐一判断,直到不是数字为止)
- isNaN():判断一个值是否是NaN
- eval():将JavaScript字符串转换为JavaScript脚本来执行
- 特点:
2、BOM
Browser Object Model 浏览器对象模型,将浏览器的各个组成部分封装成对象
2.1、Window
窗口对象
- 方法:
- 与弹出框有关方法
- alert()
- confirm():确认取消对话框,确定返回true,取消返回false
- prompt():显示一个用户可以输入的对话框
- 与打开关闭有关方法
- close():关闭正在运行的窗口,哪个对象调用关哪个对象
- open():打开一个新的浏览器窗口,返回新窗口的window对象
- 与定时器有关的方法
- setTimeout(参数1,参数2):一次性定时器,第一个参数js代码或方法对象,第二个参数毫秒值,有返回值,返回Timeout名称
- clearTimeout(Timeout名称):取消定时器
- setInterval(参数1,参数2):循环定时器,参数类型与setTimeout一致,也有返回值
- clearInterval(Interval名称):取消循环定时器
- 与弹出框有关方法
- 特点:
- 不需要创建,直接使用window.方法名();
- window引用可以省略
- 属性:
- 获取其他BOM对象(Navigator,Screen,History,Loaction)
- 获取DOM对象
2.2、Navigator
浏览器对象
2.3、Screen
显示器对象
2.4、History
历史器对象
2.5、Loaction
地址栏对象
- 方法:
- reload():刷新页面
- 属性:
- href:修改href
3、DOM
Document Object Model 将标记语言文档的各个组成部分,封装成对象,可以使用这些对象,对标记语言文档进行CURD的动态操作
3.1、核心DOM
针对任何结构化文档的标准模型
-
Document:文档对象
- 方法:
- getElementBy XX()
- createXX()
- removeAttribute():删除属性
- setAttribute():设置属性
- 方法:
-
Element:元素对象
-
Attribute:属性对象
-
Text:文本标签
-
Comment:注释对象
-
Node:节点对象,其他5个的父对象
-
特点:
- 所有DOM对象都可以被认为是一个节点
-
方法:
- appendChild():向节点的子节点列表的结尾添加新的子节点
- removeChild():删除并返回当前节点的指定子节点
- replaceChild():用新节点替换一个子结点
-
属性:
- parentNode:返回节点的父节点
-
3.2、HTML DOM
针对HTML文档的标准模型
- 标签体的设置和获取:innerHTML(文本字符串和标签字符串都可以写)
- 使用html元素对象的属性
- 控制元素样式:
- 使用元素style属性:
XXX.style.xx = ""
- 通过元素classname属性:
XXX.className = ""
- 修改类名后加载style下类选择器对应的样式
- 使用元素style属性:
3.3、XML DOM
针对XML文档的标准模型
3.4、事件监听机制
- 概念:某些组件被执行了某些操作后,触发某些代码的行为
- 事件:某些操作
- 事件源:组件
- 监听器:代码
- 注册监听:将事件,事件源,监听器结合在一起,当时减员上发生了某个事件,则触发执行某个监听器代码
- 常见事件:
- 点击事件
- onclick:点击事件
- ondbclick:双击事件
- 焦点事件
- onblur:失去焦点
- onfocus:获得焦点
- 加载事件
- onload:一张页面或一张图加载完成
- 鼠标事件
- onmousedown:鼠标按钮被按下
- 定义方法时定义形参,接受event对象,button属性获取鼠标按键
- onmouseup:鼠标按键被松开
- onmousemove:鼠标被移动
- onmouseover:鼠标移到某元素之上
- onmouseout:鼠标从某元素移开
- onmousedown:鼠标按钮被按下
- 键盘事件
- onkeydown:某个键盘按键被按下
- 定义方法时定义形参,接受event对象,keycode属性获取鼠标按键
- onkeyup:某个键盘按键被松开
- onkeypress:某个键盘按键被按下并松开
- onkeydown:某个键盘按键被按下
- 选中和改变
- onchange:域的内容被改变
- onselect:文本被选中
- 表单事件
- onsubmit:确认按钮被点击
- onreset:重置按钮被点击
- 点击事件
4、Bootstrap
https://v3.bootcss.com/
4.1、响应式布局
- 不同设备显示不同的内容
- 实现:依赖于栅格系统:将一行平均分成十二个格子,可以指定元素占几个格子
- 步骤:
- 定义容器,相当于之前table
- container:两边有一些留白
- container-fluid:100%宽度
- 定义行,相当于之前tr
- row
- 定义元素,指定该元素在不同设备上,所占的格子数
- 样式:col-设备代号-格子数目
- col-xs: 超小屏幕 手机 (<768px)
- col-sm:小屏幕 平板 (≥768px)
- col-md:中等屏幕 桌面显示器 (≥992px)
- col-lg:大屏幕 大桌面显示器 (≥1200px)
- 如果一行格子数目超过12,则超过部分自动换行
- 栅格类属性向上兼容
- 样式:col-设备代号-格子数目
- 定义容器,相当于之前table
4.2、CSS样式
- 按钮:
class="btn btn-default(默认样式)/primary(首选项)/success(成功)/info(一般信息)/warning(警告)/danger(危险)/link(链接)
- 图片:
- 图片任意尺寸都占100%:
img-responsive
- 图片形状:
img-rounded(方)/img-circle(圆)/img-thumbnail(有边框)
- 图片任意尺寸都占100%:
- 表格:
- 基本样式的表格:
class="table"
- 条纹状的表格:
class="table table-striped"
- 带边框的表格:
class="table table-bordered"
- 鼠标悬停:
class="table table-hover"
- 基本样式的表格:
- 表单:https://v3.bootcss.com/css/#forms
4.3、组件
- 导航条:https://v3.bootcss.com/components/#navbar-component-alignment
- 分页条:https://v3.bootcss.com/components/#pagination
4.4、JS插件
- 轮播图:https://v3.bootcss.com/javascript/#carousel
5、XML
5.1、概念
Extensible Markup Language 可扩展标记语言
- 可扩展:标签都是自定义的
5.2、功能
- 存储数据
- 配置文件
- 在网络中传输
5.3、和HTML区别
- 都属于w3c:万维网联盟
- XML标签自定义,HTML标签预定义
- XML语法严格,HTML语法松散
- XML存储数据,HTML展示数据
5.4、语法
<?xml version='1.0' ?>
<users>
<user id='1'>
<name>zhangsan</name>
<age>18</age>
<gender>male</gender>
</user>
</users>
5.5、组成部分
- 文档声明
- 格式:<?xml 属性列表 ?>
- 属性列表:
- version:版本号(必须属性)
- encoding:编码方式(告知解析引擎当前文档使用的字符集,默认:ISO-8859-1)
- standalone:是否独立
- yes:不依赖其他文件
- no:依赖其他文件
- 指令
- <?xml-stylesheet type=“text/css” href=“a.css” ?>
- 结合CSS
- 标签
- 自定义标签名称
- 命名规则:
- 名称可以含字母、数字以及其他的字符
- 名称不能以数字或者标点符号开始
- 名称不能以字符 “xml”(或者 XML、Xml)开始
- 名称不能包含空格
- 属性
- id属性值唯一
- 文本
- CDATA区:该区域文本原样展示
- <![CDATA[…]]>
5.6、约束
规定xml文档的书写规则
-
分类:
-
DTD:一种简单的约束技术
- 引入dtd文档到xml文档中
- 内部dtd:将约束规则定义在xml文档中
<!DOCTYPE 根标签名 []>
- 外部dtd:将约束的规则定义在外部的dtd文件中
- 本地:<!DOCTYPE 根标签名 SYSTEM "dtd所在文件的位置">
- 网络:<!DOCTYPE 根标签名 PUBLIC "dtd文件名字" "dtd所在文件的位置URL">
- 内部dtd:将约束规则定义在xml文档中
- 引入dtd文档到xml文档中
-
Schema:一种复杂的约束技术
- 填写xml文档的根元素
- 引入xsi前缀. xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
- 引入xsd文件命名空间. xsi:schemaLocation="http://www.itcast.cn/xml student.xsd
- 为每一个xsd约束声明一个前缀,作为标识 xmlns=“http://www.itcast.cn/xml”
-
<students xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.itcast.cn/xml student.xsd"
xsi:schemaLocation="http://www.itcast.cn/xml">
5.7、解析
-
DOM:将标记语言文档一次性加载进内存,会生成一颗DOM数
- 优点:操作方便,对文档进行CRUD的所有操作
- 缺点:消耗内存
-
SAX:逐行读取,基于事件驱动的
- 优点:基本不占内存
- 缺点:只能读取,不能CRUD
-
解析器:
- JAXP:sum公司提供的解析器,支持dom和sax两种思想
- DOM4J:dom思想
- Jsoup:一款Java的HTML解析器
- PULL:Android操作系统内置的解析器,sax方式
Jsop:
- 导入jar包
-
获取Document对象
- 获取对象对应的Element对象
//2.1获取student.xml的path
String path = JsoupDemo1.class.getClassLoader().getResource("student.xml").getPath();
//2.2解析xml文档,加载文档进内存,获取dom树--->Document
Document document = Jsoup.parse(new File(path), "utf-8");
//3.获取元素对象 Element
Elements elements = document.getElementsByTag("name");
System.out.println(elements.size());
//3.1获取第一个name的Element对象
Element element = elements.get(0);
//3.2获取数据
String name = element.text();
System.out.println(name);
对象
- Jsoup:工具类,可以解析html或xml文档,返回Document
- parse(File in,String charsetName):解析html或xml文件
- parse(String html):解析html或xml字符串
- parse(URL url,int timeoutMillis):通过网络路径获取指定的html或xml的文档对象
- Document:文档对象,代表内存中的dom树,获取Element对象
- getElementById(String id):根据id属性获取唯一的element对象
- getElementsByTag(String tagName):根据标签名称获取元素对象集合
- getElementsByAttribu(String key):根据属性名称获取元素集合
- getElementsByAttribu(String key,String value):根据属性名称和属性值获取元素集合
- Elements:元素Element对象的集合,可以当作ArrayList来使用
- Element:元素对象
- 获取子元素对象
- getElementById(String id):根据id属性获取唯一的element对象
- getElementsByTag(String tagName):根据标签名称获取元素对象集合
- getElementsByAttribu(String key):根据属性名称获取元素集合
- getElementsByAttribu(String key,String value):根据属性名称和属性值获取元素集合
- 获取属性值
- attr(String key):根据属性名称获取属性值
- 获取文本值
- text():获取所有子标签纯文本内容
- html():获取标签体的所有内容(包括子标签和文本)
- 获取子元素对象
- Node:节点对象
5.8、快速查询方式
-
selector:选择器
-
Elements select (String cssQuery)
-
语法:参考selector定义语法
Elements elements = document.select(“name/#id”);
-
-
-
Xpath:XML路径语言,确定XML文档中某部分位置的语言
- 根据document对象创建JXDocument对象
- selN()
- 查询Xpath参考手册:https://www.w3school.com.cn/xpath/xpath_syntax.asp
6、Tomcat
6.1、启动
- bin/startup.bat
http://ip:端口号
- 一般将tomcat默认端口号修改为80,80为http协议默认端口号,访问时可以省略不写
6.2、关闭
- bin/shutdown.bat
- Ctrl+C
6.3、配置
-
部署项目方式:
-
直接将项目放在webapps
- 将项目打成war包,再将war包放置,war包自动解压缩
-
配置conf/server.xml文件
- 在<Host>标签体中配置
- <Context docBase=“项目路径” path=“虚拟路径” />
-
在conf\Catalina\localhost创建任意名称文件(热部署)
- 文件中编写
- <Context docBase=“项目路径”/>
- 虚拟目录就是文件的名称
- 文件中编写
-
6.4、 静态和动态项目
- 动态:项目根目录–>web-INF目录:
- web.xml:web项目的核心配置文件
- classes目录:放置字节码文件的目录
- lib目录:放置依赖的jar包
7、Servlet
7.1、概念
- 运行在服务器端的小程序
- Servlet就是一个接口,定义了Java类被浏览器访问(tomcat识别)的规则
- 将来定义一个类,实现Servlet接口,复写方法,tomcat可以识别
7.2、使用
-
创建JavaEE项目
-
定义实现类,实现Servlet接口
-
实现接口抽象方法
-
配置Servlet
- 在web.xml配置
<servlet>
<servlet-name>demo1</servlet-name>
<servlet-class>servlet.ServletImp(全类名)</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demo1</servlet-name>
<url-pattern>/demo1</url-pattern>
</servlet-mapping>
- 执行原理:
- 当服务器接收到客户端浏览器的请求后,会解析请求url路径,获取访问的Servlet的资源路径
- 查找web.xml文件,是否有对应的<url-pattern>的标签体内容
- 如果有,则在找到对应的<servlet-class>全类名
- tomcat会将字节码文件加载进内存,并且创建其对象
- 调用其方法
- void init(ServletConfig servletConfig):servlet创建时执行,只会执行一次
- void service(ServletRequest servletRequest, ServletResponse servletResponse):每一次servlet被访问时执行,执行多次
- void destroy():当servlet销毁,服务器正常关闭时执行,执行一次
- ServletConfig getServletConfig():获取ServletConfig 对象
- getServletInfo():获取Servlet信息
- 生命周期:
- 被创建:执行init方法,执行一次,说明只有一个对象,单例
- 多个用户同时访问,可能存在线程安全问题
- 解决:尽量不要在Servlet中定义成员变量,定义局部变量,即使定义了成员变量,也不要进行修改值
- 默认情况下,第一次被访问执行及被创建
- 可以指定Servlet的创建时机(Web.xml)
- 第一次访问创建:
<load-on-startup>负数(默认-1)</load-on-startup>
- 服务器启动创建
<load-on-startup>正数</load-on-startup>
- 第一次访问创建:
- 多个用户同时访问,可能存在线程安全问题
- 提供服务:执行service方法,执行多次
- 被销毁:执行destroy方法,执行一次
- 服务器非正常关闭时不会执行
- 被创建:执行init方法,执行一次,说明只有一个对象,单例
7.3、Servlet 3.0
-
支持注解配置,可以不需要web.xml
-
步骤:
- 创建JavaEE项目,选择Servlet,选择Servlet3.0以上版本,可以不创建web.xml
- 定义一个类,实现servlet接口
- 复写方法
- 在类上使用@WebServlet注解,进行配置
- @WebServlet(urlPattern="/demo")
- urlPattern可省略
- @WebServlet(urlPattern="/demo")
7.4、体系结构
- Servlet(接口)–>GenericServlet(抽象类)–>HttpServlet(抽象类)
- GenericServlet:将Servlet接口中其他的方法做了默认空实现,只讲service()方法作为实现
- 定义Servlet类时,可以继承GenericServlet,实现service()方法即可
- HttpServlet:对Http协议的一种封装,简化操作
- 定义类继承HttpServlet
- 重写doGet/doPost方法
7.5、相关配置
- 注解(一个servlet可以定义多个访问路径)
- @WebServlet({"/demo","/demo2"})
- 路径定义规则:
- /xxx
- /xxx/xxx:多层路径(目录结构)
- *.do(自定义拓展名)
8、HTTP
8.1、概念
- Hyper Text Transfer Protocal 超文本传输协议
- 传输协议:定义了客户端和服务器端通信时,发送数据的格式
8.2、特点
- 基于TCP/IP的高级协议
- 默认端口号:80
- 基于请求响应模型
- 无状态:每次请求之间相互独立,不能交互数据
8.3、请求消息
- 请求行
- 请求方式/请求url 请求协议/版本
- GET/login.html HTTP/1.1
- HTTP有7种请求方式
- GET:请求参数在请求行(在url后)显示,请求url长度有限制
- POST:请求参数在请求体中,请求url长度无限制
- 请求头
- 请求头名称:请求头值
- 常见请求头:
- User-Agent:浏览器告诉服务器,使用浏览器版本信息
- 可以解决浏览器兼容性问题
- Referer:告诉服务器,当前请求从哪里来(从哪个网站请求从哪里来)
- 防盗链
- 统计
- User-Agent:浏览器告诉服务器,使用浏览器版本信息
- 请求空行
- 空行
- 请求体(正文)
- username=张三
8.4、响应消息
- 响应行
- 协议/版本 响应状态码 状态码描述
- HTTP/1.1 200 OK
- 响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态(都是三位数字)
- 分类:
- 1XX:服务器接收客户端消息,但没有接收完成,等待一段时间后,发送1XX多状态码
- 2XX:成功
- 200:成功
- 3XX:重定向
- 302:重定向
- 重定向:
- 设置状态码为302:
response.setStatus(302);
- 设置响应头location:
response.setHeader(location,资源路径);
- 简单重定向方法:
response.sendRedirect(资源路径);
- 服务器访问客户端要加虚拟路径,客户端之间访问不用加,用request.getContextPath()获取
- 设置状态码为302:
- 特点:
- 地址栏发生变化
- 重定向可以访问其他站点的资源
- 是两次请求
- 重定向:
- 304:访问缓存
- 302:重定向
- 4XX:客户端错误
- 404:请求路径没有对应的资源
- 405:请求方式没有对应的doXXX方法
- 5XX:服务器端错误
- 500:服务器内部出现异常
- 分类:
- 响应头
- 头名称:值
- 常见响应头:
- Content-Type:服务器告诉客户端本次响应体数据格式和编码格式
- Content-disposition:服务器告诉客户端以什么格式打开响应体数据
- in-line:默认值,在当前页面打开
- attachment;filename=xxx:以附件形式打开响应体,文件下载
- 响应空行
- 响应体
- 传输的数据
9、Request
9.1、request原理
- request和response对象都是由服务器创建的
- 一个是获取请求信息,一个是设置响应消息
9.2、request对象继承
- ServletRequest(接口)
- ----继承---->HttpServletRequest(接口)-
- —实现---->org.apache.catalina.connector.RequestFacade类(tomcat)
- ----继承---->HttpServletRequest(接口)-
9.3、request方法
- 获取请求消息数据
- 获取请求行数据
- 获取请求方式:
getMethod()
- 获取虚拟目录:
getContextPath()
- 获取Servlet路径:
getServletPath()
- 获取Get方式请求参数:
getQueryString()
- 获取请求URI:
getRequestURI()
- 获取请求URL:
getRequestURL()
- 获取协议和版本:
getProtocol()
- 获取客户机的IP地址:
getRemoteAddr()
- 获取请求方式:
- 获取请求头数据
- 通过请求头的名称获取请求值:
getHeader(String name)
- 获取所有的请求头名称:
Enumeration<String> getHeaderNames()
- 通过请求头的名称获取请求值:
- 获取请求体数据
- 请求体:只有POST请求方式,才有请求体,在请求体中封装POST请求参数
- 步骤:
- 获取流对象
- 获取字符输入流,只能操作字符数据:
BufferedReader getreader()
- 获取字节输入流,可以操作所有类型数据:
ServletInputStream getInputStream()
- 在文件上传中
- 获取字符输入流,只能操作字符数据:
- 从流对象中拿数据
- 获取流对象
- 获取请求行数据
- 其他功能
-
获取请求参数通用方式:
- 根据参数名称获取参数值:
String getParamter(String name)
- 根据参数名称获取参数值数组:
String[] getValues(String name)
- 根据所有请求参数名称:
Enumeration<String> getParamterNames()
- 获取所有参数的Map集合:
Map<String,String[]> getParamterMap()
中文乱码:
- get方式:tomcat8已解决
- post方式:在获取参数前,设置流的字符集:
request.setCharacterEncoding("utf-8");
- 根据参数名称获取参数值:
-
请求转发:
- 一种在服务器内部的资源跳转方式
- 通过reques对象获取请求转发器对象:
RequestDispatcher getRequestDispatcher(String path)
- 使用RequestDispatcher对象来进行转发:
forward(ServletRequest request,ServletResponse response)
- 通过reques对象获取请求转发器对象:
- 特点:
- 浏览器地址栏路径没有发生变化
- 只能转发到当前服务器内部资源中
- 转发是一次请求
- 一种在服务器内部的资源跳转方式
-
共享数据:
- 域对象:一个有作用范围的对象,可以在范围内共享数据
- request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
- 方法:
- 存储数据:
void setAttribute(String name,Object obj)
- 通过键获取值:
Object getAttribute(String name)
- 通过键移除键值对:
void removeAttribute(String name)
- 存储数据:
-
获取ServletContext:
ServletContext getServletContext()
this.getServletContext()
- 概念:代表整个web应用,可以和程序的容器(服务器)来通讯
- 作用:
- 获取MIME类型:在互联网通讯过程中定义的一种文件数据类型
- 格式:大类型/小类型 text/html image/jpeg
- 方法:
String getMimeType(String file)
- 域对象:共享数据
- 对象范围:共享所有用户的数据,不同客户端都可以获取到同一个属性值
- 获取文件真实(服务器)路径
- 方法:
String getRealPath(String path)
- 方法:
- 获取MIME类型:在互联网通讯过程中定义的一种文件数据类型
-
10、Response
10.1、response原理
- request和response对象都是由服务器创建的
- 一个是获取请求信息,一个是设置响应消息
10.2、response对象继承
- ServletRequest(接口)
- ----继承---->HttpServletRequest(接口)-
- —实现---->org.apache.catalina.connector.RequestFacade类(tomcat)
- ----继承---->HttpServletRequest(接口)-
10.3、response方法
-
设置响应行:
- 设置状态码:
setStatus(int sc)
- 设置状态码:
-
设置响应头:
setHeader(String name,String value)
-
设置响应体:
-
获取输出流
- 字符输出流:
PrintWriter getWriter()
- 字节输出流:
ServletOutputStream getOutputStream()
- 字符输出流:
-
使用输出流将数据输出到客户端浏览器
-
write()
-
中文乱码:编解码字符集不一致
-
(可以不写)获取流之前设置默认编码为GBK:
response.setCharacterEncoding("GBK")
-
告诉浏览器,服务器发送的消息体编码,建议浏览器使用此编码:
response.setHeader("content-type","text/html;charset=utf-8")
response.setContentType("text/html;charset=utf-8")
-
-
-
11、BeanUtils
- 用于封装JavaBean的
- JavaBean:标准的Java类
- 要求
- 类必须被public修饰
- 必须提供空参的构造器
- 成员变量必须使用private修饰
- 提供公共setter和getter方法
- 要求
- 功能:封装数据
- 成员变量
- 属性:setter和getter方法(截取后的产物)
- getUsername() --> Username() 属性名–> username 属性值
- 方法:
- 设置属性值:
setProperty(对象,属性名,属性值)
- 获取属性值:
getProperty(对象,属性名)
- 封装对象:
populate(对象,Map集合)
- 将map集合中的键值对信息,封装到JavaBean对象中,键为属性名称,值为属性值
- 设置属性值:
12、会话技术
12.1、概念
- 一次会话中包含多次请求和响应
- 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到一方断开为止
12.2、功能
- 在一次会话的范围内的多次请求间,共享数据
12.3、Cookie
- 客户端会话技术:
- 概念:将数据保存在客户端
- 使用步骤:
- 创建Cookie对象,绑定数据:
new Cookie(String name,String value)
- 发送Cookie对象:
reponse.addCookie(Cookie cookie)
- 获取Cookie,拿到数据:
request.getCookies();//返回cookie数组
- 创建Cookie对象,绑定数据:
- 实现原理:
- 基于响应头set-cookie和请求头cookie来实现
- 注意事项:
- 默认情况下,当浏览器关闭后,cookie被清除
- 可以设置cookie的生命周期,持久化存储:
setMaxAge(int seconds)
- 正数:将Cookie数据写入硬盘文件中,Cookie存活时间
- 负数:默认值
- 零:删除Cookie信息
- 可以设置cookie的生命周期,持久化存储:
- 在Tomcat8之前,Cookie不能直接存储中文数据(需要采用URL编码),之后,支持中文数据
- Cookie的获取范围:默认情况下同一个Tomcat服务器多个web服务器下不能共享Cookie
- 可以设置Cookie的获取范围(默认范围当前虚拟目录):
setPath(String path)
- 如果要共享,可以将path设置为"/",代表项目根路径
- 不同Tomcat服务器共享
setDomain(String path)
:如果设置一级域名相同,那么多个服务器之间cookie即可共享setDomain(".baidu.com")
:那么tieba.baidu.com和news.baidu.com中国Cookie可以共享
- 可以设置Cookie的获取范围(默认范围当前虚拟目录):
- 存储在客户端浏览器,对于单个cookie的大小不能超过4kb,同一个域名下总数目不能超过20个
- 默认情况下,当浏览器关闭后,cookie被清除
12.4、Session
- 服务器会话技术:
- 概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中,HTTPSession
- 方法:
- 获取session对象:
HttpSession session = request.getSession();
- 使用session对象:
Object getAttribute(String name)
:通过名字获取session值void setAttribute(String name, Object value)
:设置session键值void removeAttribute(String name)
:去掉指定session
- 获取session对象:
- 原理:session的实现是依赖于cookie的
- 特点:
- 用于存储一次会话的多次请求数据,存在服务器端
- 可以存储任意类型,任意大小数据
- 注意事项:
- 默认情况下,关闭客户端,清空session
- 长久保存:
Cookie cookie = new Cookie("JSESSIONNID",session.getId());
- 长久保存:
- 服务器关闭,两次获取的session对象不是同一个
- 要确保数据不丢失
- session的钝化:
- 在服务器正常关闭之前,将session对象系列化到硬盘上
- session的活化:
- 在服务器启动后,将session文件转化为内存中的session对象即可
- session的钝化:
- 正常关闭数据库,tomcat自动钝化活化
- 要确保数据不丢失
- session销毁时间
- 服务器关闭
- session对象调用
invalidate()
方法自杀 - 默认失效时间,30分钟,在tomcat,web-xml,session-config配置
- 默认情况下,关闭客户端,清空session
13、JSP
13.1、概念
- Java Server Pages:Java服务器端页面,简化书写
13.2、原理
- 本质上是一个Servlet
13.3、脚本
- JSP定义Java代码的方式
<% java代码 %>
:在service方法中可以定义什么,该脚本中就可以定义什么<%! java代码 %>
:在jsp转换后的Java类中,变成定义成员变量和成员方法<%= java代码 %>
:将java代码输出到页面上
13.4、指令
- 作用:用于配置JSP页面,导入资源文件
- 格式:
<%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ...%>
- 分类:
- page:配置JSP页面
- contentType:等同于response.setContentType()
- 设置响应体的mime类型以及字符集
- 设置当前JSP页面编码(ide自动,等效于使用
pageEncoding=""
)
- errorPage:当前页面发生异常后,会自动跳转到指定的错误页面
- isErrorPage:表示当前页面是否是错误页面
- 标注了以后就可以用exception内置对象
- contentType:等同于response.setContentType()
- taglib:导入资源(标签库)
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jst1/core"%>
- prefix前缀,可以自定义
- include:可以引用其他页面写好的资源文件
<%@include file ="top.jsp"%>
- page:配置JSP页面
13.5、注释
- html注释:
- <!-- -->:只能注释html代码片段
- jsp注释:
- <%-- --%>:可以注释所有
13.6、内置对象
- 在jsp页面中,不需要获取或创建,可以直接使用,9个内置对象
- request
- reponse
- out:可以将数据输出到页面上,字符输出流对象,和response.getWriter( )类似
- 区别:
- 后于response.getWriter( )输出
- 区别:
14、MVC开发模式
14.1、概念
- Model(模型) View(视图) Controller(控制器)
- 模型:业务逻辑操作(JavaBean)
- 视图:展示数据(JSP)
- 控制器(Servlet):
- 获取客户端输入
- 调用模型获得数据
- 将数据交给视图展示
14.2、优点
- 耦合性低,方便维护,利于分工协作
- 重用性高
14.3、缺点
- 使得项目架构变得复杂,对开发人员要求高
15、EL表达式
15.1、概念
- Expression Language 表达式语言
15.2、作用
- 替换和简化jsp页面中Java代码的编写
15.3、语法
${表达式}
15.4、注意事项
- Jsp默认支持EL表达式
- 忽略EL表达式
- page属性:
isELIgnore="true"
- page属性:
15.5、使用
-
运算符
- 算术运算符:
+ - * /(div) %(mod)
- 比较运算符:
> < >= <= == !=
- 逻辑运算符:
&&(and) ||(or) !(not)
- 空运算符:
empty
- 用用于判断字符串,集合,数组对象是否为null并且长度是否为0
- not empty
- 算术运算符:
-
获取值
- el表达式只能从域对象中获取值
- 从指定域中获取指定键的值:
${域名称.键名}
- 域名称:
- pageScope–>pageContext
- requestScope–>request
- sessionScope–>session
- applicationScope–>application(ServletContext)
- 没有获取到值不显示
- 依次从最小域中查找是否有该键对应的值,找到停止:
${键名}
- 域名称:
- 获取对象中对应的值
- 通过对象属性来获取
- setter或getter方法,去掉set或get再将剩余部分首字母变小写
- 获取List集合中的值:
${域名称.键名[索引]}
- 获取Map集合中的值:
${域名称.键名.key}
${域名称.键名[key]}
-
隐式对象
- pageContext:
- 获取jsp其他8个内置对象
- 动态获取虚拟目录:
pageContext.request.ContextPath
- pageContext:
16、JSTL
16.1、概念
- JavaServer Pages Tag Library JSP标准标签库
16.2、作用
- 用于简化和替换jsp页面上的代码
16.3、使用
- 导入jstl相关jar包
- 引用标签库:taglib指令
- 使用标签
16.4、常用标签
- if:if,一般与el表达式连用
- choose—when—otherwise:switch—case—default
- foreach:for
- 完成重复操作
- begin
- end
- var
- step
- varStatus:循环状态对象
- index:i的值
- count:循环次数
- 遍历容器
- items:容器对象
- var:容器中元素临时变量
- varStatus:循环状态对象
- index:i的值
- count:循环次数
- 完成重复操作
17、三层架构
- 软件设计架构
- 界面层(表示层):用户看的界面,可以通过界面上的组件和服务器进行交互–web
- 业务逻辑层:处理业务逻辑–service
- 数据访问层:操作数据存储文件–dao(data access object)
18、Filter
18.1、概念
- 当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能
- 作用:
- 一般用于完成通用的操作,如:登陆验证,统一编码处理,敏感字符过滤…
18.2、使用
- 定义一个类,实现Filter接口
- 复写方法
- 配置拦截路径
- web.xml
<filter>
<filter-name>过滤器名</filter-name>
<filter-class>全类名</filter-class>
</filter>
<filter-mapping>
<filter-name>过滤器名</filter-name>
<!-- 拦截路径 -->
<url-pattern>拦截路径</url-pattern>
</filter-mapping>
- 注解:
@WebFilter("/*")//在访问所有资源之前,执行该过滤器
18.3、注意事项
- 过滤器执行流程
- 先执行过滤器
- 执行放行后资源
- 回来继续执行放行后的代码
- 过滤器生命周期方法
- init():在服务器启动后,创建Filter对象,调用init方法,只执行一次,用于加载资源
- doFilter():每一次请求被拦截资源后,会执行,执行多次
- destroy():在服务器关闭后,Fiterr对象被销毁,如果服务器正常关闭,执行该方法,只执行一次,用于释放资源
- 过滤器配置
- 拦截路径:
- 具体资源路径:
/index.jsp
- 目录拦截:
/user/*
,访问/user下所有资源,过滤器都会被执行 - 后缀名拦截:
*.jsp
- 拦截所有资源:
/*
- 具体资源路径:
- 拦截方式:资源被访问的方式
- 注解:设置DispatcherTypes属性
- REQUEST:默认值,浏览器直接请求资源
- FORWARD:转发访问资源
- INCLUDE:包含访问资源
- ERROR:错误跳转资源
- ASYNC:异步访问资源
- web.xml:
- 设置标签
- 注解:设置DispatcherTypes属性
- 拦截路径:
- 过滤器链(配置多个过滤器)
- 执行顺序:如果有两个过滤器a和b a–>b–>资源执行–>b–>a
- 先后顺序:
- 注解:按照类名的字符串比较规则比较,字小先执行
- web.xml:谁定义在上边,谁先执行
19、Listener
19.1、概念
- web的三大组件之一。
- 事件监听机制
- 事件 :一件事情
- 事件源 :事件发生的地方
- 监听器 :一个对象
- 注册监听:将事件、事件源、监听器绑定在一起。 当事件源上发生某个事件后,执行监听器代码
19.2、方法
- void contextDestroyed(ServletContextEvent sce) :ServletContext对象被销毁之前会调用该方法
- void contextInitialized(ServletContextEvent sce) :ServletContext对象创建后会调用该方法
- 加载资源文件
19.3、使用
-
定义一个类,实现ServletContextListener接口
-
复写方法
-
配置
- web.xml
<listener>
<listener-class>全类名</listener-class>
</listener>
-
指定初始化参数<context-param>
-
注解:
- @WebListener
20、JQuery
20.1、概念
- JavaScript框架,封装JS原生代码
20.2、使用
- $(选择器)
20.3、对象
- JQuery和JavaScript获取对象的区别和转换
- Jquery对象在操作时更加方便
- Jquery和JS对象方法不适用
- 两者相互转换:
- jq --> js : jq对象[索引] / jq对象.get(索引)
- js --> jq: $(js对象)
20.4、选择器
- 基本选择器
- 标签选择器
- $(“html标签名”) 获得所有匹配标签名称的元素
- id选择器
- $("#id的属性值") 获得与指定id属性值匹配的元素
- 类选择器
- $(".class的属性值") 获得与指定的class属性值匹配的元素
- 并集选择器
- $(“选择器1,选择器2…”) 获取多个选择器选中的所有元素
- 标签选择器
- 层级选择器
- 后代选择器
- 语法: $("A B ") 选择A元素内部的所有B元素
- 子选择器
- 语法: $(“A > B”) 选择A元素内部的所有B子元素
- 后代选择器
- 属性选择器
- 属性名称选择器
- 语法: $(“标签名[属性名]”) 包含指定属性的选择器
- 属性选择器
- 语法: $(“标签名[属性名=‘值’]”) 包含指定属性等于指定值的选择器
- = != ^=(开始) $=(结束) *=(包含)
- 语法: $(“标签名[属性名=‘值’]”) 包含指定属性等于指定值的选择器
- 复合属性选择器
- 语法: $(“标签名[属性名=‘值’] [XX ]…”) 包含多个属性条件的选择器
- 属性名称选择器
- 过滤选择器
- 首元素选择器
- 语法::first 获得选择的元素中的第一个元素
- 尾元素选择器
- 语法::last 获得选择的元素中的最后一个元素
- 非元素选择器
- 语法::not(选择器) 不包括指定内容的元素
- 偶数选择器
- 语法::even 偶数,从 0 开始计数
- 奇数选择器
- 语法::odd 奇数,从 0 开始计数
- 等于索引选择器
- 语法::eq(index) 指定索引元素
- 大于索引选择器
- 语法::gt(index) 大于指定索引元素
- 小于索引选择器
- 语法::lt(index) 小于指定索引元素
- 标题选择器
- 语法::header 获得标题(h1~h6)元素,固定写法
- 首元素选择器
- 表单过滤选择器
- 可用元素选择器
- 语法::enabled 获得可用元素
- 不可用元素选择器
- 语法::disabled 获得不可用元素
- 选中选择器
- 语法::checked 获得单选/复选框选中的元素
- 语法::selected 获得下拉框选中的元素
- 可用元素选择器
20.5、DOM
- 内容
- html():设置/获取元素的标签体内容
- text():设置/获取元素的标签体纯文本内容
- val():设置/获取元素的value属性值
- 属性
- 通用属性操作
- attr():设置/获取元素的属性
- removeAttr():删除属性
- prop():设置/获取元素的属性
- removeProp():删除属性
- attr和prop区别:
- 操作元素固有属性:建议prop
- 操作元素自定义属性:建议attr,但是selected和checked获取不到
- 对class属性操作
- addClass():添加class属性值
- removeClass():删除class属性
- toggleClass():切换class属性
- 存在即删除,不存在即删除
- 通用属性操作
- CRUD操作
- append()
- A.append(B):将B添加到A内部末尾
- prepend()
- A.prepend(B):将B添加到A内部开头
- appendTo()
- A.appendTo(B):将A添加到B内部末尾
- prependTo()
- A.prependTo(B):将A添加到B内部开头
- after()
- A.after(B):将B添加到A后面,兄弟关系
- before()
- A.before(B):将B添加到A前面,兄弟关系
- insertAfter()
- A.insertAfter(B):将A添加到B后面,兄弟关系
- insertBefore()
- A.insertBefore(B):将A添加到B前面,兄弟关系
- remove()
- A.remove():将对象删除
- empty()
- A.empty():清空元素的所有后代元素,但是保留当前元素对象和属性节点
- clone()
- A.clone():复制一个A返回
- append()
20.6、动画
- 默认显示和隐藏方式
- show([speed,[easing],[fn]])
- speed:动画的速度。三个预定义的值(“slow”,“normal”, “fast”)或表示动画时长的毫秒数值(如:1000)
- easing:用来指定切换效果,默认是"swing",可用参数"linear"
- swing:动画执行时效果是 先慢,中间快,最后又慢
- linear:动画执行时速度是匀速的
- fn:在动画完成时执行的函数,每个元素执行一次。
- hide([speed,[easing],[fn]])
- toggle([speed],[easing],[fn]):切换状态
- show([speed,[easing],[fn]])
- 滑动显示和隐藏方式
- slideDown([speed],[easing],[fn])
- slideUp([speed,[easing],[fn]])
- slideToggle([speed],[easing],[fn])
- 淡入淡出显示和隐藏方式
- fadeIn([speed],[easing],[fn])
- fadeOut([speed],[easing],[fn])
- fadeToggle([speed,[easing],[fn]])
20.7、遍历
- jq对象.each(callback)
- jQuery / $.each(object,[callback])
- for(… of…):jquery3.0版本后
20.8、事件绑定
- 标准绑定:jq对象.事件方法(回调函数)
- on绑定事件/off解除绑定
- jq对象.on(“事件名称”,回调函数)
- jq对象.off(“事件名称”)
- 事件切换
- jq对象.toggle(fn1,fn2…) jquery1.9版本弃用,使用插件后可用
20.9、插件
-
增强JQuery功能
-
$.fn.extend(object)
-
增强通过JQuery获取的对象的功能 $("#id")
-
$.fn.extend({
//定义一个check方法,所以jq对象都可以调用该方法
check:function (){
//…
}, …
});
-
-
$.extend(object)
- 增强JQuery对象自身的功能 $/jQuery
-
21、AJAX
21.1、概念
- Asynchronous JavaScript And XML :异步的 JavaScript 和 XML
- 异步和同步
- 客户端和服务器相互通讯的基础上
21.2、实现方式
- 原生JS
//发送异步请求
//1.创建核心对象
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
//2.建立连接
//请求方式-请求url-同步(false)或异步请求(true)
xmlhttp.open("GET","test1.txt",true);
//3.发送请求,post请求参数需要在send方法中添加
xmlhttp.send();
//4.接收并处理来自服务器的响应结果 xmlhttp.responseText;
//当服务器响应成功时获取
//当xmlhttp对象的就绪状态改变时,触发事件
xmlhttp.onreadystatechange=function()
{
//判断就绪状态是否为4,响应状态码是否为200
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
//获取服务器响应结果
var responseText = xmlhttp.responseText;
}
}
- JQuery
- $.ajax()
- $.ajax({键值对});
- url:请求路径
- type:get(默认)/post
- data:“username=jack&age=23” / {“username”:“jack”,“age”:“23”}
- success:function(){//响应成功后的回调函数}
- error:function(){//响应出错后的回调函数}
- dataType:接收到响应数据的格式
- $.ajax({键值对});
- $.get()
- $.get(url , [data] , [callback] , [type])
- $.post()
- $.post(url , [data] , [callback] , [type])
- $.ajax()
22、JSON
22.1、概念
-
JavaScript Object Notation JavaScript对象表示法
-
存储数据和交换信息的语法,数据的传输,比xml更小,更快,更易解析
22.2、语法
- 键的引号可以省略不写
- 值的取值类型:数字,“字符串”,逻辑值(true,false),数组[ ],json对象{ },null
- 花括号保存对象
- 方括号保存数组
22.3、获取数据
- json对象.键名
- json对象[“键名”]
- 数组对象[索引]
- 注意事项
- 客户端获取到的服务器发送的 json 数据默认为字符串,不能直接解析
- 在AJAX请求中设置收到响应数据类型 type 的值为"json"
- 在服务器设置响应的数据类型为json,客户端不写type也会自动识别
- response.setContentType(“application/json;charset=utf-8”)
- 客户端获取到的服务器发送的 json 数据默认为字符串,不能直接解析
22.4、遍历
- for key in person
- 此处获得到的key是字符串格式,不能使用 person.key 获取值
- 使用 person[key] 来获取值
22.5、解析器
-
常见解析器:Jsonlib, Gson, fastjson, jackson
-
注解(加在类成员定义上):
- @JsonIgnore:忽略该属性
- @JsonFormat:属性值格式化
- @JsonFormat(pattern = “xxx”)
-
JSON 和 Java 对象的转换
- Java 对象 ----> JSON
- 导入jackson相关jar包
- 创建jackson核心对象 ObjectMapper
- 调用 ObjectMapper 相关方法进行转换
- writeValue(参数1,obj):
- File:将obj对象转换为Json字符串,并保存到指定的文件中
- Writer:将obj对象转换为Json字符串,并填充到字符输出流中
- OutputStream:将obj对象转换为Json字符串,并填充到字节输出流中
- writeValueAsString(obj):将对象转换为 Json 字符串
- writeValue(参数1,obj):
- JSON ----> Java 对象
- 导入jackson相关jar包
- 创建jackson核心对象 ObjectMapper
- 调用 ObjectMapper 相关方法进行转换
- readValue( Json字符串数据 , class)
- Map / List ----> JSON
- Java 对象 ----> JSON
23、Redis
23.1、概念
- 一款高性能的NOSQL系列的非关系型数据库
- 关系型:
- 数据之间有关联关系
- 数据存储在硬盘的文件上
- 非关系型:
- 数据之间没有关联关系
- 数据存储在内存中
- 关系型:
23.2、下载安装
- 解压直接可用
- redis.windows.conf:配置文件
- redis-cli.exe:redis的客户端
- redis-server.exe:redis的服务器端
23.3、使用操作
-
https://www.redis.net.cn/tutorial/3501.html
-
redis数据结构
- 存储 key – value 格式的数据,key都为字符串,value有五种不同的数据结构
- 字符串 String,哈希类型 hash,列表类型 list,集合类型 set,有序集合类型 sortedset
- 存储 key – value 格式的数据,key都为字符串,value有五种不同的数据结构
-
命令操作
- String:
set key value
get key
del key
- hash:
hset key field
hget key field
hgetall key
del key field
- list:
lpush key value
rpush key value
lrange key start end(获取所有0到-1)
lpop key
rpop key
- set:
sadd key value
smebers key
srem key value
- sortedset:
zadd key score value
zrange key start end (withscores)
zrem key value
- 通用命令
keys *
:查询所有的键type key
:获取键所对应的类型del key
:删除指定的key
- String:
-
Java客户端操作
23.4、持久化操作
-
将redis内存中数据持久化保存在硬盘文件中
-
持久化机制
-
RDB:默认方式,在一定的间隔时间中,检测key的变化情况,然后持久化数据
- 编辑 redis.windows.conf 文件
- save 900 1 # after 900 sec (15 min) if at least 1 key changed
save 300 10 # after 300 sec (5 min) if at least 10 keys changed
save 60 10000 # after 60 sec if at least 10000 keys changed - 重新启动redis,并指定配置文件名称:
redis-server.exe redis.windows.conf
-
AOF:日志记录的方式,可以记录每一条命令的操作,每一次命令操作后,持久化数据
- 编辑redis.windwos.conf文件
-
-
appendonly no(关闭aof) --> appendonly yes (开启aof)
# appendfsync always : 每一次操作都进行持久化
appendfsync everysec : 每隔一秒进行一次持久化
# appendfsync no : 不进行持久化
- 重新启动redis,并指定配置文件名称:
redis-server.exe redis.windows.conf
24、Jedis
24.1、概念
- java操作redis数据库的工具
24.2、使用
- 获取连接:
Jedis jedis = new Jedis("localhost",6379)//不传参数默认localhost和6379端口
- 操作:
命令操作
- setex(key,second,value):可以存储指定过期时间的key value
- 关闭连接:
jedis.close()
24.3、JedisPool
- 创建JedisPool连接池对象
- 创建对象传入参数(配置对象,主机名,端口号)
- JedisPoolConfig:配置对象,set方法设置配置对象的属性
- 调用方法 getResourse()方法获取Jedis连接
- 将Jedis归还到连接池中,close方法
24.4、JedisPoolUtils
package showMessage.util;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* @author jy
* @date 2021年04月16日 10:31
* JedisPool工具类
* 加载配置文件,配置获取连接池的参数
* 提供获取连接的方法
*/
public class JedisPoolUtils {
//静态变量JedisPool
private static JedisPool jedisPool;
//加载配置文件
static {
//读取配置文件
InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
//创建Properties对象
Properties pro = new Properties();
//关联文件
try {
pro.load(is);
} catch (IOException e) {
e.printStackTrace();
}
//获取数据,设置到JedisPoolConfig中
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal")));
config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle")));
//初始化JedisPool
jedisPool = new JedisPool(config,pro.getProperty("host"),Integer.parseInt(pro.getProperty("port")));
}
/**
* 获取连接方法
* @return
*/
public static Jedis getJedis(){
return jedisPool.getResource();
}
}
25、Maven
25.1、概念
- Maven 是一个项目管理工具,它包含了一个项目对象模型 (POM: Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。
- 能帮你构建工程,管理 jar包,编译代码,还能帮你自动运行单元测试,打包,生成报表,甚至能帮你部署项目,生成 Web 站点
25.2、配置
- 添加系统变量:MAVEN_HOME,对应安装路径
- 编辑Path变量:加入 %MAVEN_HOME%\bin
- 验证配置成功:控制台输入mvn -v
25.3、仓库
- 本地仓库
- 重新指定本地仓库路径
- /path/to/local/repo
- 重新指定本地仓库路径
- 远程仓库(私服)
- 中央仓库
25.4、目录结构
- 核心代码部分:
src/main/java
- 配置文件部分:
src/main/resources
- 测试代码部分:
src/test/java
- 测试配置文件部分:
src/test/resources
- 页面资源(js,css,图片…):
src/main/webapp
25.5、常用命令
- mvn clean:删除掉已经编译的class文件,删掉target目录
- mvn compile:编译main目录下java文件生成class文件
- mvn test:编译test和main目录下java文件生成class文件
- mvn package:打成war包并编译test和main目录下java文件生成class文件
- mvn install :打成war包并安装到本地仓库,并编译test和main目录下java文件生成class文件
25.6、生命周期
- 默认生命周期
- 编译 ----> 测试 ----> 打包 ----> 安装 ----> 发布
- compile ----> test ----> package ----> install ----> deploy
- 每一条命令都对应了maven底层一个插件
- 清理生命周期
- 清除项目编译信息:clean
- 站点生命周期
25.7、概念模型
-
项目对象模型
- 项目自身信息
- 项目运行所依赖的jar包
- 项目运行环境信息,jdk,tomcat等信息
-
依赖管理模型(jar包)
- 公司组织名称
- 项目名
- 版本号
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
25.8、IDE集成插件
-
setting搜索maven设置maven安装目录
-
runner添加VM Options:-DarchetypeCatalog=internal
- 确保在不联网情况下,使用骨架创建的工程,只要之前下载过插件,就可以使用本地插件
-
使用骨架创建工程
- new project ----> maven ----> create from archetype ----> org.apache.maven.archetypes:maven-archetype-quickstart
-
使用骨架创建web工程
- new project ----> maven ----> create from archetype ----> org.apache.maven.archetypes:maven-archetype-webapp
-
不使用骨架创建工程
所对应的类型del key
:删除指定的key
-
Java客户端操作
23.4、持久化操作
-
将redis内存中数据持久化保存在硬盘文件中
-
持久化机制
-
RDB:默认方式,在一定的间隔时间中,检测key的变化情况,然后持久化数据
- 编辑 redis.windows.conf 文件
- save 900 1 # after 900 sec (15 min) if at least 1 key changed
save 300 10 # after 300 sec (5 min) if at least 10 keys changed
save 60 10000 # after 60 sec if at least 10000 keys changed - 重新启动redis,并指定配置文件名称:
redis-server.exe redis.windows.conf
-
AOF:日志记录的方式,可以记录每一条命令的操作,每一次命令操作后,持久化数据
- 编辑redis.windwos.conf文件
-
-
appendonly no(关闭aof) --> appendonly yes (开启aof)
# appendfsync always : 每一次操作都进行持久化
appendfsync everysec : 每隔一秒进行一次持久化
# appendfsync no : 不进行持久化
- 重新启动redis,并指定配置文件名称:
redis-server.exe redis.windows.conf
24、Jedis
24.1、概念
- java操作redis数据库的工具
24.2、使用
- 获取连接:
Jedis jedis = new Jedis("localhost",6379)//不传参数默认localhost和6379端口
- 操作:
命令操作
- setex(key,second,value):可以存储指定过期时间的key value
- 关闭连接:
jedis.close()
24.3、JedisPool
- 创建JedisPool连接池对象
- 创建对象传入参数(配置对象,主机名,端口号)
- JedisPoolConfig:配置对象,set方法设置配置对象的属性
- 调用方法 getResourse()方法获取Jedis连接
- 将Jedis归还到连接池中,close方法
24.4、JedisPoolUtils
package showMessage.util;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* @author jy
* @date 2021年04月16日 10:31
* JedisPool工具类
* 加载配置文件,配置获取连接池的参数
* 提供获取连接的方法
*/
public class JedisPoolUtils {
//静态变量JedisPool
private static JedisPool jedisPool;
//加载配置文件
static {
//读取配置文件
InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
//创建Properties对象
Properties pro = new Properties();
//关联文件
try {
pro.load(is);
} catch (IOException e) {
e.printStackTrace();
}
//获取数据,设置到JedisPoolConfig中
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal")));
config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle")));
//初始化JedisPool
jedisPool = new JedisPool(config,pro.getProperty("host"),Integer.parseInt(pro.getProperty("port")));
}
/**
* 获取连接方法
* @return
*/
public static Jedis getJedis(){
return jedisPool.getResource();
}
}
25、Maven
25.1、概念
- Maven 是一个项目管理工具,它包含了一个项目对象模型 (POM: Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。
- 能帮你构建工程,管理 jar包,编译代码,还能帮你自动运行单元测试,打包,生成报表,甚至能帮你部署项目,生成 Web 站点
25.2、配置
- 添加系统变量:MAVEN_HOME,对应安装路径
- 编辑Path变量:加入 %MAVEN_HOME%\bin
- 验证配置成功:控制台输入mvn -v
25.3、仓库
- 本地仓库
- 重新指定本地仓库路径
- /path/to/local/repo
- 重新指定本地仓库路径
- 远程仓库(私服)
- 中央仓库
25.4、目录结构
- 核心代码部分:
src/main/java
- 配置文件部分:
src/main/resources
- 测试代码部分:
src/test/java
- 测试配置文件部分:
src/test/resources
- 页面资源(js,css,图片…):
src/main/webapp
25.5、常用命令
- mvn clean:删除掉已经编译的class文件,删掉target目录
- mvn compile:编译main目录下java文件生成class文件
- mvn test:编译test和main目录下java文件生成class文件
- mvn package:打成war包并编译test和main目录下java文件生成class文件
- mvn install :打成war包并安装到本地仓库,并编译test和main目录下java文件生成class文件
25.6、生命周期
- 默认生命周期
- 编译 ----> 测试 ----> 打包 ----> 安装 ----> 发布
- compile ----> test ----> package ----> install ----> deploy
- 每一条命令都对应了maven底层一个插件
- 清理生命周期
- 清除项目编译信息:clean
- 站点生命周期
25.7、概念模型
[外链图片转存中…(img-2eyxUXRh-1622693535794)]
-
项目对象模型
- 项目自身信息
- 项目运行所依赖的jar包
- 项目运行环境信息,jdk,tomcat等信息
-
依赖管理模型(jar包)
- 公司组织名称
- 项目名
- 版本号
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
25.8、IDE集成插件
-
setting搜索maven设置maven安装目录
-
runner添加VM Options:-DarchetypeCatalog=internal
- 确保在不联网情况下,使用骨架创建的工程,只要之前下载过插件,就可以使用本地插件
-
使用骨架创建工程
- new project ----> maven ----> create from archetype ----> org.apache.maven.archetypes:maven-archetype-quickstart
-
使用骨架创建web工程
- new project ----> maven ----> create from archetype ----> org.apache.maven.archetypes:maven-archetype-webapp
-
不使用骨架创建工程
- new project ----> maven