你要的Java基础笔记在这里

 

 

java基础

目录

java基础

类的关系之继承

类和类的关系

修饰符

Static静态修饰符

设计模式

抽象类与接口

接口

匿名内部类

枚举(类)

包装类

Math  Random类

Date类

字符串相关

StringBuffer and StringBulider

Regular Expression正则表达式

集合都在java.util包里面

ArrayList

Vector

LinkedList

HashSet

TreeSet

Map

异常

I/O流

File

字节型文件输入流

字符流

缓冲流

线程

生产者消费者问题

java.util包  Timer类

究极版单例模式

反射(reflect)

操作方法

注解

GUI(窗体,菜单,面板组件)

第一阶段

数据库

MySQL

JDBC

协议

Servlet

初识Tomcat

如何使用Tomcat

EL

JSTL

自定义jsp标签

文件上传与下载

HttpFilter

Listener监听器对象

Xml

Web注解


 

 

类的关系之继承

方法重写override                                 方法重载overload

 

  1.     产生两个继承关系的类                   一个类中的一组方法

子类重写父类的方法

 

  1. 权限  子类可以大于等于父类                                          没有要求
  2. 特征   finale static abstract                      没有要求

父类方法是final子类不能重写

父类方法是static子类不能重写

 

类和类的关系

继承  is a

聚合关系  A has a B   A里面有B  public Computer computer;

依赖关系 A need a B   A需要B    直接传参数在方法里面去和new都可以

 

 

修饰符

本包指的是同一个包 不算同一个包里面的包

Public       只要不出工程哪里都可以访问

Protected    保护的     本类  本包     在子类的范围类(this.)只有在子类的范围内部通过你子类自己才可以访问和创建对象都可以访问

默认                   默认的     本类  本包    

 

final  something

Private               私有的     本类    \       

 

 

Final  最终不可以变的                                                                                                                                                           

修饰变量  存在栈内存里面

修饰属性  存在堆内存里面

修饰方法

修饰类本身  一般用法  public final class Test  也可以final放在最前面

 

修饰变量:如果在定义时没有给变量付初始值就可以给变量一次赋值的机会(因为变量在栈内存中没有默认值如果不给机会就不能用了)

如果被final修饰的是基本类型的话则他的值不能变了

如果是引用类型那么他的引用不能变值可以变化

 

 

修饰属性:全局变量如果定义为final那么必须赋初始值不然报错

 

 

修饰方法:方法是最终的方法 不可被更改

                     子类继承父类的方法 将子类的方法重写(覆盖)

Final修饰的方法 要求不可以被子类重写(覆盖)

 

修饰类本身:类是最终的 不可被更改

                            (太监类 无后)此类不可以被其他子类继承

                            通常是一些定义好的工具类

                            包装类 String Math Scanner

 

Static静态修饰符

 

Static可以修饰: 属性 方法 块 修饰类(内部类)

 

特点:

  1. 静态元素在类加载的时候就初始化了,创建的非常的早,此时没有创建对象
  2. 静态元素存储在静态元素区中,每个类都有自己的区域,与别的类不冲突
  3. 静态元素只加载一次(只有一份)全部类对象及类本身共享
  4. 由于静态元素区加载的时候,有可能没有创建对象,可以通过类名直接访问一般不建议用对象调用
  5. 可以理解为静态元素不属于任何一个对象,属于类的
  6. 静态元素去GC无法管理 可以简单粗暴地认为常驻内存
  7. 非静态成员中(堆内存 对象里)可以访问静态成员变量(静态区)
  8. 静态成员可以访问静态成员(都存在静态存储区)

 

  1. 静态成员不可以访问非静态成员(静态成员属于类加载类是静态成员就已经出来了,比非静态成员先出来)

 

  1. 静态元素中不可以出现this和super关键字(静态元素属于类)

 

设计模式

不是知识点

是一种设计经验的总结

设计模式是用来解决某种场景下的某一类问题à通过的解决方案

有了设计模式之后 可以让代码更容易被理解 确保了复用性 可靠性 可扩展性

 

设计者模型分为三种

         创建型模式(5)种  用于解决创建对象的过程

         单例模式 工厂方法模式 抽象工厂模式 建造者模式 原型模式

         结构型模式(7)种  把类和对象通过某种形式结合在一起构成某种复杂或合理的结构

         适配器模式 装饰者模式 代理模式 外观模式 桥接模式 组合模式 组合模式 享元模式

行为型模式(11)种 用来解决类或者对象之间的交互 更合理的优化类和对象之间的关系

观察则模式 策略模式 模板模式 责任链模式 解析器模式 迭代子模式 命令模式 状态模式 备忘录模式 访问者模式 中介者模式

 

单列模式(懒汉式,饿汉式)

 

 

方法重写                                                                                                      方法重载

 

:产生两个继承关系的类                            一个类中的一组方法

子类重写父类的方法

 

权限:子类可以大于等于父类                          没有要求

 

特征:final static abstract                               没有要求

父类方法是final子类不能重写

父类方法是static子类不存在

父类方法是abstract子类必须重写(子类是抽象类可以不用重写)

 

返回值:子类可以小于等于父类(一般是指的继承返回值)    没有要求

 

名字:子类与父类一致                                 与其他重写方法一致

 

参数:子类与父类一致                                  与其他方法参数必须不一致

 

异常:运行时 编译时                                   没有要求

如果父类抛出编译时异常子类可以不予以理会

如果父类抛出运行时异常,子类抛出异常数小于等于父类

子类抛出的异常类型小于等于父类

 

方法体:子类的方法内容与父类不一致                    每个重载方法执行过程不一致

 

抽象类与接口

            修饰方法

             

  abstract         

            修饰类

 

抽象类中不是必须要有抽象方法

抽象方法必须放在抽象类或者接口中

抽象方法不可以创建构造方法创建对象来调用

只能创建子类的构造方法来调用

 

直接单继承指的是指直接继承没有任何的东西(可以加东西)

抽象类  可以直接单继承  抽象类

抽象类  可以直接单继承  具体类(通常不会这么用没意义)

具体类  不可以直接单继承  抽象类(将父类的方法具体化 或者将子类也变为抽象类)

 

抽象类中可以全部是具体方法 没有抽象方法

抽象方法中可以全部是抽象方法 没有具体方法 抽象到极致了 --> 接口

 

接口

Public interface 名字{}  接口

 

属性                   必须是 public static final String name="朱沛萌";

方法                   必须是含有共有的抽象的方法(jdk 1.8之后可以是default修饰)

块                       没有(块本身就是具体的)

构造方法         没有

 

 

如何使用创建对象

         不能创建对象

         只能通过子类多实现(implements)来做事

Public class A implements B,C,D{}

与别的类结构关系

 

接口类不能继承别的类 最抽象

 

抽象类  可以直接多实现     接口

具体类  不可以直接多实现   接口(必须将接口中的抽象方法具体化 自己变成抽象类)

接口    多继承      接口   可以直接多实现

 

 

匿名内部类

成员内部类:

 

局部内部类:只能用abstract和final来修饰可以重名访问访问局部变量的时候必须是加了final来修饰的

 

匿名内部类:成员匿名内部类和局部匿名内部类

 

静态内部类:

 

枚举(类)

一个类中的对象 认为个数是优先固定的 可以将每一个对象一一列举出来

 

 

 

 

包装类

 

包装类全部放在java.lang(相当于电脑的桌面不需要import导包直接使用)包下

八个包装类有六个是与数字相关的 有两个没有 都默认继承Number

八个包装类都实现了Serializable Comparable

每一个类中的构造方法

八个包装类里面都有自己类对应类型的构造方法

八个里面还有七个带有方构造法重载除了Character都带有String类型的

Integer i1=10;
Integer i2=
10;
Integer i3=
new Integer(10);
Integer i4=
new Integer(10);
System.
out.println(i1==i2); true  数字范围-127~128超过之后就就在堆内存里面new
System.
out.println(i1==i3); false
System.
out.println(i3==i4); false
System.
out.println(i1.equals(i2)); true
System.
out.println(i1.equals(i3)); true
System.
out.println(i3.equals(i4)); true

 

 

Math  Random类

 

数学类 Math在java lang包里面 Random类在java.util里面(要导包)

Math构造方法是私有的 我们不能直接创建对象调用

由于Math中提供的方法及属性都是static 不需要创建对象

常用方法

         abs()绝对值 ceil()向上取整  rint()找的是最近的整数如果是一半则返回偶数  floor()向下取整  round()四舍五入   pow()取a的b次方  sqrt()开算术平方根

 

 

UUID在java.lang包里面

 

Date类

import java.util.Date;里面
常用方法before() after() setTime() getTime()(long类型的) compareTo()(-1 1)
处理一个时间的格式
 
DateFormat java.text此时类是抽象类不能创建对象子类来创建SimpleDateFormat

DateFormat df=new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
String time1 = df.format(date2);
System.
out.println(time1);

 

 

Calendar类

在java.util需要导包

有构造方法但是是protected自己访问不到通常会调用(静态)getInstance();

常用方法after()  befor()  getTime(Date)  setTinme(Date)

TimeZone在java.util包里面可以通过calendar.TimeZone()得

或者TimeZone.getDefault()获得

常用方法getId()和getDisplayName()

 

字符串相关

String类在java.lang包不用导包实现了三个接口Serializable CharSequence Comparable<>

默认继承object类

==比较基本类型的话比的是值 引用类型比的是地址

equals在object类中是==要想改变的话就得重写equals方法比如String Integer

System在java.lang包里面

char [] a={‘a’,’b’,’c’,’d’};

String s1 = new String(a);

 

String的不可变性:String类中包含一个数组private final char []value;

final最终不可变的  地址不让改变本身长度也变不了

private修饰的只能在当前类中访问 数组的内容不让改变

主要体现在两个地方 长度内容

长度  因为数组本身的长度就不可以改变然后还加上了final修饰地址也不可以改变

内容  因为它是private修饰的只能在本类访问不能在外部访问

 

对象存储

“abc”  在字符串常量

new String(“abc”)  在常量池

String str = "a"+"b"+"c"+"d"字符串拼接中产生了7个对象

value str = “a”+”b”+”c”+”d”;

value[] 数组一 a  “a”

value[] 数组二 b  “b”

value[] 数组三 {a,b}  “ab”

value[] 数组四 c  “c”

value[] 数组五 {a,b,c}  “abc”

value[] 数组六 d  “d”

value[] 数组七 {a,b,c,d}  “abcd”

 

 

常用的方法

boolean = equals(Object obj)继承自object重写了比较两个字符串是否相等

int = hashCode继承自object重写了将当前字符串的每个char元素拆开乘以31求和

int = compareTo(String str)实现Comparable接口 实现了按照字典(Unicode)索引比较

 

char = charAt(index);”ask” 0àa

返回对应的index的那个值char类型的

 

int = codePointAt(index);”jafjf” 1à97

返回对应的index所在位置的code值

 

int = length()这是方法

返回字符串的长度

 

String = concat(String)

将给定的字符串拼接在后面

 

boolean = contains(CharSequence s)

判断给定字符是不是在字符串中

 

starsWith(String prefix)endsWith(String suffix)

判断此字符串是否以xx开头结尾

 

byte[] =getBytes(); -->getByte(String charsetName)

char[] =toCharArray();

 

int index = indexOf(String/int,);

当前元素出现的第一次索引位置如果不在就返回-1

lastindexOf()与之相反

 

boolean = isEmpty();

判断字符串是否为空串 ””

 

replace();

replaceAll();

replaceFirst();

将给定的字符串替换为另外的字符串

 

split(String  regex,int  limit)按照给定的格式将字符串拆分后面是拆成几段

 

String = substring(int begin,int end)截取给定范围类的字符串

 

toUpperCase()  toLowerCase()

将给定的字符串进行大小写转换左开右闭

 

String = trim()只能去掉字符串前后多余的空格

 

第一梯队(重写)

equals  compareTo  hasCode  toString

 

第二梯队(常用)

charAt()  codePointAt()  indexOf()  lastIndexOf()  substring()  replace()  split()  length()  contains()  concat()  trim()  getBytes()  toCharArray()  match()

 

第三梯队(一般)

toUpperCase()  toLowerCase()  starsWith()  endsWith()  isEmpty()

 

boolean = matches(String regex)正则表达式判断 regex正则表达式

StringBuffer and StringBulider

 

所属java.lang包

默认继承object实现接口Serializable CharSequence Appendable

StringBuffer和StringBulider没有comparaTo方法

StringBuffer和StringBulider含有一个String没有的方法append();拼接

 

特性

         可变字符串 char [] value可以动态扩容

 

对象的构建

无参构造方发

有参构造方法

StringBuffer sb = new StringBuffer();  默认是16长度的char数组

StringBuffer sb = new StringBuffer(int length);  可以自定义长度

StringBuffer sb = new StringBuffer("String");  默认是16+字符串长度

 

 

StringBuffer和StringBulider中常用方法

最主要方法append();频繁的拼接字符串使用

ensureCapacity()确保容量够用

capacity()数组的真实长度

length()数组的真实长度

 

char = charAt(int index);  取给定位置的字符为char类型的

int = codePointAt(int index);  取给定位置的字符的code码

String = substring(int start, int end); 截取给定位置的字符串必须接String(可以不要后面的参数)

 

StringBuffer() = delete(int start, int end);删除给定位置的值用他自己来接也可以不接他

 

StringBuffer() = deleteCharAt(int index);给定的位置的字符删了

 

int = indexOf(String str, int fromindex);寻找某个字符串出现的位置(从前往后寻找)

int = lastIndexOf(String str, int fromindex);寻找某个字符串出现的位置(从后往前寻找)

 

insert(int index ,value);

 

replace(int start, int end, String str)替换给定位置的字符串

 

setCharAt(int index, char value);

将给定位置的字符修改为指定的字符

 

toString()就是将StringBuffer或者StringBuilder()转换为String类型

 

trimSize();去掉数组中多余的元素

 

 

知识总结

一般是用于频繁的追加字符串append();

常用方法

         与String类不同的方法

         append()  insert()  delete()  deleteChar()  reverse()

 

 

与String相同的方法

charAt();  codePointAt();  indexOf();  lastindexOf();  replace();  string();字相同用法不一定一致

 

StringBuffer和StringBuilder的区别

StringBuffer是jdk1.1  StringBuilder是jdk1.5

早期版本 线程同步   安全性较高  执行效率相对较低

晚期版本 线程非同步 安全性较低  执行效率相对较高

 

Regular Expression正则表达式

regex带有规律的表达式匹配字符串格式

 

下面都是描写一个字符的

[abc]  必须是abc其中一个

[a[^bc]] 第一个必须是a后两个不能是bc中一个

[a-zA-Z] 必须是这两个中的一个

[a-z&&[^bc]] 必须是a-z中一个但是不能是bc

 

. 表示任意一个字符

\d 表示digital数字[0-9]

\D 表示非[^0-9]的数字

\s 表示space留白 如 空白 换行 回车

\S 表示非留白

\w 表示[0-9A-Za-z]中任意一个字符

\W 表示非[^0-9A-Za-z]中的任意一个字符

 

下面都是描写字符出现的次数的

?出现0-1次

*出现0-n次

+出现1-n次

{n}出现n次

{n,}至少出现n次

{m,n}出现m到n次

 

//先利用Pattern类创建一个模式 可以理解为正则表达式对象
Pattern pattern = Pattern.compile("\\d{6}");
//创建一个字符串
String value = "134656ahjf123458fhdj654123";
//利用pattern模式创建一个匹配器
Matcher matcher = pattern.matcher(value);
//用匹配器创建出来的对象调用find方法
while(matcher.find()){
    //一组一组的输出
    System.out.println(matcher.group());

}

需要导包java.util.regex.Matcher;  java.util.regex.Pattern;
 

 

集合都在java.util包里面

 

Collection(存储的都是value)                               Map(以key-value形式存在)

list(有序可以重复)    Queue    Set(无序不重复)    key是无序无重复 value是无序可重复

序:指的是拿进去是第几个然后取出来就是第几个

重复:指的是有重复就不存了两个对象元素对象一致

 

 

 

 

ArrayList  Vector 区别StringBuffer和StringBuilder的区别

List集合

ArrayList  Vector  LinkList

 

ArrayList

底层就是一个数组 适合便利和轮询 不适合插入删除

无参构造方法  带默认空间的构造方法  带collection参数的构造方法(可以传入其他几类)

常用的方法   小容器

add(E e)  add(int index ,E e)

addAll(Collection c)并集

add(int index,Collection c)

clear()清除集合里面的所有元素

contains(Object);寻找某个元素是否在集合中

int = indexOf(Object)  lastIndexOf()

isEmp()  Iterator = list.iterator()//迭代器

remove(int index)  remove(Object)

removeAll()差集

retainAll()交集

set(int index,E value)

List = subList(int start, int end);

toArray();    toArray(T[]);

trimSize()真实元素那么长

 

 

由于ArrayList底层是Object[]数组什么类型都可以存进去

取出来的时候是多态效果所以去出来的时候需要造型显得非常的麻烦

jdk1.5 之后出现了泛型概念

 

泛型

         用来判定数据类型的  定义的时候用某种符号来代替某种类型

在使用的时候应该把那个符号换成具体类型

泛型可以用在那里

泛型类可以放在类的后面集合就是这样的

泛型接口

与集合类用法差不多一致子类用的时候必须写为具体的型

 

public interface Test{

         public T value;

}

 

public class Son implements Test{}

 

泛型方法

         调用方法时在给他定型 与类无关 可以在没有泛型的类里面

 

高级泛型  规范边界 extends super

 

 

Vector

 

是ArrayList早期版本  底层也是利用(动态)数组来实现的

线程是同步的(synchronized)比较安全但是效率比较低

扩容是2倍的扩可通过构造方法来自定义数组长度

方法和和list里面都差不多

 

 

Stack栈类  继承Vector

只有一个无参数的构造方法

特殊的方法

push(E e)将某个元素压入栈顶 --> add()

E =pop()将某一个元素从栈顶取出并删除E = remove()

E = peek()查看栈顶的一个元素不删除  get()

Boolean = empty() 判断栈内的元素是否为空  Boolean = isEmpty()

int = search() 看看给定的元素在栈中的位置indexOf()

 

Queue接口

子类LinkdList  ArrayDeque

通常无参数构造

一般方法

add()

element()  相当于get()

remove()

 

 

Boolean = offer(E e);相当于add()  不会抛出异常

E = peek() 查看相当于element()

E = poll() 剪短相当于remove()

 

LinkedList

底层使用双向链的结构 适用于插入或者删除 不适合遍历和轮询

构造方法  无参的有参的

常用方法  增删查改  add()  get()  set()  size()  remove()

手册中的方法

addAll()  addFirst()  addLast()  clear()  contains()  element()  getFirst()  getLast()

indexOf()  lastIndex()

 

 

 

HashSet

无序无重复 没有set(查询)方法 没有get()方法 可以用增强for循环

无序:指的是我们存放元素和取元素的位置不是一样的

HashSet  (底层是HashMap  数组加链表  散列表 临街链表)

 

方法

boolean add()  boolean remove()

iterator()迭代器获取一个迭代对象

 

无重复原则

         先利用equals方法比较

         如果我们要让自己写的一个类默认比较的是内容那么我们可以重写equals方法

         其次是比较了hashCode方法比较他们的hash值是否相等

两个方法共同作用才出现了HashSet的无重复原则

发现重复就拒绝存入

 

TreeSet

TreeMap-->二叉树利用Node(左  中  右)

无序无重复

无参构造方法   带collection构造方法

基本常用方法

         add()  iterator()  remove()  没有修改  size();

 

无重复规则是如何实现的

         TreeSet本身是有顺序的是按照Unicode码排序的

         但是和我们存放和取出的位置是不一样的

         他的排序是通过compaTo来实现的

         如果想让自己写的类能存进TreeSet中就必须重写comparaTo方法不能随意的添加

         如果发现内容相同就拒绝存入

 

Map

 

HashMap存储的是键值泛型是两个

key是无序无重复(重写hashCode和equals方法) value是无序有重复的

构造方法有有参的也有无参的

常用方法

         put(key, value)(也可以修改)  remove(key)  replace(key, value)  get(key)

         Set = keyset()获取全部的key  Set = entrySet()entry相当于一个节点

key存储的顺序与取得的顺序不一致

key不能相同如果相同的话那就覆盖原来的(与set的相反)

不同的key可以存储相同的value

API中的方法

         clear()  containsKey()  containsValue()  getOrDefault(key , defaultValue)(defaultValue是自己加的如果key没有找到才加)  isEmpty()  putAll()  putIfAbsent(key,value)(如果有key就不添加了如果没有就添加进去) 

 

数组和集合什么情况下用

想要存一组元素如果希望存进去的值不变的话就用数组长度不确定的话那就用集合

 

如果长度不确定的话该选哪个集合

List  Set  Map

List家族有序的  存储有序的就用这个

         ArrayList   适合遍历和轮询

         LinkedList  适合插入和删除

         Stack      后进先出 (LIFO)

 

Set家族无重复 如果存储元素希望无重复就用这个

         HashSet    性能比起下面更高

         TreeSet     希望存进去的元素自动去重复同时还能自动排序

 

Map家族key-value 希望通过唯一的key快速找到value就用这个

         HashMap   性能更高

         TreeMap    希望存进去的元素key自动排序

 

 

HashMap底层的数据存储结构

         散链表结构   数组加链表

HashCode方法  不同的对象可以产生相同的hashCode码   而不同的hashCode码不能产生相同对象

TreeMap

你要的Java基础笔记在这里_第1张图片

你要的Java基础笔记在这里_第2张图片

自然有序按照Unicode码排序的

Tree中的key需要可比较的key的对象需要实现comparable接口

底层实现的结构是红黑二叉树

 

 

异常

 

Exception

RuntimeException(运行时异常)                        其他异常

 

异常的分枝体系

运行时异常(非检查异常)

         Error和RuntimeException都算运行时异常编译的时候不会被检测

         这类异常我们可以处理也可以不去处理(用try  throws就可以了)

         只要求我们知道错在哪里了和知道怎么修改就可以了

         InputMisMatchException  输入不匹配

         NumberFormatException  数字格式化

         NullPointerException     空指针异常

         ArithmeticException      数学异常  10/0     小数/0不会有异常infinity

         NegativeArraySizeException 数组长度为负

         ClassCastException       造型异常

         StringIndexOutOfBoundsException  字符串长度越界了

         ArrayIndexOutOfBoundsException  数组越界

         IndexOutOfBoundsException   集合越界

         IllegalArgumentException     参数不合法

 

编译时异常(检查异常)

 

这类异常产生后我们必须去处理不然极有可能导致后续的代码停止

这时候就要求我们取处理异常了  处理异常不代表异常没有了  处理异常指的是处理完该异常后后续的代码能够正常的运行了

 

处理异常的手段

try{} catch(){} finally{}

try不能单独出现要么跟catch 要么跟finally

catch可以出现很多个

catch(NullPointerException e){}多个异常之间没有等级关系(除了Exception是所有异常的父类他执行了后面的异常就不能执行了)捕获异常只能是从小到大不然报错

 

final   finally    finalize

final修饰方法属性变量类是一个特征修饰符

final修饰方法不能被重写

修饰属性必须赋值不然会报错

修饰变量  如果为基本类型的话值不能发生改变 引用类型的话只可以发生变化地址不可以发生变化(如果没有赋初值给一次机会赋值)

 

finally

是try  catch之后的代码块可有可无有且只能有一块

 

finalize

是Object中的一个protected修饰的方法

对象没有任何指向的时候会被GC回收回收的时候回调用finalize方法

若想看到对象回收的效果可以重写public void finalize(){}

 

当在方法中有try catch finally 和return时不管return在哪里只要有finally他都要执行然后再把相应的返回值给出去他们三个是一个大家庭

 

 

 

Throws抛出异常谁调方法就抛给谁

throw一定是在方法内产生的  属性(全局变量)是产生不了异常的也处理不了的  块也没有异常

抛出异常也可以抛出几个  与catch类似  抛出异常也是从小到大

 

 

自定义异常 

自己描述一个异常类  必须要继承异常

如果自定义异常继承--->RuntimeException 则为运行时异常可以处理也可以不处理

如果自定义异常继承--->Exception则为编译时异常那么我们就必须处理了

 

想要用自己的异常就必须

创建一个自己定义的异常的对象然后用throw关键字主动产生异常

 

 

 

I/O流

在java.io包下面

我们在程序中创建的File他不是一个文件或者文件夹他只是一个对象它和电脑硬盘中的文件只是形成了一个一一对应的映射关系

流指的是数据的流动分为Input(读数据)输入     Output(写数据)输出

 

File

File不能直接操作文件中的内容只能错做文件本身

File中的常用方法

canRead()是否可读  canWerite()是否可写  isFile()是不是文件(.txt)  isDirectory()是不是一个文件夹  isHidden()文件是否隐藏状态  length()文件的长度(字节个数)  lastModified()获取文件的最后修改时间毫秒值

 

String path = getAbsolutePath()获取文件的绝对路径

相对路径  就是前面不加盘符默认是当前工程的路径

String name = getName()获取文件的名字

你要的Java基础笔记在这里_第3张图片

 

createNewFile()创建一个文夹要抛异常他可能没有父亲C:\a\Test.java可能没有a文件夹

mkdir()创建一个文件夹单一的

mkdirs()创建多个文件夹

getParent()获取当前file的父亲的file名字

getParentFile()获得当前file的父亲file对象返回值是File

String [] str = list()获取当前文件夹的儿子的名字的

File [] file = listFiles()获取当前file的所有儿子的对象的               只有文件夹才可以调用这两个方法,如果文件调用这个方法的话不会报错数组为null,当前file是文件数组不为空他的长度为0则说明文件夹为空

 

delete() 布尔类型的删除不了带东西的文件夹,不管文件里面有没有东西都直接删掉不能找回

文件夹的遍历----需要一个递归

 

查看属性

创建新的文件文件夹

查看父目录

对文件的删除和遍历(通过递归方法)

 

字节型文件输入流

在java.io     FileInputStream继承InputStream类

 

 

里面的方法 

available()返回从此输入流中可以读取(或跳过)的剩余字节数的估计值

read()读取文件当中的文字一次只读取一个字节

read(byte[] b)一次读取byte数组的长度这么长的字节

skip(long l)跳过多少字节读取

 

 

创建文件如果是输入流的时候如果没有那个文件则会抛出FileNotFoundException异常

创建文件如果是输出流的时候如果没有那个文件他不会抛出异常反而会默认帮我们创建那个文件

FileInputStream (读文件)  FileOutputStream(写文件)

 

 

字符流

FileReader(读文件)  FileWriter(写文件)

 

FileReader

继承 InputStreamReader 在继承Reader

构造方法

常用方法

         read()  read(char[])

 

FileWriter

继承InputStreamWriter 再继承 Writer

构造方法

常用方法

write(int)  write(char[])  write(String)  flush()  close()

 

最常用方法

         FileInputStream  FileOutStream  FileReader  FileWriter  方法 read write

 

缓冲流

在流的过程中增加缓存

让我们使用流读取文字更加的流畅

高级流  通过低级流创建

BufferedInputStream/BufferedInputStream

BufferedReader/BufferedWriter

BufferedReader里面的readline方法有用读取一行

BufferedWriter里面的newLine()是学一行

 

 

数组流

         byte数组

         char数组

数据流

 

对象流

         对象的序列化/反序列化

对象的序列化

         将对象拆成字节碎片记录在文件中

对象的反序列化

         将文件中的对象碎片反过来组合成一个完整的对象

想要白对象写进文件里去的话

就必须实现Serializable接口

这和接口只是示意性的说明了了一下没有什么实在意义

为了让对象可以反序列化

需要在对象中多存在一个属性

 

相当于是当前的版本号

 

 

线程

程序

         可以理解为一组静态的代码

进程

         正在运行的程序 静态的代码运行起来

线程

         正在程序中的小单元

 

主线程(系统线程)

用户线程  main

守护线程(精灵线程)GC回收器

 

线程是操作系统级别的   CPU操作

 

线程的几种状态

  new   start     CPU分配(run方法)  wait       exception  over                 

创建线程---à就绪状态---à执行状态---à等待(挂起)---à异常(死亡)

 

 

 

                notifiy/notifyall

实现线程的过程

继承了Thread线程重写run方法

new一个线程对象  调用start方法(我们调用run的话就是单线程了) 让线程进入等待状态

 

实现接口实现Runnable

重写run方法new一个线程对象

 

 

生产者消费者问题

当两个消费者同时访问一个仓库中最后一个元素的时候这时有可能出现资源抢夺问题

 

此时需要加锁  sychronized锁的不是方法是对象谁来调用锁谁

 

 

当没有锁的时候有可能会产生一个IllegalMonitorException

 

 

 

程序进程线程之间的区别

线程的创建方式

线程的几种状态  如何切换

sleep                  wait的区别

类  Thread                 Object

调用 静态 类名             对象

理解 哪个线程调用 谁等待  对象调用方法  访问对象的其他线程等待

唤醒  不需要别人来唤醒     需要其他对象调用notify/notifyall来唤醒

锁    不会释放锁           等待或释放锁

 

join方法是Thread类中的方法

         让多个线程同步执行变成单个线程

死锁

         synchronized一但对象被锁定的情况下没人释放锁其他的对象都需要等待

         这是就可能产生死锁的情况

 

哲学家就餐问题

 

计时器定时器   线程应用

java.util包  Timer类

无参构造方法

time.schedule()

 

private ArrayList list = new ArrayList<>();
private int count = 0;
{
    list.add("a");
    list.add("b");
    list.add("c");
    list.add("d");
}
public void test() throws ParseException {
    System.out.println("预备开始");
    Timer time = new Timer();//一个小线程  DATA  延迟
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date firstTime = sdf.parse("2019-10-28 20:05:00");
    time.schedule(new TimerTask() {
        @Override
        public void run() {
            for(int i = 0 ;i < list.size();i++){
                System.out.println("第"+count+++"次"+"给"+list.get(i)+"发一条信息");
            }
        }
    },firstTime,2000);
}

public static void main(String[] args){
    TimerTest tt = new TimerTest();
    try {
        tt.test();
    } catch (ParseException e) {
        e.printStackTrace();
    }
}

 

 

究极版单例模式

private SingleTon(){}

private static volatile(为了防止重排序) SingleTon singleTon;

public static SingleTon getInstance(){
    if(singleTon == null){
        synchronized (SingleTon.class){
            if(singleTon == null){
                singleTon = new SingleTon();
            }
        }
    }
    return singleTon;
}

 

反射(reflect)

 

类              从很多对象中抽取出来的共有的行为特征 抽象描述 用来描述一组对象

对象         从现实生活中存在了好多的对象 很多相同特征 相同行为

 

类是用来描述一组对象

反射机制则可以理解为用来描述一组类的(与File差不多)

 

Class    用来描述类本身

Package  用来描述类所属的包

Filed     用来描述类中的属性的

Method   用来描述类中的方法的

Constructor  用来描述类的构造方法的

Annotation   用来描述类中的注解的(@Override)

 

获取类的方法

Class c = Class.forName(“包名.类名”);

(可以直接通过Object object = c.newInstance建立一个无参构造方法只能是无参)

Class c = 类名.class;

Class c = 对象.getClass();这是Object类中的方法(String str = new String(“java”);)str.getClass();

 

Class类中的常用方法

 

int modifier = getModifieras();获取权限修饰符和特征修饰符的

 

String name = getSimpleName();获取类名字的

String name = getName();获取类全名的包括他所属的包

 

Package p = getPackage();

         p.getName();

 

Class clazz = getSuperClass();获取父类

Class[] classz = getInterface();获取接口的

 

 

Field中的常用方法

int = Modifiers()

Class = getType()

String = getName()

 

Class clazz = Class.forName("refleckt.Person");

Field field = clazz.getField("name");//知道属性的名字

Field [] field = clazz.getFields(); 不知道里面的属性就直接获取全部的属性包括继承父类的属性都一起列出来  只能获取公有的

 


int a = field.getModifiers();
System.out.println(a);

Class s = field.getType();
System.out.println(s.getSimpleName());
System.out.println(s.getName());
System.out.println(field.getName());

 

反射操作String里面的private final 数组;

String str = new String("abcdefg");

    Class clazz = str.getClass();

    try {
        Field field = clazz.getDeclaredField("value");//只能获取本类的所有属性不能获取父类

        field.setAccessible(true);
        char [] c = (char [])field.get(str);
        c[0] = '你';
        c[1] = '我';
        System.out.println(str);
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
}

 

Class [] = getClasses();获取内部类

 

操作方法

Method [] method =  clazz.getDeclaredMethods();

System.out.println(method1.getModifiers());//修饰符
System.out.println(method1.getReturnType().getSimpleName());//返回值名字类型
System.out.println(method1.getName());//方法名字
Class [] cc = method1.getParameterTypes();//获取参数列表的类型
Class [] exception = method1.getExceptionTypes();//获取异常的类型的

 

(可以有返回值) = (String) method1.invoke(p,"类型(Integer String Double)");

 

 

注解

注解的写法@xxx[(信息)]

注解放在哪里   类上面  属性上面  方法上面  构造方法上面  参数前面

 

注解的作用

         充当注释的作用(仅仅是一个文字说明)  @Deprecated

         用来做代码的检测(验证)    @Override

         可以携带一些信息(内容)  文件.properties   .xml  注解

 

java中有一些人家写好的注释供我们用

         @Deprecated    说明方法已经废弃了

         @Override       用来做代码检测  检测此方法是否重写

         @SuppressWarnings(信息)  String[] 数组  unused变量定义后未被使用  (serial)序列化

         rawtypes(没有泛型)  unchecked(出现了泛型问题)  all是直接取消所有的非语法错误

 

 

Properties pro = new Properties(); java.util下想map集合他读取的是.properties文件
        try {
            pro.load(new FileReader("src\\Test\\test.properties"));

//            String name = pro.getProperty("key1");
//            System.out.println(name);
            Enumeration en = pro.propertyNames();//得到的是key
            while(en.hasMoreElements()){
                String key = (String) en.nextElement();//遍历的是key
                String value = pro.getProperty(key);
                System.out.println(key+"---"+value);
            }

注解中可以携带信息可以不携带

信息不能随意的写只能是以下的类型

String  Enum  基本数据类型      注解类型         数组类型[]  数组里面只能是如上的几种类型

 

 

如何自己创建一个注解

 

 

 

通过  @interface  定义一个性的注解类型和接口有点象

属性都是public static final的属性

 

如何自己描述一个注解类型

通过@interface定义一个新的注解类型

写法与接口非常的相似

属性是用public static final 来修饰的

方法是用public abstract 来修饰的但是方法必须有返回值

自定义元注解如果像要使用

         就要细致的说明(利用元注解)

         @Target描述自定义注解可以放在哪里

         @Retention描述当前的注解的作用域

         源文件à编译à字节码文件à加载à内存执行

         SOURCE        CLASS             RUNTIME

@Inherited描述当前的注解是否能被子类继承

@Document 描述这个注解是否能被文档所记载


import static java.lang.annotation.ElementType.*;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.Docment;


@Target({TYPE,CONSTRUCTOR,FIELD,METHOD})描写可以放在哪里
@Retention(RetentionPolicy.RUNTIME)描写作用域
@Inherited

@Document
public @interface MyAnnotation {
    String test();
}

 

自己使用自己描述的注解

问题一.

在注解里面描述了一个方法 方法没有参数 方法是返回值String [] 使用的时候让我们传递参数  可以理解为 注解的方法做事将我们传递的参数搬运走了给别人

问题二.

         使用别人定义好的注解我们不用写方法名我们自定义的要写方法名=  是怎么回事呢

         是因为别人定义好的注解里面只有一个方法  它写成value就可以不用写方法名=

如果我们自己写的注解要想不用写方法名= 的话也可以把方法名改为value 但是如果有一个以上的方法了就必须写方法名= 别人的也是public class TestAnnotation {
    @MyAnnotation(test = "aaa")
    private String name;
}

 

如何获取注解里面的内容

Class clazz = Person.class;
Field field = clazz.getDeclaredField("name");//获取属性
Annotation annotation = field.getAnnotation(MyAnnotation.class);//获取Annotation的类型
Class aclazz = MyAnnotation.class;//获取Annotation的类型(annotation.getClass)
Method method = aclazz.getMethod("value");
String values[] = (String[]) method.invoke(annotation);
for (String value : values) {
    System.out.println(value);
}

 

 

低级Spring(之ioc)

 

 

 

GUI(窗体,菜单,面板组件)

 

                            AWT                       Swing

窗体        Frame                      JFrame

                            Panel                                                 Panel

                            Button                                              JButton

                            TextArea                                          JTextAre

                            Lable                       JLable

                       TextField                    JTextField

                                                                                             JMenubar菜单条

                                                                                             JMenu菜单

                                                                                             JMenuItem菜单项

 

frame最大的窗体管理方式边界式中东西南北           BorderLayout

 

JMenuBar 菜单条 上面frame. set JMenuBar (bar) ;

Panel 面板可以有多个 管理方式流式居中              FlowLayout

 

组件

frame. setLayOut (new FlowLayout () ;

frame. setLayout (null) ;|

 

 

事件     ActionListenter   KeyListener  MouseListener  Windos  Item…

 

 

 

 

第一阶段

数据库

 

MySQL

操作数据库的语言规范

SQL接过话查询语言(关键字不区分大小写,最好大写)

DDL数据定义语言

         用来创建,删除,修改数据库中的对象(create创建,drop删除,alter修改)

DML数据操作语言

         用来操作数据库表格中的具体数据

         写数据,(insert),(delete),(updata) 创建数据库create

         读数据 (select)  à

DQL数据查询语言

                   select  where(条件)  group by(分组)  having(条件)  order by(排序)

DCL数据控制语言

         用来控制用户权限的   SYSDBA数据管理员

         (赋予权限)grant 权限,权限 to 用户

         (回收权限)revoke 权限,权限 from 用户

TPL事务处理语言

         (可以理解为多线程并发访问同一个文件带来的安全问题)

         begin transcation启动一个事务一般oracle  mysql是自动的

         操作  commit提交 rollba回滚 save point A保存还原点

 

数据库安装完成之后

在命令行输入show databases;之后看自己又几个数据库分号必须加不然认为没有输入完

想要用那个数据库就用use xxx 就可以使用那个数据库了

用show tables;显示当前数据库的表格

 

MySql相当于一个小小的服务

         先启动服务器localhost开放一个端口3306

 

 

卸载数据库

         停止服务 卸载产品 删除注册信息  运行à 输入à regedità 选择HKEY_LOCAL_MACHINEà SYSTEMàControlSet(有几个)开头àMySql和EventLog(ApplicationàMySql)

 

MySql不区分大小写            创建一个表格create

创建数据库

creat table 表名(列名,类型(长度), 列名,类型(长度), 列名,类型(长度));

 

数据库存储的数据

         存储数据的方式来分类大致可以分为三类:

         数值型

                   整数 tinyint  smallint  mediumint  int/integer(4字节32个比特位)  bigint

小数float  double  decimal  numeric前面两个要精确一些(m,n)一共m为小数点后n位(m默认10,1-65)(n默认0,0-30)

         字符串

                   char字符串(不可变动)(char (4) 规定是4字节了就算你写的是’a’前面也是3个0)

                   varchar可变字符串  varchar(4) 你只写了’a’自动是占用一个字节

                   variable可变的

 

                   binary二进制

                   varbinary 可变二进制

                   blob二进制大文本

                   text正常大文本

         日期/时间

                   date日期  time时间  datetime时间&日期  timestamp时间戳(详细是时间年月日)

 

在自己的database中建立一个表格

         用来记录学生的信息---Student

                   学号  姓名  性别

 

通过DDL来修改表的结构

         修改表格的名字 alter table 原表名 rename [to] 新表名

修改原有的列(修改表格的列名 类型 长度 )

         alter table 原表名 change 原列名 新列名(其他可以改可以不改其他一样)

新增一列

         alter table 原表名 add 新列名 类型 长度

删除原有的列

         alter table 原表名 drop 要删除的列名

删除表格 drop table 表名

删除database(数据库) drop database 数据库名字

 

 

 

 

新增记录

         insert into 表名(列名…) values (值…);

insert into 表名 values (值…);可以省略列名就是插入全部信息

insert into 表名 values (值…),(值…)…;可以一下增加几个记录

 

创建数据库的时候可以默认字符集

         create database 数据库名 default character set = ‘utf8’;

         insert into student values () default character utf8 collate 排序效果;

         排序效果utf8_general_ci      utf8_unicode_ci

 

如果不知道自己使用的是什么字符集的话

         select 列 from 表 where 数据库 = ‘自己数据库名字’;

select schema_name,default_character_set_name from information_schema.schemata where schema_name = ‘数据库名字’;

 

查询记录

         select 列名 … from 表名 where…

删除记录

         delete from 表名 where….

修改记录

         update 表名 set 列 = 值,列 = 值,where…

 

查看数据库的状态

         show table status from 数据库名 like ‘表名’;

 

条件筛选where

         除了insert后面不加where    delete  updata  select之后都可以加上where

delete from 表名 where…

updata 表名 set 列 = 值 where…

select 列 from 表 where…

选出来的是符合条件的行  不是列

按照某一列后者某一条件来筛选的

(not)between A and B包含AB

select * from 表名 列名 (not) in (a,b);满足ab的条件

like 模糊查询  后面经常跟上  %(0到多个)  _(有且仅有一个)

排序  order by  升序排列(默认是asc) 降序排列(desc)

 

数据库常用函数

         比较函数

                   ifnull(值) 空就返回1 不空就是0

         数学函数abs绝对值 floor向下取整 mod(5,2)5对2取余  pow()求次方  round四舍五入

 

日期时间类

         now()  year(date数据)  month(date)   day(date)

 

控制流程函数

         if(条件,值1,值2),满足就是值1不满足就是2

         ifnull(值,v)如果为空就是v不是空就不管

 

字符串函数

length()  concat(字符串拼接)  substr(截取)  instr(str,’a’)  replace()  upper(大写)  lower(小写)  ltrim(去左空格)  rtrim(去右空格)  lpad()  rpad()

reverse(反转)

 

distinct去重

distinct 列,列…如果后面跟上了几个列那他就是组合几个列来看的一列和二列是一样的

话就去重复

 

分组函数

         count(字段(*))记录个数  *是指的一行只要有东西就记录

         max() min() avg() sum()

where > group by> having(小where)>order by

嵌套查询

         嵌套可以将一个查询语句当成另一个查询的条件

         可以将上一次的查询结果当作下一个查询语句的表格

         可以联合几张表格的东西只要有联系

 

几个关键字的使用

         in满足查询子集中的某一个即可 默认=比较in后面的子集内可以是常量可以是表达式

 

以下三个后面只能跟一个表的式子不能跟一个固定的值

         any 满足子集中的一个即可>any

         some 与any用法一样的

         all满足子集中的全部才行

 

集合操作

         并集union

要求要查询的前后两个列数是相等了

类型没有要求,列名默认是前一个子集的名字

union和union all的区别

         union合并后可以去重复  性能较慢去重后的元素是第一个后面的就不让他出现

         union all是直接合并元素不去重性能快

 

列的约束

 

 

主键约束

         每一个表格内只能有一个列为主键

         主键通常是用来表示表格中的数据是唯一存在的

         主键约束当前列不能为null值

         主键约束要求当前列值是唯一存在的不能重复

添加约束语句

         alter table 表名 add constraint 约束名字 约束类型(列);

         alter table student add constraint pk_myclass primary key(id);

         alter table 表名 add constraint (主键名字) primary key(列);

         constraint可以不要

         设置主键之后可以设置主键的某些特性

主键自增alter table 表名 modify 列名 int(4) auto_increment;没有值就默认是1

alter table 表名 change 列名 列名 修饰符(多少位) auto_increment;

alter table 表名 auto_increment = 值;就从值开始自增1

        

    去掉自增约束 alter table 表名 modify 列名 int(4);

         去掉主键约束 alter table 表名drop primary key;但是非空特性还在

 

         看key的方式 desc 表名;

         show keys from 表名;

唯一约束

         可以为表格中的列添加唯一约束

         他的值可以为空但是不能重复

         他可以位多个列添加约束

         alter table 表 add constraint 约束名 约束类型 (列)

         alter table student add constraint uk unique key (id);

         简写alter table student add unique [key](id);

         删除 alter table drop index 约束名

非空约束

alter table 表 modify 列 int(4) (not) null ;

alter table 表 modify 列 int (4) not null;

alter table 表 modify 列 int(4) not null default 值;设置默认值

检查约束

外键约束

         约束自己表内的信息不可以乱填

         受到另一个表格某一列的影响

         可以有多个列被设置可以重复可以为空

         当前列的值受到另一张表格某一列的影响

         另一张表是唯一约束(主键  唯一)

         alter table 表 add constraint 约束名 foreign key (列) references 另一个表 (列);

         alter table 表 add foreign key (列) references 另一个表 (列);

         删除外键约束alter table 表 drop foreign key 外键名字;

         执行上述语句其实外键已经被删除了

         但是系统会自动生成一个key 名字和外键一样的需要自己手动删除

         alter table 表名 drop key 名字;一般是删除外键的key  

看key的语句

         show keys from 表名

         desc 表名

         show create table 表名;

 

关系

         一对多  一端有一个主键 多端保证一个外键与外表关联

         多对多  一般是两个主表然后一个中间表来实现主表与主表之间的关系

         一对一  在一对多的基础上来实现的  可以将多端的主键设置为外键

表格之间的联合查询

广义笛卡尔积à等值连接

                   竖着的列是两个表格列之和

                   横着的行是两个表格行之积

                   将两张或者多张表格连接起来没有条件约束任何的表都可以

                   select * from A ,B where 条件

外连接

         select * from A left/right [outer] join B on条件

         A B先后顺序是由他们谁在左谁在右决定的

         left和right是用来控制基准的谁在select * from A left/right [outer] join B on条件

         以A为基准反之亦然  

         然后后面一个表格就是取决于on后面的条件了有就显示没有则为空  

内连接(自连接)

         select * from A a inner join B b on 条件 where a = b;可以加上where

 

行列互换

select wname 仓库名,sum(if(wmonth=1,wstorage,0)) 一月,sum(if(wmonth=2,wstorage,0)) 二月,sum(if(wmonth=3,wstorage,0)) 三月 from warehouse group by wname; sum可以是其他函数但是运用得合理

分页查询

         语句完成之后  à limit a,b  显示的起始位置[0,..]

 

DCL数据控制语言

         控制用户的权限

         grant赋予

         remove回收

        

         创建新的用户         给新的用户赋予权限     注销用新的用户登录     回收用户权限                   创建新的用户

Mysql配置环境变量

         登录MySql   mysql –u root –p   回车输密码

在mysql数据库中  user表格 里面的user列  host列  password列  更新版本在authentication_string列可以看见用户相关的信息

 

mysql创建新用户

create user ‘用户名’@‘ip’ identified by ‘密码’; ip可以是localhost(本机) 也可以是*(表示所有的ip都可以访问)

         create user ‘admin’@’localhost’ identified by ‘123456’;

         当前的权限是Usage只允许登录不能干其他的

         show grants for ‘用户名’@’ip’; 查询用户的权限

         赋予权限:grant 权限 on 数据库名.表名 to ‘用户名’@’ip’;

         grant all on *.* to ‘用户名’@’ip’;

         然后最好刷新一下:flush privileges;

 

回收权限

         revoke 权限 on 数据库名.表名 from ‘用户名’@’ip’;

修改用户的密码

update user set authentication_string=password(‘密码’) where user = ‘用户名’;password是加密函数

删除用户

         drop user ‘用户名’@’ip’;

 

数据库设计的范式

         目的是减少数据库的冗余

         管理变得简单了

         查询的时候性能可能不太好

Normal Form(标准化形式----普通范式)

1NF

数据原子性

         每一个表格的每一个列都是不可分割的

         在行列的交叉点是不可以存在两个数据的不然违背了第一范式

         必须要有主键

2NF

在满足第一范式的条件下

         非主键不能受到主键(或者主键一部分)的影响  如果影响了就拆分表格

3NF

在满足前两个的前提下

不允许出现传递依赖性(非主键列不能受到主键或者主键列一部分的影响和非主键列的影响)

出现了此类问题就拆开

事务的处理

         实质上就是多线程并发操作一个数据库产生的安全问题

事务的四大特性(ACID)

A(Atomicity) 原子性

         一个事务中的所有操作是一个整体不可分事务中的所有操作要么都成功要么都失败

C(Consistency) 一致性

         一个用户操作数据后另一个用户看到是数据与他之前看到的数据是一致的

I(Isolation) 隔离性

一个用户在操作数据库的同时另一个用户不能干预多个用户之间的数据事务操作要相互隔离

需要考虑到事务的隔离级别

Serializable  级别最高可以避免所有出现的的问题 性能很慢

Repeatable Read 可重复读 (一次会话内永远读到的是一样的)  (MySql默认管理级别)

         即使是数据库已经删除了这个数据(只要没有commit都一样)

Read Committed 只能读已提交没有提交的不能读 (避免脏读)  (Oracle 默认管理级别)

Read Uncommitted 读取未提交 (所有的效果均无法保证)

修改数据库的管理级别

         set session transaction isolation level 级别;设置会话事务隔离级别

         查询级别:select @@tx_isolation;

 

数据库读取出现的问题

         脏读:一个用户读到了另外一个用户没有提交的数据

A修改了数据还没有提交B读到了,然而A不提交数据回滚回来B读到的就是无用数据

         不可重复读

A先读取了数据,然后B对数据进行了修改,A再按前面的条件读一次与第一次读到的不一致了(一个事务里面)

         幻读(虚读)

A先读了一些数据,然后B又增加了记录A按照前面的条件再读一次发现与原来不一致

D(Durablity) 持久性      

指的是用户提交数据之后他对数据库底层是真实存在的不可以变的是永久保存的不可返回

mysql数据库事务管理默认的效果可以更改

         autocommit = on;

         show variables like ‘%commit%’;

show variables like ‘autocommit’;

set autocommit = off;

开启事务  begin; 和 start transaction;

开启一个事务

         每执行一条语句之前都会默认开启事务

执行操作

         各种语句可能不止一条

事务的处理

         提交(commit)/回滚(rollback)/保存原点   mysql 会默认提交事务

show create table bank;查询表格的字符集

alter table bank convert to character set utf8;修改已经建好的表或者数据库的字符集

 

 

JDBC

 

JDBC-ODBC   每一个客户机都需要安装 很耗费空间管理方便

JDBC-Native  类是第一种每一个客户机安装调用原生C/C++具体到某一个数据库

JDBC-Net     使用了标准的Socket通信不需要每一个客户机都进行安装相对比较灵活

纯的JavaJDBC  一个纯粹基于Socket不需要安装在客户机上每一个数据库每一个数据库的厂商自身提供可以下载

先找到适合MySql的JDBC驱动包

         下载一个驱动包

JDBC六部曲

         导包

         加载驱动类 Driver

获取连接

创建状态参数

执行数据库操作

         写  DML   DELETE INSERT UPDATE(对数据库进行更新操作)

         读  DQL   SELECT(数据库没有发生变化  需要处理结果)

关闭  先创建后关闭

package jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class TestJDBC {
    public static void main(String[] args){

//        JDBC六部曲
//        1.导包
//        2.加载类驱动
        try {
            Class clazz =  Class.forName("com.mysql.jdbc.Driver");
//        3.获取链接  DriverManager管理者
            String url = "jdbc:mysql://localhost:3306/test01?characterEncoding=utf-8"; //要连接那个数据库  jdbc:mysql://ip:port/database名字
            String user = "root";
            String password = "123456";
            Connection connection = DriverManager.getConnection(url,user,password);
//        4.创建状态参数
            Statement statement = connection.createStatement();
//        5.执行操作(增删查改)
            //String sql = "delete from bank where id = 7";
            String sql = "insert into bank values (7,'郭雨衡',99999999)";
            statement.executeUpdate(sql);
            System.out.println("执行成功");
//        statement.executeUpdate(String);   ?=statement.executeQuery(String);
//        6.关闭 倒着关闭
            statement.close();
            connection.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

JDBC  5.0 导包àcom.mysql.jdbc.Driver

JDBC  8.0 导包àcom.mysql.cj.jdbc.Driver

5.0  url àjdbc:mysql://ip:port/database名字

8.0  url àjdbc:mysql://ip:port/database名字?serverTimezone=CST

 

加载驱动的目的就是让静态方法执行一次(静态元素在类加载的时候就产生了)

加载驱动的方法

Class.forname(String);

new Driver()

DriverManager.registerDriver(new Driver());

System.setProperty(“jdbc.driver”,” com.mysql.cj.jdbc.Driver”);

他们的目的就是为了加载驱动

 

可以自己设置手动提交事务

         连接.setAutoCommit(false); true是自动提交

设置隔离级别

         连接.setTransactionIsolation(Connection值);

连接.commit()提交

SavePoint s = 连接.setSavepoint(“xxx”)

连接.rollback(s)回滚(回滚到还原点,可以不加s)

 

SQL注入问题

用Statement很不安全容易被别人随意破解

 

所以利用PrepareStatement(预处理状态参数)

Statement和PrepareStatement区别

Statement                           PreparedStatement

普通的状态参数                      预处理状态参数

创建时不需要sql语句                 创建时需要预先加载sql语句

此时没有执行sql                     创建时没有执行但是在底层已经准备好了我们

所需要的sql查询结果性能高可以利用动态化进

行参数的处理利用?替代数据类型及值

 

PrepareStatement好处

 

 

MVC

V:View视图层

M:Model模型层 (数据的处理service,数据的读写dao,数据的存储domain)

C:Controller控制层

 

协议

当想浏览器地址栏中输入一个url回车之后,网络中都会发生什么

         先看浏览器的缓存  如果浏览器认识就直接告诉你ip是什么

         如果不认识 看本机host文件Windows C:windows/system32/drivers/etc/host

         如果还是没有的话就会看自己家里的路由器

         如果还是没有的话就继续访问上级路由/城市的DNS

         层层递进globalDNS

 

         也可能是直接通过域名直接访问ip

 

http协议分为两个部分

 

请求头 + 要搜索的东西

 

你要的Java基础笔记在这里_第4张图片

 

http协议分为两个部分:

请求Request

         请求方式(GET,POST)   路径  协议版本

你要的Java基础笔记在这里_第5张图片

TCP/IP协议(对方的ip自己的ip对方的端口) HTTP协议(请求头)+要搜索的东西

你要的Java基础笔记在这里_第6张图片                                             

Request

         请求头和数据体

         请求方式  url  http协议版本

         GET/POST  /路径?url 协议版本

         HOST:www.baidu.com(连接的网站)

         Connection:keep-alive长连接

         User-Agent:代理各个浏览器的详细信息

        

         如果是post的话这里就是他传输的文件的信息get一般不传输文件

 

请求方式GET/POST    DELETE/PUT/HEAD(不常用)

 

 

响应Response

 

响应头  数据体

         协议版本  状态码  信息

HTTP/1.1    200     OK

         Cache-Control:缓存

GETPOST的区别

  1. 基于什么前提的?如果没有前提不适用任何的规范,值考虑语法和理论的HTTP协议他们没有区别只是名字不同
  2. getpost如果是基于RFC规范的
  1. 理论上(Spacification):getpost具有相同的语法,不同的就是get是用来获取数据的post是用来发送数据的
  2. 实现上的(implementation):各种浏览器各种浏览器就是这个规范的实现者

常见的不同

1).get数据在url是可见的,post请求不显示在url

2).get是对长度有限制的    post对长度是没有限制的

3).get请求的数据可以添加为书签,post请求到的不可以添加为书签

4).get请求道的数据按后退刷新不会受到影响,post则会重复提交

5).get编码类型:application/x-www-form-url

post编码类型有多种:encodeapplication/x-www-form-urlencoded

                 :mulitipart/form-data

6).get历史参数会保留到浏览器中,post不会

7).get只允许ASCII  post没有编码限制允许发二进制的

8).getpost相比,get安全性相对较差,因为所发的数据是url的一部分

 

 

CookieSession区别

Cookie(存放在浏览器客户端上的)

当登录网站之后,网站会自动记住这个cookie,以后每次每一次向浏览器发送请求它都会自动带上这个cookie,服务端看到这个代有idcookie就可以解析这个加密的id,从而获取这个id,如果能获得本身的id那就证明这个用户已经登陆了,后端会继续保留用户信息,cookie是存储在浏览器上面的不是存储在某个页面上的,是可以长期存储的,cookie即是存放在浏览器里面,也是存放在不同的域名下的(每一次请求都会向后端发送的不会因为某个页面的关闭而关闭,不能跨域存储)

 

缺点就是如果有人知道了这个cookie他就可以在他的电脑登录了

 

Session

存放在服务器上的缺点:如果用户量非常的大服务端会非常的耗费资源

用户执行登陆操作之后,在那台机器上执行的就一般存在与哪台机器上

 

B/S结构   Browser只负责展示内容Server负责提供内容

C/S结构   Client只负责展示内容 Server负责提供内容

 

页面的本质就是字符串   就是带html格式的字符串

 

浏览器向服务器请求一个页面的本质是什么

 

服务器接收到请求后,把这个页面内容(带有html格式的字符串)返回给浏览器,页面的内容存在那里存在html文件里面  服务端读取文件将取出来的内容返回给浏览器  最后返回的是一个字符串 这个字符串的来源可能是缓存可能来源于数据库……等等

 

服务器:严格的来说服务器就是一台计算机,这台计算机只提供服务(不是用户用的计算机一般是linux,unix系统)

我们常常说的服务器其实就是一个服务容器不是真正的服务器

         服务容器是一个程序用来监听一个端口,读取文件并且返回,如果我们想通过访问服务器的方式来访问自己的页面我们就得装一个服务器的程序

 

打开网页的方式:

直接在地址栏中输入网址   在浏览器控制台输入location.href=”网站”回车也可以但是页面会跳转

 

代有src的标签请求时可以发出的服务器是可以处理的也是可以返回的但是返回之后能否被应用还得取决于浏览器

带有href的标签请求是可以发出的服务器是可以处理可以返回的但返回之后是否被应用还得看浏览器

带有action属性的标签例如form标签也可以发送请求但是他要跳转页面

 

Ajax既可以用代码控制也可以得到返回及后继续用js处理页面也不会跳转

 

跨域访问资源:

Js算资源可以跨域访问 ,css文件,jpg png等都可以跨域访问,src的资源都是可以被跨域访问的href的资源大部分都是可以被跨域访问的

那些算跨域访问资源

         后端接口的数据

         其他域的cookie

         其他域的缓存

什么算其他域

         页面本身有协议  域名  端口

         http://www.baidu.com:80/.....地址

         只要其中一个不相同就算跨域访问,跨域发生在浏览器端

跨域这个行为发生在那里

         即使(协议 域名 端口号有一个不一样)他也是可以发送请求的

         服务器是可以接受的也是可以处理的也可以返回的

浏览器是可以接受的但是接收到之后浏览器发现页面的域和请求的域不一样就会判定为跨域  我们的代码在这里等着但是浏览器判定跨域了所以不会把结果返回给我们的代码

 

如何解决跨域问题:

后端配合我们进行跨域

  1. JSONP
  2. 后端设置Access-Control-Allow-Origin属性可以跨域

后端不支持我们跨域

         Ifram(只能显示不能控制)

         通过后端代理(自己的后端) 

 

 

 

Servlet

初识Tomcat

 

实际上是一个web容器

一般通用的web容器

         Tomcat  Apache开源的

         Jetty    轻量级的

         Resin    Caucho公司的

         JBoss    Weblogic  WebSpher

Tomcat是Apache开源的免费一个容器

用来管理web项目  包括Servlet Html+css+JavaScript

Tomcat发展历程

Tomcat6   JDK1.5   Servlet2.x  EL2.X   JSP2.X

Tomcat7   JDK1.6   Servlet2.x  EL2.X   JSP2.X

Tomcat8   JDK1.7   Servlet3.x  EL3.X   JSP2.X

Tomcat9   JDK1.8   Servlet4.0  EL3.0   JSP2.3

 

Tomcat文件结构

         Bin目录            服务器启动相关

         *Conf                 配置文件  主要(web.xml(请求相关)  server.xml(容器自身的信息  比如端口))

         Lib文件     jar形式的包

         Logs                    日志信息

         Temp                  临时文件

         *Webapps        用来存放部署在容器里面的项目资源

         *work       用来存放解释jsp后的java文件

 

 

Tomcat可以找到文件资源(.html .jsp…)

Tomcat也可以找到操作资源(java代码)

V:View     视图层     Html css js

C:Controller 控制层     HttpServlet

M:Model   模型层     

                      数据处理   service

                      数据读写   dao

                      数据存储   domain

D:DataBase  Mysql

 

如何使用Tomcat

  1. 编写一个自己的类
  2. 继承Tomcat中的HttpServlet
  3. 重写一个方法void service(HttpServletRequset,HttpServletResponse) throws ServletExcption,IOException
  4. 填写web.xml配置文件  目的请求名字真是类对应关系

配置

           xx与下面对应

           包名.类名

           xx与上面对应(随便写)

           /请求名字

 

 

小知识点:发送请求的时候只写工程名字,不写资源名

Tomcat需要参考web.xml配置文件优先参考工程中的web.xml文件,如果没有的话就去找tomcat下的conf下的web.xml文件

当用(IDEA)Tomcat部署项目的时候项目会给你部署到IDEA下你的out文件下并没有给你部署到Tomcat的webapps下,IDEA觉得这样浪费时间只是给了一个映射过去但是可以自己修改部署到Tomcat的webapps中

解析JSP中的java代码后会放到Tomcat中的work内部

 

请求发送方式:

                   Get 在浏览器输入url点击回车  

                   Post  

 

JSP内置对象:

< %            %>    放在_jspServlet内部

<%=     %>            放在_jspServlet内部一般赋值

<%!     %>             放在_jspServlet外部

<%@     %>          放在作说明一般放在头部

 

JSP九个内置对象:

HttpServletRequest          request

HttpServletResponse        response

JSPWriter            out

HttpSession          session

ServletContext        application

Object               page

Exception             exception

ServletConfig          config

PageContext          pageContext

 

HttpServletRequest

         String value = request.getParameter(“key”);获取请求携带的参数

         Request.setCharacterEncoding(“UTF-8”);

         Request.setAttribute(key,Object);

         Request.getAttribute();

         RequestDispatcher rd = Request.getRequestDispatcher(“index.jsp”);

         Rd.forword(request,response);转发

 

转发和重定向的区别:

转发                                                                                    重定向

RequestDispatcher类                       HttpServletResponse类

Rd.forword(req,resp);                       resp.sendRedirect(path)

转发是在服务器内部完成的                 让浏览器再发一个请求,浏览器是知道的

浏览器不知道                                                             

Req和resp是原来的那个                   req和resp是新的

地址栏url不会跳转到其他的文件资源(**.jsp)  地址栏url会发生变化

转发只能在服务器当前的工程               可以发送给不同的服务器和新的工程

 

 

HttpSession    session

         Session.setAttribute(“”,obj);   obj = session.getAttribute(“”);

         Session.removeAttribute(key);  Enumeration = session.getAttributeNames();

Session默认存活时间1800秒=30分钟

session.setMaxInactiveInterval(int 秒);设置session的会话时长 但是session对象还在

session.invalidate();设置session死亡对象没有了

 

 

 

ServletContext servletContext = request.getServletContext();//获取ServletContext对象
String v = (String) servletContext.getAttribute("key");//得到key
servletContext.setAttribute("key",obj);//设置key
String v = servletContext.getInitParameter("key");

 


    key
    value

System.out.println(servletContext.getRealPath("/"));获取真实的路径,web部署的路径

最好的是pro.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("路径"));

 

Object  page获取当前页对象  index_jsp.java类对象

PageContext   pageContext  当前上下文对象

pageContext.setAttribute   pageContext.getAttribute      pageContext.removeAttribute

 

作用域对象

PageContext        pageContext 只有在当前页作用域内可以访问(xx_jsp.java)

HttpservletRequest  request      在一次请求范围之内

HttpSession        session             一次会话同一个人(几次请求)

ServletContext      application   全局范围,很多的session可以共享

 

JSP标签

         JSP指令标签  用户还没用的时候就已经加载了几个jsp和为一个 可能出现重名

         <%@ xxx%>      通常放在jsp头部,做说明性质的描述

         <%@page contentType=”text/html;charset=UTF-8”告知浏览器解析时遵循的规则

                   PageEncoding=”UTF-8”  告诉tomcat解析的时候遵循的字符规则

                   浏览器解析class文件写回的消息  charset àpageEncoding

                   Import=””导包

                   isErrorPage=”true”是一个错误页

                   errorPage=”xxx.jsp”出错误跳转哪个页面

    %>    

<%@ taglib%>    JSTL

<%@ include%>   用来在当前jsp中引入已经写好的资源,引入html可能乱码


   
        *.html
        UTF-8
   

Web.xml里面配置

Jsp代码标签

<%!   %>

<%=   %>

<%   %>

 

Jsp动作标签  是在用户用的时候才加载

用来替代jsp标签中java创建对象  对象的取值赋值  请求转发  携带参数

 

 

创建对象 scope是范围


property属性名字(类名)   parame是参数名字(请求的参数名字)

如果属性名字和参数名字一样的property设置为*

 

EL

${xxxScop.xxx}

${requestScop.xxx}

${sessionScop.xxx}

${param.xxx}//相当于${requestScop.xxx}接收请求携带的参数的

上述都可以用${xxx}简写来接收,但是他会扫描4个作用域速度比较低,

4大作用域(page,session,request,application)

 

 

JSTL

先导包

核心标签库:core前缀c

<%@taglib uri=”http://java.sun.com/jsp/jstl/xxx” prefix=”x”%>

   可以写字符串也可以写el表达式

        只能写表达式

        

        

  (相当于switch)

         循环的时候是个数字${i.index}

${user.name}…

函数标签库:functions 前缀 fn

<%@taglib uri=”http://java.sun.com/jsp/jstl/xxx” prefix=”xxx”%>

${fn:xxx}

 

自定义jsp标签

自定义函数

通常是带有返回值的,修饰符必须是静态的.

 

文件上传与下载

//factory.setRepository(new File());设置缓冲区路径  默认是在tomcat的tem下
//factory.setSizeThreshold(int);设置缓冲区大小 默认大小10240

//fileUpload.setFileSizeMax(long);设置单个文件上传大小
//fileUpload.setSizeMax(long);设置上传总文件大小

 

 

HttpFilter

继承HttpFilter只有在tomcat9版本才能继承

之前的版本可以实现Filter接口

重要方法: doFilter  init  destroy

三个参数:HttpServletRequest  HttpServletResponse  FilterChain

异常:ServletException  IOException

配置:只需要把servlet改为filter

执行servlet之前先过滤

session.setMaxInactiveInterval(int);设置session的最大活跃时间

 

filter拦截器,默认的是REQUEST,不会拦截forward,会拦截redirect想因为forword是在浏览器内部的请求,但是redirect是新的请求


    filter
    /*
    REQUEST//默认拦截
    FORWARD//

 

Listener监听器对象

监听域对象的产生和销毁

监听与对象的值修改删除

         Page request application session

 

Xml

1.写法

                            创建一个文件   .xml

                            建议在文件的第一行   头信息

                           

                   2.规则

                            结构良好的        有规则  标签对应

                            结构有效的        在结构良好的基础上遵循很多规则(写什么标签 名字叫什么 属性叫什么 几个 顺序)

                                     如果想要让写完的xml遵循结构有效的

                                     需要单独再写一个xml文件--->用来描述规则(类似元注解的作用)

                                     .tld   Tag  Library  Definition  用来描述标签的

                                     .dtd  Document  Type  Difinition 文档类型描述

                                     .xsd  Xml  Schema  Definition   用来描述xml文档内容

                                     .xml  eXtensible  Markup  Language   用来存储数据的文档

                   3.基本xml文件写法

                            为了让xml文件中的内容遵循某些规则

                            自定义dtd

                                     第一可以写在当前的xml文件中

                                     第二可以写在一个外部的文件中  引入

                            描述根标记

                           

                            描述根标记中的其他标记<标签>

                           

                                     类别  通常是EMPTY

                                     元素内容  (其他标签,其他标签)

                                     标签内部没有标签  是普通的文字    PCDATA

                                     PCDATA    Parsed  Character  DATA(通常用来描述标签中间的文字<>xxx<>)

                                     可以被解析的字符数据   支持实体  &xxx; 

                                               >大于   <小于   &与符号   "双引号   '单引号

                                     正常情况下 描述标签内部的子标签时候  默认认为是一个

                                     还需要在子标签基础上增加一个  对于个数的说明

                                     *符号    0-n个    ?符号  0-1个   +符号  1-n个

                                     ,符号  都有    |符号  a或b其中的一个

                            每一个标记中还需要有属性

                                   attribute list

                           

                                     通常类型的描述

                                               CDATA       Character DATA 原封不动 (通常用来描述属性名)

                                               (t1|t2|t3) 来描述

                                     通常值的描述

                                               默认值  "xxx"

                                               值的说明  (是否是必须 固定的。。)

                                               #REQUIRED必须   #IMPLIED非必需   #FIXED value固定的

                            如果想要描述实体

                           

                           

 

                           

&spring;

 

Web注解

使用在Filter,Servlet,Listener上

WebFilter,WebServler,WebListener

Exp:WebFilter(“/test”)èWeb(urlPattern=”/test”)è

WebFilter(value=”/test”)

èWebFilter(urlPattern=”/test”)èWebFilter(urlPattern={“/test”,”/xxx”,…})

 

一个请求可以省略value或者urlPattern

 

LoadOnStartUp=int值servlet对象什么时候加载

initParams为了携带信息,里面需要另外一个注解{@webInitParam(name=””,value=””)},{…}d

你可能感兴趣的:(笔记,java)