JavaSE从零开始的学习笔记(更新至MySQL)
2021-07-08 17:44:01 18 举报
AI智能生成
java笔记,每日跟随自己学习的进度进行更新,直到我die了
作者其他创作
大纲/内容
面试
方法重载和方法重写
方法重载
重载(Overload):一个类中定义多个相同名称的方法
要求
方法名称相同
参数列表不同
与访问修饰符,返回值类型无关
调用带有重载的方法时,需要根据传入的实参去找到与之匹配的方法
好处:屏蔽使用差异,灵活、方便
只是参数名称的不同并不能构成方法的重载
什么时候该用,当你发现行为是相同的,但是实现过程不同
用的最多的是构造方法,和工具类方法
方法重写/覆盖
当父类提供的方法无法满足子类需求时,可在子类中定义和父类相同的方法进行覆盖(override)
方法覆盖原则
方法名称、参数列表、返回值类型必须与父类相同,返回值类型或者是他的子类
访问修饰符可与父类相同或是比父类更广泛
方法覆盖的执行
子类覆盖父类方法后,调用时优先执行子类覆盖后的方法
方法重写是带有约束的
方法名被约束了,参数列表、返回值也被约束了
保证了所有子类都可以使用相同的方法
保证了所有子类都可以使用相同的方法
1.8新特性
在局部内部类中使用局部变量,该变量必须为常量
jdk1.8及以后java默认给使用在局部内部类的变量加上final关键字
jdk1.8及以后java默认给使用在局部内部类的变量加上final关键字
this与super
super关键字
在子类中,可以通过super.的形式访问父类的属性和方法,可解决一定的属性遮蔽、方法覆盖后的父类成员调用问题
super()或super(实参)表示在子类代码的首行调用父类的构造方法
在子类的方法中使用super.的形式访问父类的属性和方法
注意
如果在子类构造方法中,没有显示定义super()或super(实参),则默认提供super()
同一个子类构造方法中,super()、this()不可同时存在
this 关键字
this 代表”当前实例“,即时模板中的当前对象,模板服务于哪个对象,this就指向哪个对象
this 第一种用法
调用本类中的实例属性、实例方法如:this.name this.sayHi()
this 第二种用法
调用本类中的构造方法 如:this();this(形参);
必须在构造方法的首行(也就是只可以有一个),仅可在构造方法中而不能在普通方法中
new String()创建了几个对象
final、finalize、finally区别
final修饰类,方法,常量
finalize垃圾回收的调用方法,用于标记对象是否进入垃圾回收队列
finally不管是否出现异常最终都是执行,异常处理中使用,基本用于资源的回收、
常用类
内部类
概念:在一个类的内部,在定义一个完整的类
特点
1.编译之后可生成独立的字节码文件,名字为类名$其他名字
2.内部类可直接访问外部类的私有成员,而不破坏封装
3.可以为外部类提供比压迫的内部功能组件
分类
成员内部类
概念:在类的内部定义,与实例变量、实例方法同级别的类
属于外部类的一个实例部分,创建内部类对象必须依赖外部类对象,不能脱离外部类对象独立存在
语法 外部类类名 变量名= new 外部类类名()
外部类.内部类 变量名 = 外部类变量名.new 内部类名()
外部类.内部类 变量名 = 外部类变量名.new 内部类名()
但外部类、内部类存在重名属性时,有限访问内部类属性,同过外部类类名.this.外部类实例属性
成员内部类不可以定义静态成员
内部类是非静态的,除了要依靠外部类实例,还要依赖内部类实例,静态常量是不要类实例的,在编译时就分配好了内存,且final类型可以离开实例存活一段时间。所以非静态内部类只能有静态的final型常量。
成员内部类可以使用三种修饰符,
静态内部类
概念:在类的内部定义,与外部类、外部类的静态属性,静态方法等同级别
静态内部类可以直接使用外部类的静态成员,而不能直接使用外部类的非静态成员
如果需要使用,可以在静态内部类实例化外部类,进而用外部类类名.外部类成员来使用外部类的成员
如果需要使用,可以在静态内部类实例化外部类,进而用外部类类名.外部类成员来使用外部类的成员
语法:静态类类名 变量名 = new 外部类类名.内部类类名()
实例化之后可以用静态类类名.静态类成员;来使用其属性和方法
可以当作写在内部的外部类
可以当作写在内部的外部类
局部内部类
概念:定义在外部类的方法中,作用范围和创建对象的范围仅限当前方法中
局部内部类访问外部类局部变量时,因无法保障变量的生命周期与自身相同,所以修饰为final
作用:隐藏类的信息、限制类的使用范围
匿名内部类(局部内部类的简化版)
没有类名的局部内部类
必须继承一个父类或实现一个接口
定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
优点:减少代码量,书写的思路流畅,更符合程序员的书写规律
缺点:可读性较差
object类
概念
超类、基类,所有类的直接或间接父类,位于继承树的最顶层
任何类,如果没有书写extends显示继承某个类,都默认直接继承object类,否则为间接继承
object类中所定义的方法,是所有对象都具备的方法
object类型可以存储任何对象
作为参数,可接受任何对象
作为返回值,可返回任何对象
常用方法
public final Class<?>getClass(){}
返回引用中存储的实际对象类型,
通常应用于判断两个引用中实际存储对象类型是否一致
通常应用于判断两个引用中实际存储对象类型是否一致
public int hashCode(){}
一个对象的整数表现形式(整数类型的名字)
返回该对象的十进制哈希码值即哈希算法根据对象的地址
或字符串或数字计算出来的int类型的值
哈希码并不唯一,可保证相同对象返回相同哈希码,尽量保证不同对象返回不同哈希码
返回该对象的十进制哈希码值即哈希算法根据对象的地址
或字符串或数字计算出来的int类型的值
哈希码并不唯一,可保证相同对象返回相同哈希码,尽量保证不同对象返回不同哈希码
public String toString(){}
返回该对象的字符串表示(表现形式)
可以根据程序需求覆盖该方法,比如:展示对象的各个属性值
public boolean equals(object obj){}
默认实现this == obj,比较两个对象地址是否相同
可以进行覆盖比较两个对象的内容是否相同
覆盖equal的顺序
比较两个引用是否指向同一个对象(即判断地址是否相同)
判断obj(但是通过下一步可以排除判断obj为空的过程)
判断两个引用指向的实际对象类型是否相同(通过instanceof)
强制类型转换
依次比较各个属性值是否相同
protected void finalize()throws Throwable//了解,面试题中可能有坑
当对象被判定为垃圾对象时,由jvm自动调用此方法,用以标记垃圾对象,进入回收队列
垃圾对象:即没有有效引用指向此对象时,为垃圾对象
垃圾回收:由gc销毁垃圾对象,释放数据存储空间
自动回收机制:jvm的内存耗尽,一次性回收所有的垃圾对象
手动回收机制:使用system.gc()通知jvm执行垃圾回收
包装类
概念:八个基本类型各自的对象(引用数据类型)
八种基本类型不是对象,但是八种基本类型的包装类都是对象,符合了万物皆对象的概念
杂类
六种数字型的包装类父类都是number,父类提供了六种转型的方法
包装类型里有封装了对印的基本类型、赋值取值的基本方法,常用的一些方法(比如转型)
object可统一所有数据,包装类的默认值是null
类型转换与装箱、拆箱
8种包装类提供不同类型间的转换方法:
Number父类中提供的6个共性方法
parse数据类型()静态方法
valueOf()静态方法
Number父类中提供的6个共性方法
parse数据类型()静态方法
valueOf()静态方法
注意:需要保证类型兼容,否则抛出NumberFirmatException异常
character 没有parse方法
character 没有parse方法
jdk5.0之后,自动装箱、拆箱。基本数据类型和包装类自动转换
valueOf:基础数据类型转换为包装类
基础数据类型Value:包装类转回基础数据类型
parse基础数据类型:字符串转化为基础数据类型
valueof转换为引用数据类型
基础数据类型与包装类进行运算判断时,永远都是包装类自动拆箱为基础数据类型进行运算或者判断
方便之处
可以被object统一数据,且每一个都是对象其中还有很多方法可以使用
整数缓冲区
Java预先创建了256个常用的整数包装类型对象,在实际应用当中会对已创建的对象进行复用
String
字符串是常量,创建之后不可以改变
字符串字面值存储在字符串池中可以共享
String s = "hello";产生一个对象,字符串池中存储
String s = new String("hello")产生两个对象,堆中池中各存储一个
常用方法
xx.charAt(下标),把字符串对应下标的字符提取
xx.contains("字符串"),判断字符串内是否有包含你查询的字符串。返回布尔值
判断用户名黑名单
xx.toCharAt,把字符串转为字符数组
xx.indexOf(字符串),找到字符串中对应字符串的下标位置(输入多个字符会把其当成整体看待)
xx.lastIndexOf,从后向前找
xx.length(),获取字符串长度
与length的区别一个属性一个是方法,带有小括号的都是方法
xx.trim(),去除字符串两边的空格,字符串中间的无效
判断用户名黑名单是否为空
xx.toUpperCase(),把字符串转大写
xx.toLowerCase(),把字符串转小写
xx.endsWith(字符串),判断字符串是否以字符串结尾
判断文件类型
xx.startsWith(字符串),判断字符串是否以字符串开头
xx.replace(字符串1,字符串2),前面是要被替换的字符串,后面是替换进去的字符串
xx.split(字符串):根据字符串做拆分,[,]+正则表达式,根据一个或多个,进行拆分
xx.substring(下标)从指定下标开始,包括下标
xx.substring(开始下标,结束下标)截断,包含前下标不包含后下标
xx.substring(开始下标,结束下标)截断,包含前下标不包含后下标
String重写了equals方法,只比较字面值,严格区分大小写
equalsIgnoreCase则不区分daxiaoxie
equalsIgnoreCase则不区分daxiaoxie
可变长字符串
StringBuilder(jdk5.0推出,速度快,线程不安全建议首选)
StringBuffer(jdk1.0推出,速度慢,线程安全)
字符串相加就是自动利用Stringbuilder拼接新开空间,如果是字面值相加则就不会新开空间直接是字面值拼接
BigDecimal
在java.math中
最好用字符来创建,因为字符创建的才是最精确的
创建语法:BigDecimal 变量名 =new BigDecimal(值)
+-*/
+:add
-:subtract
*:multiply
/:divide
进行除法时,如果无法除尽可以指定精确到几位以及按照自己制定的取舍模式
BigDecimel(除的数,取小数点后几位,四舍五入为UP)
日期类型
日期类型Date
不管什么语言,不管什么数据库都会有毫秒这个单位
日期类型Calender
calender是一个抽象类,无法被实例化,但是它提供了一个方法getinstance
来获得一个calendar对象得到的calendar由当前时间初始化
来获得一个calendar对象得到的calendar由当前时间初始化
获取时间
因为国内外时间规定不同,存减取加
4
SimpleDateFormat
通过声明new SimpleDateFormat(格式)来使用各种方法进行符合格式的字符串与日期的互相转换
format(),日期转换为字符串
parse(),字符串转日期
集合
概念:对象的容器,定义了对多个对象进行操作的常用方法,可实现数组的功能
与数组的区别
数组长度固定,集合长度不固定
数组可以存储基本数据类型和引用数据类型,集合只能存储引用数据类型
位置
java.util.*包里面
collection集合
collection父接口:该体系结构的根接口,
代表一组对象称为集合,每个对象都是该集合的元素
代表一组对象称为集合,每个对象都是该集合的元素
子接口为list与set
list接口
特点:有序、有下标、元素是可重复的
继承父接口提供的共性方法,同时定义了一些独有的与下标操作相关的操作方法
实现类
JKD8的Arraylist,
实际初始长度是0
首次添加元素时,需要实际分配数组空间,执行数组扩容操作
真正像数组中插入数据
赋值add方法,取值1:foreach遍历取值,
取值2:while(hasNext)循环,hasNext判断当前是否为有效元素,next()取值之后指针游标往下移动
取值2:while(hasNext)循环,hasNext判断当前是否为有效元素,next()取值之后指针游标往下移动
Arraylist没有自身好用的独有方法,所以一般arraylist都是使用list接口来接受实例
方便进行多态和替换
方便进行多态和替换
Arraylist源码分析
1.Objecr[] elementData//Arrayslist底层源码使用数组进行数据的保存
2.DEFAULT_CAPACITY =10//默认的容量可以存储多少个值
3.刚开始创建的时候,长度为0
4.当arraylist使用.add()方法进行存值的时候,该方法内会有进行扩容的判断
第一次存值默认扩容10,之后每次扩容1.5倍
查询快,增删慢
vector
与arraylist一样,区别在于一个快一个慢线程安全与不安全
linkedlist
独有方法addlast,addfrist,getlast,geifrist,存取首位值
poll()(弹栈方法)
取第一个值之后把值拿走了,集合里对应的值也被删掉了
以链表形式存储
查询慢增删快
set接口
set接口的特点:无序、无下标,元素不可重复
当插入新元素时,如果新元素与已有元素进行equals比较,结果为true时,则拒绝新元素的插入
当插入新元素时,如果新元素与已有元素进行equals比较,结果为true时,则拒绝新元素的插入
实现类
hashset
1.基于hashcode实现元素不重复
2.当存入元素的哈希码相同时会调用==或.equals来进行确认,结果为true拒绝元素存入
存储方式数组加单向链表
可以通过重写hashcode与equals来重新更改判内容重复
linkedHashSet
链表实现的hashset,按照链表进行存储,
即可保留元素的插入顺序,但是没有下标
即可保留元素的插入顺序,但是没有下标
TreeSet
基于排列顺序实现元素不重复
实现了sortset接口,对集合元素自动排序
元素对象的类型必须实现comparable接口,指定排序规则
通过conpareto的方法返回作为0确定是否为重复元素
底层为红黑树
方法全部都是继承collection中的方法
collection父接口
特点:代表一组任意类型的对象,无序、无下标
方法
boolean add(object obj):添加一个对象
add all(cikection c)将一个集合中的所有对象添加到此集合中
clear()清空此集合中所有对象
contains(object obj)检查此集合是否包含obj对象
就是equals比较地址
containsall,一样遍历再用contains比较
size()集合的元素个数而不是长度
equals(object o)比较此集合是否与指定对象相等
isempty()判断此集合是否为空
remove(object o )在此集合中移除o对象
Object[] toArray()将此集合转换成数组
removeall(colection c),删除集合中与c相同的数据
iterator()获取迭代器Iterator类型接口接收
迭代器每次使用都需要迭代器名=集合名.iterator初始化
Map父接口
特点:称为映射存储一对数据(Key-Value),无序,无下标,键不可重复,值可以重复
当map的key值重复就会出现value值被覆盖的情况===>修改
hashmap算法
拿到任何一个对象,通过hash(key)做运算,key>>>16(除以16),
只可能的到0-15之间的一个数组作为插入的数组下标
只可能的到0-15之间的一个数组作为插入的数组下标
hashtable
hashmap的线程安全版本
properties
hashtable的子类,主要用于存储key和value都是字符串的情况
常在读取配置文件之后,保存文件中的键值对。反射jdbc
常在读取配置文件之后,保存文件中的键值对。反射jdbc
treemap
自动对key做排序,根据compareto的返回值去重
map集合的遍历
keyset():获得map集合中所有的键。返回的时set集合
values():获得map集合中所有的值。返回的是collection集合
enteyset():返回的是map.entry(node)包含了getkey和getvalue。
直接输出是调用tostring打印键值对
直接输出是调用tostring打印键值对
泛型
泛型集合
概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致
特点:编译时即可检查,而非运行时抛出异常
访问时,不必类型转换(拆箱)
访问时,不必类型转换(拆箱)
泛型类创建对象时指明,泛型接口在实现接口时指明,都叫实例泛型(创建对象实现接口指明的泛型)
静态泛型加载方法上static后面添加
public static <T extends Number> void method(T t)//只接受数字
public static<T extends Animal> void method( T t)//只接受animal类型或其子类
public static<T extends Animal> void method( T t)//只接受animal类型或其子类
概念
java泛型是jdk1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递
常见形式有泛型类、泛型接口、泛型方法
语法<T...>T为类型占位符
泛型不可以被实例化
高级类别的知识,熟练应用需要时间、经验的积累(常用名称:Eelement/T=Type/K=Key/V=Value)
约束-规范类型
使用泛型的场景
定义泛型
实例泛型
类:创建对象时,为类所定义的泛型;进行参数化赋值
接口:实现接口时,为接口所定义的泛型,进行参数化赋值
静态泛型
定义在方法的返回值前面:<T><T extends Comparable<T>>可应用在形参列表、
返回值类型两种常见、不单单可以规范化泛型还可以语义化返回值
返回值类型两种常见、不单单可以规范化泛型还可以语义化返回值
定义在方法的形参列表中<?>、<?extends Object>不支持使用&只能应用在形参列表上,规范泛型
collections工具类
概念:集合工具类定义了除了存取以外的集合常用方法
常用方法
publicstatic<TextendsComparable<?superT>>voidsort(List<T>list)//排序
要求必须实现comparable,必须可与自身类型比,以及父类类型比
要求必须实现comparable,必须可与自身类型比,以及父类类型比
publicstaticvoidreverse(List<?>list)//反转、倒置元素
publicstaticvoidshuffle(List<?>list)//随机重置顺序配合poll弹栈可以模拟抽奖
throwable(可抛出的异常)
异常Exception
异常的概念
程序在运行过程中出现的特殊情况(报错)
异常处理的必要性:任何程序都可能存在大量未知问题、错误;
如果不对这些问题进行正确处理,则可能导致程序的中断,造成不必要的损失
如果不对这些问题进行正确处理,则可能导致程序的中断,造成不必要的损失
异常的分类
Throwable:可抛出的,一切错误或异常的父类,位于Java.lang包中
Error:JVM、硬件、执行逻辑错误,不能手动处理
Exception:程序在运行和配置过程中产生的问题,可处理
RuntimeException:运行时异常,可处理,可不处理
CheckedException:受查异常,必须处理,不处理编译不通过
异常的产生
自动抛出异常:当程序在运行时遇到不符合规范的代码或结果时,会产生异常
手动抛出异常:throw new 异常类型("实际参数")
一旦产生异常结果:相当于执行return语句,导致程序因异常而终止
异常的传递
按照方法调用链反向传递,如果最终都没有处理异常,
最终交由我们的jvm进行默认异常处理(打印堆栈跟踪信息)
最终交由我们的jvm进行默认异常处理(打印堆栈跟踪信息)
受查异常:throws声明异常,生命位置:修饰在方法参数列表的后端
运行时异常:因其可处理,可不处理无需声明
异常的处理
I.try{
//可能出现异常的代码
}catch(Exceptione){
//捕获异常后,对异常处理的相关代码。
处理方案:1、自定义2、printStackTrace();
3、getMessage();
}finally{
//无论是否出现异常,都需要执行的代码。常用于释放资源.
}
//可能出现异常的代码
}catch(Exceptione){
//捕获异常后,对异常处理的相关代码。
处理方案:1、自定义2、printStackTrace();
3、getMessage();
}finally{
//无论是否出现异常,都需要执行的代码。常用于释放资源.
}
常见异常处理结构
try{}catch(){}
try{}catch(){}catch(){}
try{}catch(){}finally{}
Try{}catch(){}catch(){}finally{}
try{}finally{}
注意:在多重catch下,遵循从子到父的顺序,父类异常在最后捕获
最好按照精确的异常捕获来做,但是在多重catch最后要加上exception
自定义异常
继承Exception(受查异常)或Exception的子类
常用runtimeexception(运行时异常)
常用runtimeexception(运行时异常)
必要提供的内容
无参构造方法
string message参数的构造方法。定义异常原因信息
通过调用父类的构造
异常方法覆盖
方法名、参数列表、返回值类型必须与父类相同
子类的访问修饰符和父类相同或比父类更宽泛
子类中的方法,不能抛出比父类更宽泛的异常
扩充
方法执行中字节码操作指令
反编译:javap-verbose文件名称(是.class)>自定义文件名称.bytecode
异常处理最大的作用就是不让我的程序终止以至于造成更大的损失
错误Error
jvm、硬件、执行逻辑错误,不能手动处理
多线程
程序是啥
程序是静止的,只有真正运行时的程序才被称为进程
单核CPU在任何时间点上,只能运行一个程序;宏观并行、微观串行
什么是线程
线程又称轻量级进程,程序中的一个顺序控制流程,同时也是cpu的基本调度单位。
进程由多个线程组成,彼此间完成不同的工作,交替执行称为多线程
进程由多个线程组成,彼此间完成不同的工作,交替执行称为多线程
cpu类似公司,部门类似进程,线程类似部门的员工,时间片类似公司分配给部门,
部门交给员工的任务时间,员工就开始打架抢时间片,任务做完就会自杀,
在java中线程争取时间片采用抢的形式,实际工作的是线程
部门交给员工的任务时间,员工就开始打架抢时间片,任务做完就会自杀,
在java中线程争取时间片采用抢的形式,实际工作的是线程
main方法就是主线程,同过其他的方法可以创建子线程,与主线程并发执行
java是抢占式的资源,a资源多a先运行,然后b把a资源抢了比a资源多b就运行循环往复
进程与线程的区别
进程是操作系统分配资源的基本单位,而线程是CPU的基本调度单位
一个程序运行后至少有一个进程
一个进程可以包含多个线程,但是至少需要有一个线程
进程间不能共享数据短地址,但同进程的线程之间可以
线程的组成
所有线程都具有基本的组成部分
cpu时间片:操作系统会为每个线程分配执行时间。
运行数据(决定线程操作的数据)
堆空间:存储线程需要使用的对象,多个线程可以共享堆中的对象
栈空间:存储线程需使用的局部变量,每个线程都有独立的栈
线程的逻辑代码(线程做的事)
线程的创建
第一种继承thread
继承thread类,重写run方法,run方法内就是子线程运行的内容
调用采用.start()方法启动子线程的调用
如果直接.run()则主线程直接运行
thread.currentthread().getid()//获取线程id
thread.currentthread().getname()//获取线程名
thread.currentthread().getname()//获取线程名
子线程因为继承了thread所以可以直接使用getid与getname方法
第二种实现接口runnable
实现runnable接口,重写run方法,run方法内就是子线程运行的内容
接口里面只有run方法,所以只有thread类能够启动线程
实例化runnable的实现类,创建thread对象,
提供runnable的实现给予thread去启动线程执行。
即把runnable的实现类当参数传进thread
提供runnable的实现给予thread去启动线程执行。
即把runnable的实现类当参数传进thread
好处不占用继承的名额
且可以做到数据的共享
还可以使用匿名内部类
且可以做到数据的共享
还可以使用匿名内部类
如果这个线程做的事情只有使用一次,
可以直接使用匿名内部类来实现,写法会更简洁
可以直接使用匿名内部类来实现,写法会更简洁
线程的基本状态
New初始状态
线程对象被创建,即为初始状态,
只在堆中开辟内存,与常规对象无异
只在堆中开辟内存,与常规对象无异
调用start()后变成ready就绪状态
等待OS(系统)选中并分配时间片
OS选中后变为Running运行状态
时间片到期后变为Ready就绪状态
时间片到期后变为Ready就绪状态
限期等待
sleep(x)
timed waiting(限期等待),等待完毕回到就绪状态
无限期等待
join()
waiting(无限期等待)满足条件回到就绪状态
blocked阻塞状态
线程进入运行状态没有锁标记进入不了代码块
进入阻塞状态等待获取锁标记,获得锁标记时
回到就绪状态等待时间片
进入阻塞状态等待获取锁标记,获得锁标记时
回到就绪状态等待时间片
run()结束变为Terminated终止状态
主线程main()或独立线程run()结束
进入终止状态,并释放持有的时间片
进入终止状态,并释放持有的时间片
注意:jdk5开始就绪与运行状态统称为runnable
在给定时间点上,线程只能处于一种状态
线程的基本方法
都是与线程暂停有关
都是与线程暂停有关
休眠sleep(毫秒)
当前线程主动休眠毫秒
当直接类名点sleep时,代码属于那个线程
哪个线程就睡一会
哪个线程就睡一会
放弃yield()
当前线程主动放弃时间片,回到就绪状态,竞争下一次时间片
结合join()
将发起点的线程加入到所在线程中等待发起点的线程结束后再执行
允许其他线程加入当前线程中并优先执行
加入当前线程,他会阻塞当前的线程直到自身线程任务完成
括号可以传递参数,表示等待运行时间
join方法必须在线程start方法调用之后才有意义
多个join运行则使用join的抢,当前线程不会抢
优先级别设置,只是几率(垃圾)
setpriority,默认级别5上下限为1-10
线程的安全问题
临界资源:被多线程共享的对象,
一次仅允许一个线程使用才可保证其正确性
一次仅允许一个线程使用才可保证其正确性
原子操作:不可分割的多个步骤,
被视作一个整体,其顺序和步骤不可打乱或缺少
被视作一个整体,其顺序和步骤不可打乱或缺少
关于共享数据的操作都是原子操作
线程不安全:当多线程并发访问临界资源时,
如果破坏原子操作,可能会造成数据不一致
如果破坏原子操作,可能会造成数据不一致
解决线程不安全方法
同步代码块(锁)
可以新建一个object对象作为标记
每个对象都有一个互斥锁标记,用来分配给线程
只有拥有对象互斥锁标记的线程,才能进入
对该对象加锁的同步代码块
对该对象加锁的同步代码块
线程退出同步代码块时才会释放相应的锁标记
synchronized(临界资源对象){对临界资源加锁
代码原子操作
}
代码原子操作
}
同步方法
synchronized加在返回值前面
整个方法都被锁住,不管静态还是实例方法,只有一个进程可以进来
锁类型
私有锁
新建一个私有对象作为锁对象
对象锁
括号填this当前对象作为锁
类锁
类名.class 作为条件
互斥关系不一样
同步规则
只有在调用包含同步代码块的方法或同步方法时,才需要对象的锁标记
如调用不包含同步代码块的方法或普通方法时,则不需要锁标记,可直接调用
死锁
产生原因
当第一个线程拥有a对象锁标记并等待b对象锁标记
同时第二个线程拥有b对象锁标记,并等待a对象锁标记时
产生死锁
同时第二个线程拥有b对象锁标记,并等待a对象锁标记时
产生死锁
一个线程可以同时拥有多个对象的锁标记,
当线程阻塞时,不会释放已经拥有的锁标记,
由此可能造成死锁
当线程阻塞时,不会释放已经拥有的锁标记,
由此可能造成死锁
解决方法:线程通信
等待
public final void wait()
public final void wait(long timeout)
必须在对obj加锁的同步代码块中。在一个线程中调用obj.wait()时
此线程会释放其所拥有的所有锁标记,同时此线程因obj处在无限期等待的状态中
释放锁进入等待队列
此线程会释放其所拥有的所有锁标记,同时此线程因obj处在无限期等待的状态中
释放锁进入等待队列
通知
public final void notify()
public final void notifyall()
必须在对obj加锁的同步代码块中。从obj的waiting中释放一个或全部线程
对自身没有任何影响
对自身没有任何影响
生产者与消费者
形成死锁的四个条件
互斥
占有且等待
不可抢占
循环等待
生产者与消费者
高级多线程
线程池
概念
现有问题
线程是宝贵的内存资源、单个线程约占1mb空间
过多分配容易造成内存溢出
过多分配容易造成内存溢出
频繁的创建及销毁线程会增加虚拟机回收频率、资源开销,造成程序性能下降
线程容器,可设定线程分配数量上限
将预先创建的线程对象存入池中,并重用线程池中的线程对象
避免频繁的创建及销毁
原理
将任务提交给线程池,由线程池分配线程、运行任务
并在当前任务结束后复用线程
并在当前任务结束后复用线程
获取方法
常用的线程池接口和类(所在包java.util.concurrent)
Executor:线程池的顶级接口,只能使用runnable
ExecutorService:线程池接口,可通过submit(Runnable task)提交任务代码
不仅支持父类接口的runnable还支持功能更强大的callable
不仅支持父类接口的runnable还支持功能更强大的callable
Executors工厂类:通过此类可以获得一个线程池
通过newfixed thread poll(int nthreads)获取固定数量的线程池。
参数:指定线程池中线程的数量
参数:指定线程池中线程的数量
通过newcachedthreadpool();获得动态数量的线程池,
如不够则创建新的,没有上限,更灵活但不适合资源过少的场景
如不够则创建新的,没有上限,更灵活但不适合资源过少的场景
callable 接口
public interface Callable<V>{
public V call() throw Exception
}
public V call() throw Exception
}
jdk5加入,与Runnable接口类似,实现之后代表一个线程任务
callable具有泛型返回值、可以声明异常
Future接口
概念:异步接受ExecutorService.submit()所返回的
状态结果,当中包含了call()的返回值
状态结果,当中包含了call()的返回值
方法 : V get()以阻塞形式等待Future中的异步处理结果(call()的返回值)
异步与同步
同步
形容一次方法调用,同步一旦开始,调用者必须等待该方法返回,才能继续
单条执行路径
异步
形容一次执行方法调用,异步一旦开始,像是一次消息传递,调用者告知后立刻返回,二者竞争时间片,并发执行
多条执行路径
lock接口与其实现类
JDK5加入,与synchronized比较,显示定义,结构更灵活
提供更多实用性方法功能更强大,性能更优越
重入锁
reentrant lock
lock接口的实现类,与synchronized一样具有互斥锁功能
Lock locker = new reentrantlock()
locker.lock()
locker.unlock()
locker.lock()
locker.unlock()
读写锁
Reentrantreadwritelock
一种支持一写多读的同步锁,读写分离
可分别分配读锁、写锁
可分别分配读锁、写锁
支持多次分配读锁,多个读锁操作可以并发执行
互斥规则:写-写:互斥、阻塞
读-写:互斥、读阻塞写,写阻塞读
读-读:不互斥、不阻塞
在读操作远远大于写操作的环境中,可以保障线程安全的情况下提高运行效率
读-写:互斥、读阻塞写,写阻塞读
读-读:不互斥、不阻塞
在读操作远远大于写操作的环境中,可以保障线程安全的情况下提高运行效率
线程安全的集合
常用集合
IO流
什么是流
内存与存储设备之间传输数据的通道
水借助管道传输;数据借助流传输
即流就是通道
流的分类
按方向分
输入流:将存储设备中的内容读入到内存中
输出流:将内存中的内容写入到存储设备中
按单位
字节流:以字节为单位,可以读写所有数据(包括图片视频)
字符流:以字符为单位,只能读写文本数据(一字节等于二字符,所以读文本数据快)
按功能
节点流:具有实际传输数据的读写功能
过滤流:在节点流的基础之上增强功能
字节流
父类(抽象类)
inputstream:字节输入流
read
available获取当前流读取了多少可读的字节数
output steam:字节输出流
write
构造方法重载第二参数布尔值默认为flase(覆盖内容)
改成true则文件内容追加
改成true则文件内容追加
文件不存在会自动创建,文件夹不存在则报错
子类字节节点流
file output steam:write(btye[] b)
一次写多个字节将b数组中所有字节
写入输出流
一次写多个字节将b数组中所有字节
写入输出流
fileinputstream:read(byte[] b)
从流中读取多个字节,将读取内容存入b数组
返回实际读到的字节数;如果达到文件尾部返回-1
从流中读取多个字节,将读取内容存入b数组
返回实际读到的字节数;如果达到文件尾部返回-1
注意:所有的流有开就有关,即tryfinally必须要有关
.close关闭流方法
.close关闭流方法
字节过滤流
缓冲流buffered开头的outin
提高io效率,减少访问磁盘的次数
数据存储在缓冲区中,flush是将缓存区
的内容写入文件中,也可以直接close
的内容写入文件中,也可以直接close
对象流object开头的outin
增强了缓冲区功能
增强了读写8种基本数据类型和字符串功能
增强了读写对象的功能
readobject
writeobject
writeobject
对象序列化
细节:对象到硬盘序列化,反之反序列化
对象必须转成二级制,机器码或者.class等计算机可以看懂的
需要实现标识性接口serializeable才可以序列化
对象流不能追加,想让它正常追加只能重写
也可以在读取后的数据进行覆盖
也可以在读取后的数据进行覆盖
必须保证其所有属性均可序列化
tansient修饰为临时属性,不参与序列化
读取到文件尾部标志:java.io.EOFException
基础的字符编码
ISO-8859-1收录出ascii外,还包括西欧、希腊语、泰语等
utf-8
gb2312简体中文
gbk简体中文扩充
big5台湾,繁体中文
注意如果工作前端传数据过来是乱码,先检查字符编码
字符流
父类抽象类
reader:字符输入流
writer:字符输出流
字符节点流
前面加file
只要是文本文件优先使用字符流,如果是图片
视频音频等等全部都要使用字节流’
视频音频等等全部都要使用字节流’
字符过滤流
与字节过滤流一模一样
while判断从-1改成null
支持输入换行符,可以一次写一行读一行
字符打印流
printwriter:输出流
封装了print()/println()方法,支持写入后换行
支持数据原样打印
字符节点流
input stream reader
outputsteamwriter
File类
概念:代表物理盘符中的一个文件或者文件夹
方法
createNewFile创建一个新文件
MKdir创建一个新目录
Delete删除文件或空目录
Exists判断File对象所对象所代表的对象是否存在
getAbsolutePath获取文件的绝对路径
getName取得名字
getParent获取文件目录所在目录
isDirectory是否是目录
isFile是否是文件
length获得文件的长度
listFiles列出目录中的所有内容
renameTo修改文件名为
FileFilter接口
子主题
IO流思路
多个服务端可以多个线程,每个功能不同的服务端接口都不一样
网络编程
什么是网络
由点和线构成,表示诸多对象之间的互相联系
什么是计算机网络
为实现资源的共享和信息传递,通过通信线路连接起来的若干主机(host)
最重要的就是资源共享和信息传递
互联网(internet)点与点相连
万维网(www-worldwideweb)端与端连接
物联网(lot-internetofehings)物与物相连
网络编程:让计算机与计算机之间建立连接、建立通信
网络模型
osi
第一层:物理层,设备之间的数据通信提供传输信号和物理介质(双绞线、光导纤维)
第二层:链路层:在物理层上,通过规程和协议(差错控制)来控制传输数据的正确性(mac)
第三层:网络层:负责定义了能够标识所有网络节点的逻辑地址(IP地址)
第四层:传输层负责是否先择差错恢复协议,数据流重用,错误顺序重排(tcp、udp)
第五层:会话层负责使应用建立和维持绘画,使通信在失效时继续恢复通信(断点续传)
第六层:表示层负责定义转换数据格式及加密、允许选择以二进制或ASCII格式传输
第七层:应用层负责文件访问和管理、可靠运输服务、远程操作服务(http、ftp、smtp)
tcp/ip协议
五六七合并应用层
第四层应用层负责传送各种最终形态的数据,是直接与用户打交道的层,典型协议是HTTP/ftp等
第三层传输层负责传送文本数据,主要协议是TCP、udp协议
第二层网络层负责分配地址和传送二进制数据、主要协议是ip协议
一二合并网络接口层
接口层负责建立电路连接,是整个网络的物理基础,典型的协议包括以太网ADSL等
tcp协议tranmissioncontrolprotocol
UDP协议:UserDatagramProtocol
UDP协议:UserDatagramProtocol
传输控制协议
是一种面向连接的、可靠的、基于字节流的传输层通信协议
数据大小无限制。建立连接的过程需要三次握手,断开连接的过程需要四次挥手
数据大小无限制。建立连接的过程需要三次握手,断开连接的过程需要四次挥手
用户数据报协议
是一种无连接的传输层协议,提供面向事物的简单不可靠信息传送服务,每个包的大小64kb
IP协议:Internet Protocol Address
分配给互联网设备的数字标签(唯一标识)
Ip地址分两种
ipv4
4字节32位整数,分成四段8位的二进制数,每8位之间用圆点隔开,每8位整数可以转换为一个0-255的十进制整数
D.D.D.D例如255.255.255.255
D.D.D.D例如255.255.255.255
分类
A类政府机构:1.0.0.1-126.255.255.254
B类中型企业:128.0.0.1-191.255.255.254
C类个人用户:192.0.0.1-223.255.255.254
D类用于组播:224.0.0.1-239.255.255.254
E类用于实验:240.0.0.1-255.255.255.254
回环地址:127.0.0.1,指本机,一般用于测试使用
查看ip命令:ipconfig
测试ip命令:ping D.D.D.D
ipv6
16字节128位整数,分成8段16进制数,每16位之间用圆点隔开,每16位整数可以转换为0-65535的十进制数
X.X.X.X.X.X.X.X例如FFFF.FFFF.FFFF.FFFF.FFFF.FFFF.FFFF.FFFF
X.X.X.X.X.X.X.X例如FFFF.FFFF.FFFF.FFFF.FFFF.FFFF.FFFF.FFFF
port端口号
在通信实体上进行网络通讯的程序的唯一标识
端口分类
公认端口:0-1023
注册端口:1024-49151
动态或私有端口:49152-65535
常用端口
MySQL:3306
Oracle:1521
tomcat:8080
SMTP:25
web服务器:80
ftp服务器:21
inet address
概念:表示互联网协议(IP)地址对象,封装了
基于tcp的网络编程
socket编程
socket(套接字)是网络中的一个通信节点
分为客户端socket与服务器sever socket
通信要求:IP地址+端口号
开发步骤
建立通信连接(会话)
创建sever socket,指定端口号
调用accept等待客户端接入
客户端请求服务器
创建socket,指定服务器ip+端口号
使用输出流,发送请求数据给服务器
使用输入流,接受响应数据到客户端
服务器响应客户端
使用输出流,发送请求数据给客户端
使用输入流,接受响应数据到服务器
反射
什么是类对象
概念:基于某个类new出来的对象,也称为实例对象
类加载的产物,封装了一个类的所有信息(类名、父亲、接口、属性、方法、构造方法)
获取类对象的三种方法
1.通过类的对象获取类对象
Class c = 类的实例.getClass()
Class c = 类的实例.getClass()
2.通过类名获取类对象
Class c = 类名.Class
Class c = 类名.Class
3.通过静态方法获取类对象
Class c = Class.ForName(全限定名("包名.类名"))
Class c = Class.ForName(全限定名("包名.类名"))
常用方法
getName获取全限定名
getpackage获取包名
getsuperclass获取父类名字
getfeld获取所有可见属性
获取所有公开的构造方法constructor<?>[] x = class.getconstructors()
获取所有的包括非公开使用getdeclareconstructors方法
获取所有的包括非公开使用getdeclareconstructors方法
获取指定的构造方法,class.getconstructor(参数)
调用无参构造方法获取对象object、 newinstance = constructor.newinstance()
获取类中所有的公开方法,包括父类的方法methon[] methods=class.getmethods()
非公开使用getdeclaredmethods()
非公开使用getdeclaredmethods()
获取指定方法method method = class.getmethod(方法名)
调用非静态方法需要使用invoke(对象,实参)
调用静态方法需要使用invoke(null,实参)
调用静态方法需要使用invoke(null,实参)
获取类中的公开属性field[] fields = class.getfields();
反射可以获取类里面所有的东西,不管私有还是公开
设计模式
什么是设计模式
一套被反复使用、被多数人知晓、经过分类编目的、代码设计经验的总结
可以简单理解为特定问题的固定解决方法
好处
使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码的可靠性、重要性
在Gof的设计模式书中描述了23种设计模式
典型两个
工厂设计模式
开发中有一个非常重要的开闭原则、对拓展开放、对修改关闭
工厂模式主要负责对象创建的问题
可通过反射进行工厂模式的设计,完成动态的对象创建
单例设计模式
饿汉式
直接在类里私有静态最终实例化
构造方法私人化
对外提供一个可访问的静态方法
使用直接用反射获取对象的实例
对象类型 对象名 = 对象类型.getinstance()
然后对象名.方法使用
对象类型 对象名 = 对象类型.getinstance()
然后对象名.方法使用
类加载即可创建,占用内存高,存在时间久,但是线程安全
懒汉式
直接在类里私有静态实例化
构造方法私人化
对外提供唯一的可访问的静态方法
方法里判断对象是否为空,为空就实例化并返回
消耗资源少,保存时间短,线程不安全,但是可以加锁哇
懒汉式究极体
建立私有静态内部类里面创建静态对象
使用时创建,线程安全
一般使用饿汉和究极体,最好时究极体
枚举
枚举就是个常量类,只能定义字符串,变量名和值都是同一个
使用方式直接通过枚举名称点常量名
使用方式直接通过枚举名称点常量名
枚举里面的值都是静态的常量
枚举是一个引用类型,枚举是一个规定了取值范围的数据类型
枚举变量不能使用其他的数据,只能使用枚举中的常量
jdk8新特性
概述
jdk8(又称jdk1.8)是java语言开发的一个主要版本
Oracle公司于2014年3月18日发布Java8
Oracle公司于2014年3月18日发布Java8
支持lambda表达式
函数式接口
新的stream api
新的日期API
其他特性
Lambda表达式
概念
lambda表达式是特殊的匿名内部类,语法更简洁
lambda表达式允许把函数作为一个方法的参数(函数作为
方法的传递)将代码像数据一样传递
方法的传递)将代码像数据一样传递
语法
<函数式接口><变量名> = (参数1,参数2)->{
//方法体[};
//方法体[};
()代表的是方法的参数列表->箭头函数,只是一种指向,代码前面的参数列表的变量式应用在后面的{}代码
基本使用
演示案例
只能用在函数式接口,只有一个必须要实现方法的接口
函数式接口
概念
如果一个接口只有一个抽象方法,则该接口称之为函数式接口
函数式接口可以使用Lambda表达式,lambda表达式会被匹配到这个抽象方法上
ps:@Functionallnterface 注解检测接口是否符合函数式接口规范
ps:@Functionallnterface 注解检测接口是否符合函数式接口规范
常见函数式接口
consumer<T>消费型接口,无返回值,一个参数T
accept(T t)对参数进行操作
accept(T t)对参数进行操作
Supplier<T>供给型接口,有返回值,无参数
T.get返回类型为T的对象
T.get返回类型为T的对象
Function<T ,R>函数型接口,R applu(T t);
对类型为T的对象应用操作并返回类型为R的对象
对类型为T的对象应用操作并返回类型为R的对象
Predicate<T>断言型接口
boolean test(T t)确定类型为T的对象是否满足条件
并返回boolean值
boolean test(T t)确定类型为T的对象是否满足条件
并返回boolean值
方法引用
概念
方法引用时Lambda表达式的一种简写形式
如果Lambda表达式方法体中只是调用一个特点的
已经存在的方法,则可以使用方法引用
已经存在的方法,则可以使用方法引用
常见形式
对象::实例方法
类::静态方法
类::实例方法
类::new
stream
概念
流与集合类似,但集合中保存的是数据,而Stream中保存
对集合或数组数据的操作
对集合或数组数据的操作
特点
stream自己不会存储元素
stream不会改变源对象。相反,他们会返回一个持有结果的新stream
stream操作是延迟执行的,会等到需要结果的时候才执行
使用步骤
创建
新建一个流
中间操作
在一个或多个步骤中,将初始stream转化到另一个
stream流的中间操作
stream流的中间操作
终止操作
使用一个终止操作来产生一个结果。
该操作会强制之前的延迟操作立即执行,
在此之后,该Stream就不能使用了
该操作会强制之前的延迟操作立即执行,
在此之后,该Stream就不能使用了
创建stream的方法
同过collection对象的stream或parallestream方法
通过Arrays类的stream方法
通过stream接口的og、iterate、generate方法
通过intstream、longstream、Doublestream接口
中的of、range、rangeclosed方法
中的of、range、rangeclosed方法
中间步骤
filter过滤
limit限制
skip跳过
distinct去掉重复
sorted排序
新时间API
之前时间API存在问题:线程安全问题、设计混乱
本地化日期时间API
LocalDate
只有年月日,没有时分秒
LocalTime
LocalDateTime
不是new出来,调用其静态方法now输出当前时间
instant时间戳
获取格林威治的时间
zoneid时区
systemdefault返回当前时区
前端web基础
HTML
HTML简介
概念
一门使用标记或标签来描述网页展示信息给用户的语言
超文本标记语言
超文本
页面内可以包含图片连接音乐程序等非文字元素
标记
标签,不同的标签实现不同的功能
语言
人与计算机的交互工具
HTML版本
93年6月html1.0
95年11月2.0
97年1月3.2
97年12月4.0
99年12月4.01
14年10月5.0
书写规范
HTML标签是以尖括号包围的关键字
Html标签通常是成对出现的,又开始就有结束
HTML通常都有属性
格式:属性="属性值"
多个属性之间空格隔开
在HTML标签内不区分大小写,建议小写
HTML标签
结构标签
<html>
根标签
<head>
头标签
<title>
标题标签
<body>
正文
排版标签
用于实现简单的页面布局
注释标签
<!--注释内容-->
换行标签
<br/>
段落标签
<p></p>
align:对齐方式,left,center,right
水平线标签
<hr/>
width:水平线的长度
size:水平线的粗细像素表示,例如:10px
color:水平线的颜色
align:水平线的对齐方式
标题标签
随着数字增大文字逐渐变小,字体是加粗的,内置字号,默认占据一行
h1-h6由大到小
块标签
使用DIV+CSS是现下流行的一种布局方式
div:行级块标签,独占一行,换行
span:行内块标签,所有内容都在同一行
文字标签
font标签处理网页中文字的显示方式
size:用于设置字体的大小,最小1号最大7号
color:用于设置字体的颜色
face:用于设置字体的样式
文本格式化标签
格式化标签实现内容的简单样式处理
b:粗体标签
strong:加粗
em:强调字体
sub:上标标签
sbp:下标标签
del:删除线
综合案例
表单标签
无序列表
使用一组无序的符号定义,标签为<ul></ul>
circle :空心园
type = "circle"
disc:实心圆
square:黑色方块
有序列表
使用一组有序的符号定义,标签为<ol></ol>
1
A
a
i
I
列表嵌套
无序列表与有序列表相互嵌套使用】
图片标签
在页面指定位置处中引入一副图片
src:引入图片的地址
width:图片的宽度
height:图片的宽度
align:对齐显示方式
alt:提示信息
hspace在图片左右设定空白
vspace在图片上下设定空白
链接标签
连接标签为<a>文本或图片</a>
在页面使用链接标签跳转到另一页面
href:跳转到页面的地址(跳转到外网需要协议)
target:设置跳转页面时的打开方式
_blank:新窗口中打开
_self:自身空口中打开
parent:在父窗口中打开
_top:在顶级窗口中打开
指向同一页面中指定位置
定义位置<a name="名称"></a>
指向:<a href="#名称"></a>
表格标签
表格标签用来在页面中规则整齐的显示数据
标签
table:定义一个表格
tr:定义行
td:定义列
th:定义列标题加粗显示
表格常用属性
border:设置表格边框
width、height:设置表格的宽度或和高度
align、valign:设置单元格的水平或垂直对齐
bgcolor:设置表格的背景颜色
颜色表示方式
用表示颜色的英文单词
用十六进制表示i颜色
列合并:cols
行合并:rows
表单标签:表单用于收集不同类型的用户输入数据
from标签定义表单
action:将表单的数据提交到该地址上处理
method:get:不安全、post:相对安全
enctype
application/x-www-from-urlencoded:默认、普通表单
multipart/from-data:文件上传使用
表单元素
input元素
框架标签
框架
使用框架可以在同一个游览器窗口中显示不只一个页面
每份HTML文档称为一个框架,并且每个框架都独立于其他的框架
frameset
row/columns:规定了每行或每列占据屏幕的面积
frameborder:是否有框架边框
frame
noresize="noresize":不能调整大小
其他标签
标签
meta:定义网页元信息
link:链接样式表
script:定义js代码
特殊字符
 :空格
>:>
<:<
®:注册符号
":双引号
¥:人民币
CSS
是一种用来表现HTML或XML等文件样式的计算机语言
层叠样式表
CSS可以修饰美化网页
CSS可以配合各种脚本语言动态地对网页各元素进行格式化
内容与表现分离,页面外观维护的更加容易
基本语法
CSS规则有两个重要的部分构成:选择器以及一条或多条声明
选择器通常时您需要改变样式的HTML元素
每条声明由一个属性和一个值组成
导入方式
内联方式
把CSS样式嵌入到HTML标签当中,类似属性的用法
内部方式
在head标签中使用style标签引入CSS
外部方式
将CSS样式抽成一个单独.css文件,使用link标签引入或@import导入
link标签
<link rel="stylesheet" type ="test/css" href="div.css"><link>
rel:代表当前页面与href所指定文档的关系
type:文件类型,告诉游览器使用css解析器去解析
href:css文件地址
@import方式
css2.1特有的
<style>@import url("地址")</style>
选择器
作用:选择页面上的某一个或者某一类元素
三种基本选择器
标签选择器
选择一类标签
类选择器
选择所有class属性一致的标签,跨标签.类名{}
格式.class的名称{}好处是同一个class可以复用
id选择器
全局唯一#id名{}
与类相同.换成#不可以复用id只能有一个且不可以以数字开头
不遵循就近原则,固定的
id选择器>class选择器>标签选择器
高级选择器
层次选择器
后代选择器
在某个元素后面 祖爷爷 爷爷 爸爸 你
body p{}
子孙后代都改变
子选择器
body>p{}
只有后面的第一代才有
相邻兄弟选择器
.类名 +标签{}
只有下面的一个会变
通用选择器
.类名~标签名{}
选择元素下面所有兄弟元素
结构伪类选择器
伪类 :
属性选择器
JavaScript
概述
解释性脚本语言,是一种动态类型、弱类型、基于原型继承的语言,内置支持类型
解释器成为JavaScript引擎,作为浏览器的一部分
用来给HTML网页增加动态功能,定义网页的行为
组成
ECMAScript语法
文档对象模型(DOM)
游览器对象模型(BOM)
使用方式
在<script>标签中编写
可以在网页任何地方编写
在外部JS文件中编写
需要使用<script src=""></script>关联
在事件属性中编写
<button onclick="">按钮</button>
变量
JS中变量都用var关键字来声明,var是variable的缩写
注意
var是声明关键字,num是变量名,语句以分号结尾;分号可以省略(建议不要省略)
命名规范
包含字母、数字、下划线和美元符号
不能以数字开头
变量名不能是关键字
数据类型
基本类型
Number、String、Boolean、Undefined、Null五种
使用typeof运算符检测一个变量的类型
使用方式:typeof(表达式)或typeof变量名
引用类型
对象类型
object表示任何对象
使用JSON表示法创建对象
var person = {"name":"张三","age":20}
数组类型
和java数组概念一直,而在JavaScript中使用Array类型
使用JSON表示法创建数组
var arr =["a","b","c"];
注意创建数组时可以不用指定长度
运算符
与java一样
==与===的区别
==比较的是指与数据类型无关
===要求数据类型一样,值也一样
函数
概念:封装特定任务功能的 代码块
定义:JavaScript函数通过function关键词进行定义
调用:当事件发生时调用或者通过代码调用、自调用
弹窗函数
alert()
只能点击确定按钮的弹窗
值为undefined类型
confirm()
可以点击确定或者取消的弹窗
确定值为true,取消值为false
prompt()
可以输入文本内容的弹窗
第一个参数是提示信息,第二个参数是用户输入的默认值
点击确定返回用户输入内容,点击取消或者关闭,返回null、
系统函数
parseint()
解析一个字符串并返回一个整数
parseFloat()
解析一个字符串并返回一个浮点数
isnan()
检查某个值是否为数字,是返回false,不是返回true
常用事件
onchange
HTML元素内容改变
onclick
用户点击HTML元素
onmouseover
用户将鼠标移入一个HTML元素中
onmousemove
用户在一个HTML元素上移动鼠标
onmouseout
用户从一个HTML元素上移开鼠标
onkeyup
按下键盘弹起
onkeydown
按下键盘
onload
浏览器已完成页面的加载
onsubmit
表单提交
正则表达式
概念:正则表达式是描述字符模式的对象
作用
用于对字符串模式匹配及检索替换
是对字符串执行模式匹配的强大工具
语法
var patt = new regexp(pattern,modifiers)
var patt =/pattern/modifiers
修饰符
i:执行对大小写不敏感的匹配
g:执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)
m:执行多行匹配
字符
[abc]:查找方括号之间的任何字符
[^abc]查找任何不在方括号之间的内容
[0-9]查找任何从0-9的数字
[a-z][A-Z][A-z]同上
(x|y|z)查找x或y或z
元字符
.查找单个字符,出了换行和行结束符
\w查找单词字符
\W查找非单词字符
\d查找数字
\D查找非数字
\s查找空白字符
\S查找非空白字符
量词
用于表示重复次数的含义
n+匹配任何包含至少一个n的字符串
n*匹配任何包含零个或多个n的字符串
n?匹配任何零个或一个n的字符串
n{x}匹配包含x个n的序列的的字符串
n{x,}x是一个正整数,前面的模式n连续至少出现x次时匹配
n{x,y}x和y为正整数,前面的n连续出现至少x次,至多y次匹配
refexp对象方法
complie:编译正则表达式
exec:检索字符串中指定的值,返回找到的值,并确定其位置
test:检索字符串中指定的值,返回true与false
String对象方法
search:检索与正则表达式相匹配的值
match:找到一个或多个正则表达式的匹配
replace:替换与正则表达式匹配的子串
split:把字符串分割为字符串数组
DOM
概念
通过HTML DOM,可访问JavaScriptHTML文档的所有元素
当网页被加载时,游览器会创建页面的文档对象模型(DOM)
查找HTML元素
getelementbyid:通过id找到html元素
getelementbytagname:通过签名找到HTML元素
getelementsbyclassname:通过类名找到HTML元素
修改HTML内容
document.write():可用于直接向HTML输出流写内容
innerHTML属性:获取或设置HTML内容,HTML标签会被解析
innertext:获取或设置HTML内容,HTML标签会作为普通文本
修改html属性
对象.attribute:获取或设置dom对象的属性
使用方法:getAttribute("att"),获取属性值
setattribute("att","value")设置属性值
setattribute("att","value")设置属性值
改变css
获取
getcomputedstyle()
currentstyle
实例
设置
对象.style.property=新样式
将property替换成真实的属性名
设置DOM事件
通过dom对象设置事件属性
语法:dom对象.onxxx=function(){...}
EventListener
addEventListener:向指定元素添加事件,不会覆盖已存在的事件
event:事件类型
function:事件触发后调用的函数
usecapture:用于描述事件是冒泡还是捕获,默认false冒泡、true捕获
removeEventListener:移除事件
新建、删除元素
新建元素
document.createElement("标签");
追加appendchild()
添加:insertbefore()
删除元素
删除子元素:removechild()
删除元素:remove()
BOM
概念
游览器对象模型(BOM)使JavaScript有能力与游览器对话
现代游览器实现了和JavaScript交互性方面的相同方法和属性,因此常被认为是BOM的方法和属性
window对象
概述
所有游览器都支持window对象,它表示游览器窗口
JavaScript全局对象、函数以及变量均自动成为window对象的成员
属性
window.innerheight:内部高度,包括滚动条
window.innerwidth:内部宽度,包括滚动条
方法
open():打开新的窗口
close():关闭窗口
screen对象
表示当前屏幕对象
属性
screen.availwidth:可用的屏幕宽度
screen.availheight:可用的屏幕高度
location对象
概述
location对象用于获得当前页面的地址(URL),并把游览器重新定向到新的页面
属性
location.href:返回当前页面的URL
location.hostname:返回web主机的域名
location.protocol:返回所使用的web协议
location.port:返回web主机的端口
方法
reload()重新加载页面
history对象
概述
包含用户在游览器窗口中访问过得URL
属性
length:返回浏览器历史列表中的URL数量
方法
back()加载histor列表中的前一个URL
forwa():加载history列表中的下一个URL
go()加载history列表中的某个具体页面
navigator对象
概述
navigator对象包含有关游览器的信息
属性
appname:返回游览器的名称
appversion:返回游览器的代码名
platform:返回运行游览器的操作系统平台
useragent:有客户机发送服务器的user-agent头部的值
JavaScript定时器
定时器函数
setinterval每间隔固定毫秒值就执行一次函数
settimeout在固定时间之后执行一次调用函数
clearinterval(定时器id)清楚定时执行
cleartimeout(定时器id)清除延时执行
前端web进阶
jQuery
引言
概述
jQuery是一个快速、简洁的JavaScript代码库,设计宗旨是write less,do more
即倡导写更少的代码,做更多的事情,他封装JavaScript常用的功能代码,提供
一种简便的JavaScript操作方式优化HTML文档操作,事件处理动画设计Ajax交互
即倡导写更少的代码,做更多的事情,他封装JavaScript常用的功能代码,提供
一种简便的JavaScript操作方式优化HTML文档操作,事件处理动画设计Ajax交互
特点
具有独特的链式语法
支持高效灵活的css选择器
用用丰富的插件
兼容各种主流游览器
语法
基本使用
$(匿名函数)表示页面dom加载完毕则执行,比onload
事件执行早,并且可以写多个,$是jQuery函数的简写
事件执行早,并且可以写多个,$是jQuery函数的简写
$(function(){})
$(selector).action()通过选取HTML元素
并对选取的元素执行某些操作
并对选取的元素执行某些操作
选择符(select)表示查找html元素
jQuery的action()执行对元素的操作
基本实例
$(this).hide():隐藏当前元素
$("p").hide()隐藏所有<p>元素
$("p.test").hide()隐藏所有class=test的<p>元素
$("#test").hide()隐藏所有id为test的元素
jQuery选择器
元素选择器
jQuery元素选择器基于元素名称选取元素
$("元素名称例如p,button等等")
id选择器
jQuery#id 选择器通过选择HTML元素的id属性选取指定的元素
页面中元素的id应该是唯一的,所以你要在页面中选取唯一的元素需要通过#id选择器
$("#id").事件
class选择器
jQuery类选择器可以通过指定的class查找元素
$(".类名")
事件以及常用事件方法
什么是事件
页面对不同访问者的响应
事件处理程序指的是当html中发生某些事情时所调用的方法
比如在元素上移动鼠标,点击的
常见dom事件
鼠标事件
click
dblclick双击事件
mouseenter鼠标进入
mouseleave鼠标离开
键盘事件
keypress按下的过程触发只会触发字符键
keydown被按下触发
keyup被松开触发
表单事件
submit提交触发
change元素变动触发
focus聚焦
blur失焦
文档/窗口事件
load页面加载完成事件
resize调整窗口大小事件
scroll元素滚动条滚动触发时间
unload离开页面触发
Ajax
layUI
bootstrap
工具与框架
框架概念
什么是框架
软件的半成品,解决的软件开发过程当中得普适性问题,从而简化的开发步骤,提供了开发的效率
什么是ORM框架
ORM对象关系映射,将程序中的一个对象与表中的一行数据一一对应
ORM框架提供了持久化类与表的映射关系,在运行时参照映射文件的信息,把对象持久化到数据库中
使用JDBC完成ORM操作的缺点
存在大量冗余代码
手工创建connection、statement等
手工将结果集封装成实体对象
查询效率低,没有对数据访问进行过优化
mybatis框架
概念
MyBatis本是Apache软件基金会的一个开源项目iBatis,
2010年这个项目由apache software foundation 迁移到了Google Code,
并且改名为MyBatis 。2013年11月迁移到Github。
2010年这个项目由apache software foundation 迁移到了Google Code,
并且改名为MyBatis 。2013年11月迁移到Github。
MyBatis是一个优秀的基于java持久层的框架(持久层类似于dao层)
支持自定义SQL,存储过程和高级映射
支持自定义SQL,存储过程和高级映射
MyBatis对原有JDBC操作进行了封装,几乎消除了所有JDBC代码,使开发者只需关注SQL本身
MyBatis可以使用简单的xml或annotation来配置执行SQL并自动完成orm操作将执行结果返回
课外补充
直接操作01的运算符
&与运算符,|或运算符,^异或运算符,<<左位移,>>右位移
&运算符,直接比较两边的2进制数值,两边为一就为一,否则为0
|异或运算符,两个都是相同的值的时候结果为0,不同的时候结果为1
|或运算符,至少一边为1就为1,两边为0才为0
<<左位移,二进制上的数全部往左一两位,多的舍弃
公式,n<<m,n*2^m
>>右位移,二进制上的数全部往右一两位,多的舍弃
公式,n>>m,n/2^m
开闭原则
对扩展开放,对修改关闭
线性数组存储与链表存储的区别
线性是有序的存储,但是分配空间一样的,会有很多碎片空间
线表需要开辟连续空间,查询快,增删慢
链表则是利用复用有限的碎片空间进行存储
链表无需开辟连续空间,查询慢,但是增删快
equals重写
在类里重写用this
判断地址相同
instanceof判断类型是否是对象类型
进行强转
开始判断规则
模式
优先适配器模式
适配器模式
显而易见灵感来自于笔记本电脑一类的适配器
模式动机
在软件开发中采用类似于电源适配器的设计和编码技巧被称为适配器模式
通常情况下,客户端可以通过目标类的接口访问它所提供的的服务,有时候现有的类可以满足客户类的需要
,但是它所提供的接口不一定是客户类所期望的,这可能是因为现有类中方法名和目标类中定义的方法名
不一致等原因所导致的
,但是它所提供的接口不一定是客户类所期望的,这可能是因为现有类中方法名和目标类中定义的方法名
不一致等原因所导致的
在这种情况下,现有的接口需要转化为客户类期望的接口,这样保证了对现有类的重用
如果不进行这样的转化,客户类就不能利用现有类所提供的功能,适配器模式可以完成
这样的转化
如果不进行这样的转化,客户类就不能利用现有类所提供的功能,适配器模式可以完成
这样的转化
n接口在适配器模式中可以定义一个包装类,包装不兼容接口的对象,这个包装类值得就是
适配器,他所包装的对象就是适配者,即被适配的类
n适配器提供客户类需要的接口,适配器的实现就是把客户类的请求转化为对适配者的相应
接口的调用,也就是说:当客户类调用适配器的方法时,客户类并不直接访问适配者类,
因此,适配器可以使由于接口不兼容而不能交互的类可以一起工作,这就是其模式动机
适配器,他所包装的对象就是适配者,即被适配的类
n适配器提供客户类需要的接口,适配器的实现就是把客户类的请求转化为对适配者的相应
接口的调用,也就是说:当客户类调用适配器的方法时,客户类并不直接访问适配者类,
因此,适配器可以使由于接口不兼容而不能交互的类可以一起工作,这就是其模式动机
模式定义
适配器模式:将一个接口转换成客户希望的另一个接口,适配器模式,使
接口不兼容的那些类可以一起工作,其别名为包装器,适配器模式可以作
为类结构模式,也可以作位对象结构模式
接口不兼容的那些类可以一起工作,其别名为包装器,适配器模式可以作
为类结构模式,也可以作位对象结构模式
代理模式
建造者模式
两表关联时,外键一定在多的一方
要用那个表的数据,那个表的外键一定在使用的哪一方
要用那个表的数据,那个表的外键一定在使用的哪一方
概述环境与搭建
JDK工具包下载,Oracle官网
packa包
package 包名;
只可以写在源文件的第一行
带包编译 javac -d . 源文件名称.java
-d 表示是带包翻译,.表示在当前文件夹
自动生成目录结构
带包运行java 包名.类名
包名.类名又称为全限定名
带包编译只可以带包运行
编码规范
书写格式
层级之间必须缩进(一个tab制表位)
一行只写一句代码
注释规范
单行注释//通常都是解释下面的代码
多行注释/**/字数太多的话单行注释不够用的话就用多行
文档注释/** */类类属性类方法的注释必须使用
javadoc -d . 源文件名.java生成外部文档
标识符命名
标识符就是类名,名字等等
可以用数字,字母,_,$组成,但是不可以以下划线开头
不可以与关键字,保留字重名
约定俗成
望文生义,见名知意
类名由一个或多个单词组成,每个字母的首字母都要大写
函数名由一个或多个单词组成,首单词小写,拼接词首字母大写
包名全小写,以.连接
常量名大写,以下划线_连接
语言基础
变量
计算机内存中的一块储存空间,
是储存数据的基本单位
是储存数据的基本单位
组成部分
数据类型
变量名
值
声明方式
先声明在赋值
数据类型 变量名;
变量名 = 值;
变量名 = 值;
声明并赋值
同时声明赋值多个同类型变量
数据类型
基本数据类型
整数
byte
1字节
-2^7~2^7-1
short
2字节
-2^15~2^15-1
int
4字节
-2^31~2^31-1
默认是int类型
long
8字节
-2^63~2^63-1
浮点数
float
double
默认是double类型
布尔
boolean
true
false
字符
char
转义字符\
\\
\'
\"
\t
引用数据类型
字符串
String
数组
对象
类型的转换
自动类型转换
两种类型兼容且目标类型大于源类型
强制类型转换
两种类型兼容且目标类型小于源类型
转换规则
整数长度足够,数据完整
整数长度不够,数据截断
小数强转整数,小数部分截断
字符整数互转,数据完整
保证正整数转换成字符可以正常显示
boolean类型不可以与其他类型转换
运算符
算数预算符
+,-,*,/,%
赋值运算符
=,+=,-=,*=,/=,%=
关系运算符
==,>.<.>=.<=,!=
逻辑运算符
&&,||,!
&&注意,如果&&前面的表达式结果为false,则后面的表达式不会运行
||注意,如果||前面的表达式为true,贼后面的表达式不运行
即后面运行的话,自增i++,++i,等等这些都不会生效
布尔运算符
布尔表达式?结果1:结果2
布尔表达式结果为真时取结果1,反之结果2
一个公式(算式)得出的结果为true或false
表达式
使用运算符连接的变量或字面值,并可以的到一个最终结果。
字面值就是没有任何变量接受,直接写出的值
自动类型提升
算数运算时
两个操作数有一个为double,计算结果提升为double;
如果操作数中没有double,有一个为float,其计算结果提升为float;
如果操作数中没有float,有一个为long,其计算结果提升为long;
如果操作数中没有long,有一个为int,其计算结果自动提升为int;
如果操作数中没有int,均为short或byte,计算结果仍提升为int;
特殊情况
任何类型与String相加(+)时,实为拼接,其结果自动提升为String
控制台输入
程序运行中,可在控制台(终端)手动录入数据,再让程序继续运行
导包语法
import 包名.类名;//将外部class文件功能引入到自身文件中
使用顺序
1.导入java.util.Scanner。 import java.util.Scanner; inport 关键字的声明,写在package之后
2.声明一个Scanner类型的变量 Scanner 变量名 = new Scanner(System.in);
使用Scanner类中对应得函数(区分类型):
使用Scanner类中对应的函数(区分类)
.nextInt();获得整数
.nextDouble();获得浮点数
.next();获得字符串
.next().charAt(0);获得输入的首个字符
如果输入了不匹配的数据,则会产生一个java.util,InputMismatchException异常
语法层面
Java语言规范
规定的什么就能用什么,没有规定的绝对不能用
Java虚拟机规范
规定怎么用就支持怎么用,没有规定的随便用,支持自我创造
选择与分支结构
概念:根据已知条件进行落尽判断,满意条件后执行相应的操作
if选择结构
if(布尔表达式){
代码块1
}
后续代码
代码块1
}
后续代码
判断布尔表达式为真则执行代码1,然后跳出整个结构再执行后续代码
当你需要判断,并且只会执行一个选择的时候
if else选择结构
if(布尔表达式1){
代码块1
}else{
代码块2
}
后续代码
代码块1
}else{
代码块2
}
后续代码
判断布尔表达式1为真则执行代码块1,然后跳出整个结构再执行后续代码,反之执行代码块2然后跳出整个结构执行后续代码
注意,代码1和代码2一定会执行一个
当你需要判断,并且只会执行选择是二选一的时候
多重if选择结构
if(布尔表达式1){
代码块1
}else if(布尔表达式2){
代码块2
}else if(布尔表达式3){
代码块3
}等等、
代码块1
}else if(布尔表达式2){
代码块2
}else if(布尔表达式3){
代码块3
}等等、
判断布尔表达式1为真时执行代码块1,在跳出整个结构执行后续代码
反之判断布尔表达式2以此类推
反之判断布尔表达式2以此类推
注意相互排斥,当有一个条件为true时,其他均不再执行,使用与区间判断(区间条件,遵循从大到小或从小到大)
当你需要判断,发现会有多个判断条件存在的时候,适用于多个区间判断的时候
switch分支结构
可判断的byte,short,int,char,String(JDK7+)
switch中case的取值不可以相同
switch有自动向下贯穿的特性,如需要在加载某个选项后终止,需要追加break关键字
局部变量
- 概念:函数内部的变量必须先赋值才可以使用
作用范围:从定义的所在行开始到代码块结束
注意:如果是多个变量在重合的作用范围内不可以出现变量的重名
嵌套if
循环
概念:通过某个条件,重复的执行一段逻辑代码
while循环
语法:while(布尔表达式){ 逻辑代码(循环操作)}
执行流程:1.先对布尔表达式进行判断,结果为true,则执行逻辑代码。
2.本次执行完毕后,再次进行判断,结果仍旧为true,则再次执行逻辑代码
3.直至布尔表达式的结果为false时,才会退出循环结构,执行后续代码
2.本次执行完毕后,再次进行判断,结果仍旧为true,则再次执行逻辑代码
3.直至布尔表达式的结果为false时,才会退出循环结构,执行后续代码
循环的组成:1.初始部分:用以判断的变量
2.循环条件:决定是否继续循环的依据
3.循环操作:单次执行的逻辑代码或任务
4.迭代部分:控制循环条件改变的增量
2.循环条件:决定是否继续循环的依据
3.循环操作:单次执行的逻辑代码或任务
4.迭代部分:控制循环条件改变的增量
约定俗成:一般定义变量都用i
特点:首次既有入口条件,先判断再执行,适用于循环次数明确的情况
do while循环
语法:do{逻辑代码(循环操作)}while(布尔表达式)
执行流程:先执行一次循环操作之后,在进行布尔表达式判断
如果结果为true,则再次执行循环操作
如果结果为false,才会退出循环结构执行后续代码
如果结果为true,则再次执行循环操作
如果结果为false,才会退出循环结构执行后续代码
特点:首次没有入口条件,先执行在判断,判断满足在循环,不满足则至少循环1次,适用于循环次数不明确的情况
for循环
语法: for(初始部分 ;循环条件; 迭代部分){循环操作}
其中初始部分,循环条件,迭代部分都可以省略,会默认为true
执行流程:1.首次执行初始部分(仅一次)
2.对布尔表达式进行判断,结果为true,则执行逻辑代码
3.本次执行完毕后,执行迭代部分,再次判断,结果仍为true则再次执行逻辑代码
4.直至布尔表达式的结果为false时,才会退出循环结构,执行后续代码
2.对布尔表达式进行判断,结果为true,则执行逻辑代码
3.本次执行完毕后,执行迭代部分,再次判断,结果仍为true则再次执行逻辑代码
4.直至布尔表达式的结果为false时,才会退出循环结构,执行后续代码
for循环与while循环相同,首次判断不满足则一次都不会执行,首次即有入口条件,先判断再执行,适用于循环次数明确的情况下
流程控制
break:终止,跳出switch,循环结构
continue:结束本次、进入下一次循环
嵌套循环
概念:在一个完整的循环当中,嵌套另一个完整的循环
经验:打印图形,外层控制行数,内层控制列数
打印其他:外层控制循环次数,内层控制单次循环操作
打印其他:外层控制循环次数,内层控制单次循环操作
函数
概念:实现特定功能的一段代码,可反复使用
定义:public static void 函数名称(){ 函数的主题 }
定义的位置:定义在类的内部,与main函数并列。多数情况下,定义在main函数的下面
调用:函数名();
执行顺序:函数调用时,优先执行函数内部代码,结束后返回到函数的调用处,然后继续向下执行
返回值与返回值类型
定义返回值类型:基本数据类型,引用数据类型,void
return value;//函数可以返回一个结果,类型必须与函数定义的返回值类型一致
一个函数只能由一个返回值,如果函数中包含分支,需要保证所有的分支都有正确的返回值
return的两种用法
return value;//表示结束当前函数,并伴有返回值,返回函数调用处(有具体的返回值类型)
return;//表示结束当前函数,直接返回函数调用处(返回值类型是void)
总结:
注意:一个类中可以定义多个函数,函数之间属于并列关系,不可嵌套
经验:一个函数只做一件事
好处减少代码冗余,提高复用性,可读性,可维护性,方便分工合作
递归
实际再发中,递归可以解决一些具有既定规律的问题
当需要解决的问题可以拆分成若干个小问题,大问题、小问题的解决方法相同,有特点的规律,函数自己调用自己
设置有效的出口条件,避免无穷递归
参数
参数:多数情况下,函数与调用者之间需要数据的交互;调用者必须提供必要的数据,才能使函数完成相应的功能
调用函数时,所传入的数据被称为参数
调用函数时,所传入的数据被称为参数
参数定义:形式参数
实参
实参
形参
定义语法:public static void 函数名称(形式参数){ 函数主体 }
就是函数内部的局部变量,等价于局部变量的声明
实参
调用的时候:函数名称(实际参数)
实参等价于局部变量内给形式参数的赋值赋值
注意
调用带参函数时,依次传入实参,类型,个数,顺序,必须与形参对应
补充
== 比较的是地址,比较字符串时,==不够准确,应该采用 字符串1.equals(字符串2) 来准确的比较字符串内容,当比较两个字符串不相同是可以使用!字符串1.equals(字符串2)来比较
数组
概念:一组连续的存储空间,存储多个相同数据类型的值
数组中每个数据格被称为数组元素
对每个元素进行赋值或取值的操作被称为元素的访问
访问元素时,需要使用下标,(从0开始,依次+1,自动生成)
访问的语法:数组名【下标】;//例如 存:a[0] = 10;取:a[0];
数组的遍历
所有整数数组的默认值都是0,但是随着整数类型不同,默认值0的类型也不同
浮点数0.0
字符 空格
布尔 false
所有引用类型都是 null,表示没有在堆中打开空间,代表引用类型为空
数组的扩容
创建数组时,必须显示指定长度,创建之后不可以更改长度
扩容的思路
创建长度大于原数组的新数组
将原数组中的数据依次复制到新数组当中
数组的复制
循环将原数组的所有元素数据逐一赋值给新数组
System.arraycopu(原数组,原数组起始位置,新数组,新数组起始位置,长度)
数组类型的变量 = java.util.Arrays.copyOf(原数组,新长度);//根据长度创建新数组,并将原数组中的数据赋值给新数组
基本数据类型和引用数据类型的区别
基本数据储存的是值
引用数据类型储存的是地址
地址的替换
基本数据类型的变量储存的是值
引用数据类型的变量储存的是地址
num = newNum 将新数组的地址赋值给num变量,进而在后续操作num时,则操作更大的新数组
数组类型的参数
基本数据类型是值的传递,一方改变,不会影响另一方
引用数据类型的传递,是地址的传递,一方改变会影响另一方
可变长参数
概念:可以接受多个同类型的实参,个数不限,使用方式与数组相同
语法:数据类型... 形参名//必须定义在参数列表的最后,且只能有一个,支持0~n的参数
可边长参数,是对数组的一种便利写法的补充
排序
冒泡排序
比较相邻的两个值大小,互换位置
记忆,外层length-1;内层length-1-i
补充:嵌套循环约定俗称的变量命名,一重循环i,二重循环j,三重循环k
选择排序
固定值与其他值依次的的比较大小,互换位置
记忆,外层length-1;同时外层的i做为固定值;内层的j=i+1作为其他值的起始
JDK排序
java.util.Arrays.sort(原数组);固定是升序
插入排序
for(int i = 1; i <a.length;i++){
int temp = a[i];暂存要插入的数据
int j ;声明j,方便 后续使用
for(j = i-1; j >=0;j--){
if(temp<a[j]){
a[j+1] = a[j];
}else{
break;如果值小于temp,则终止循环
}
}
a[j+1]=temp;
}
int temp = a[i];暂存要插入的数据
int j ;声明j,方便 后续使用
for(j = i-1; j >=0;j--){
if(temp<a[j]){
a[j+1] = a[j];
}else{
break;如果值小于temp,则终止循环
}
}
a[j+1]=temp;
}
优化版
for(int i = 1; i<a.length;i++){
if(a[i]<a[i-1]){//如果本来有序就跳过
int temp = a[i];
int j;
for(int j = i-1;temp<a[j];j++){
a[j+1]=a[j]
}
a[j+1] =temp;
}
}
if(a[i]<a[i-1]){//如果本来有序就跳过
int temp = a[i];
int j;
for(int j = i-1;temp<a[j];j++){
a[j+1]=a[j]
}
a[j+1] =temp;
}
}
冒泡排序效率最低,选择效率第二低,插入排序效率最高
char和string类型的数组也可以排序,一个根据ASCII码来排序,一个根据万国码来排序
二维数组
概念:一维数组中的一维数组,数组中的元素还是数组
高位数组中的每一个元素保存了低维数组的地址,访问高位数组等于访问低维数组的地址
访问元素的方式:数组名[高维下标][低维下标]
创建语法:数组类型[][]数组名=new数据类型[高维下标][低维下标]
杨辉三角
int [][] a = new int [line][];
for(int i =0;i<line;i++) {
a[i] = new int[i+1];
for(int j =0 ;j<=i;j++) {
if(j==0||j==i) {
a[i][j] = 1;
}else {
a[i][j] =a[i-1][j-1]+a[i-1][j];
}
}
}
for(int i =0;i<line;i++) {
a[i] = new int[i+1];
for(int j =0 ;j<=i;j++) {
if(j==0||j==i) {
a[i][j] = 1;
}else {
a[i][j] =a[i-1][j-1]+a[i-1][j];
}
}
}
for each循环(增强for)
只应用于数组或者集合
for(数组类型 自定义名称:数组名){
System.out.println(自定义名称)}
System.out.println(自定义名称)}
自动遍历
将数组名里的值第一个赋值给自定义名称,然后输出,然后继续循环
如果需要修改其中数据的话,不要使用这个
二分查找法
普通
public static int BS(int b,int... a) {
int strat = 0;
int end = a.length-1;
while(strat <= end) {
int mid = strat +(end - strat)/2;
if(b == a[mid]) {
System.out.println("找到了在下标"+mid+"上面");
return mid;
}else if(b > a[mid]){
strat = mid+1;
}else {
end = mid -1;
}
}
return -1;
}
int strat = 0;
int end = a.length-1;
while(strat <= end) {
int mid = strat +(end - strat)/2;
if(b == a[mid]) {
System.out.println("找到了在下标"+mid+"上面");
return mid;
}else if(b > a[mid]){
strat = mid+1;
}else {
end = mid -1;
}
}
return -1;
}
递归
public static int bs(int strat,int end,int a, int... b) {
if(strat>end) {
return -1;
}
int mid = strat +(end - strat)/2;
if(a ==b[mid]) {
return mid;
}else if(a>b[mid]) {
return bs(mid+1,end,a,b);
}else {
return bs(strat,mid-1,a,b);
}
}
if(strat>end) {
return -1;
}
int mid = strat +(end - strat)/2;
if(a ==b[mid]) {
return mid;
}else if(a>b[mid]) {
return bs(mid+1,end,a,b);
}else {
return bs(strat,mid-1,a,b);
}
}
面向对象(oop)
程序是为了模拟现实世界。解决现实问题而使用计算机语言编写的一系列有序的指令
如何使用程序模拟现实世界解决现实问题
现实世界中,都是对象,程序中也应有对象
首先,在程序当中,必须具有和现实中相同的对象,用于模拟现实世界
然后,使用程序的对象代表现实中的对象,并执行操作,进而解决现实问题
现实中的对象从哪里来
手机->工厂->图纸(模板)
什么是类
汽车设计图纸规定了该款汽车所有的组成部分,包括外观形状、内部结构、发动机型号、安全参数等具体的信息。
这即为现实对象的模板。程序中的模板也有相同的作用,称之为”类“
这即为现实对象的模板。程序中的模板也有相同的作用,称之为”类“
按照设计图纸创造出来的汽车,才是真实存在、切实可用的实体,所以汽车实体被称为现实中的对象。而通过程序中的模板创造出来的实体,
即为程序中的对象,称之为”对象“
即为程序中的对象,称之为”对象“
类的抽取
在一组相同或类似的对象中,抽取出共性的特征和行为,保留所关注的部分
类的定义:
方法:通过函数表示,又称实例方法
语法:public 返回值类型 方法名(形参){//方法的主体}不在书写static
类与对象的关系
类:定义了对象应具有的特征和行为,类是对象的模板
对象:拥有多个特征和行为的实体,对象是类的实例
对象
对象的创建过程
对象类型 变量名 = new 对象名()
1.堆内存中开辟对象空间
2.构造方法执行
1.为各个属性赋予初始值
2.执行构造方法中的逻辑代码
3.[ 将构造后对象的地址赋值给变量
方法重载
重载(Overload):一个类中定义多个相同名称的方法
要求
方法名称相同
参数列表不同
与访问修饰符,返回值类型无关
调用带有重载的方法时,需要根据传入的实参去找到与之匹配的方法
好处:屏蔽使用差异,灵活、方便
只是参数名称的不同并不能构成方法的重载
什么时候该用,当你发现行为是相同的,但是实现过程不同
用的最多的是构造方法,和工具类方法
构造方法
概念:类中的特殊方法,主要用于创建对象
特点
名称与类名完全相同(包括大小写),没有返回值类型,即啥也不写
创建对象时(new 对象时),触发构造方法的调用,不可通过句点的形式手工调用
注意:如果没有在类中显示定义过构造方法,则编译器默认提供无参构造方法
如果已经手动添加过有参的构造方法,则无参构造方法不在默认提供,可结合需求自行添加(建议:必须手动添加无参构造方法)
如果已经手动添加过有参的构造方法,则无参构造方法不在默认提供,可结合需求自行添加(建议:必须手动添加无参构造方法)
构造方法也可以重载,遵循方法重载规则
一般用于给属性赋值
this 关键字
this 代表”当前实例“,即时模板中的当前对象,模板服务于哪个对象,this就指向哪个对象
this 第一种用法
调用本类中的实例属性、实例方法如:this.name this.sayHi()
this 第二种用法
调用本类中的构造方法 如:this();this(形参);
必须在构造方法的首行(也就是只可以有一个),仅可在构造方法中而不能在普通方法中
三大特性()
封装
概念:尽可能隐藏对象的内部实现细节,控制对象的修改及访问的权限
访问修饰符:private(可将属性修饰为私有,仅本类可见、可用),外部无法直接访问,只可通过set/get方法
公共的访问方法
以访问方法的形式进行赋值与取值的操作
里面可以添加限制非法参数的代码
命名规范
赋值:setXxx()//使用方法参数实现赋值
取值:getXxx()//使用方法返回值实现取值
方法名是get加首字母大写的属性名
赋值:setXxx()//使用方法参数实现赋值
取值:getXxx()//使用方法返回值实现取值
方法名是get加首字母大写的属性名
get/set方法是外界访问对象私有属性的唯一通道,方法内部可对数据进行检测和过滤
继承
程序中的继承,是类与类之间特征和行为的一种赠与或获得
两个类之间的继承关系,必须满足"is a"的关系
功能越精细,重合点越多,越接近直接父类,反之越接近object类(万物皆对象)
可根据程序需要使用到的多个具体类,进行共性抽取进而定义父类
在一组相同或类似的类中,抽取出共性的特征和行为,定义在父类中实现重用
在一组相同或类似的类中,抽取出共性的特征和行为,定义在父类中实现重用
继承特点
Java只有单继承,一个类只能由一个直接父亲,但可以多级继承,属性和方法逐级叠加
不可继承
构造方法:类中的构造方法吗,只负责创建本类对象,不可继承
private修饰的属性和方法
然是还是可以使用父类提供的set/get方法
父子类不在同一个package中时,default修饰的属性和方法(什么都不写的就是默认访问修饰符default)
方法重写/覆盖
当父类提供的方法无法满足子类需求时,可在子类中定义和父类相同的方法进行覆盖(override)
方法覆盖原则
方法名称、参数列表、返回值类型必须与父类相同,返回值类型或者是他的子类
访问修饰符可与父类相同或是比父类更广泛
方法覆盖的执行
子类覆盖父类方法后,调用时优先执行子类覆盖后的方法
方法重写是带有约束的
方法名被约束了,参数列表、返回值也被约束了
保证了所有子类都可以使用相同的方法
保证了所有子类都可以使用相同的方法
super关键字
在子类中,可以通过super.的形式访问父类的属性和方法,可解决一定的属性遮蔽、方法覆盖后的父类成员调用问题
super()或super(实参)表示在子类代码的首行调用父类的构造方法
在子类的方法中使用super.的形式访问父类的属性和方法
注意
如果在子类构造方法中,没有显示定义super()或super(实参),则默认提供super()
同一个子类构造方法中,super()、this()不可同时存在
对象创建,
在具有继承关系的对象创建中,构建子类对象会先构建父类对象
由于父类的共性内容,叠加子类的都有内容组合成完整的子类对象
创建流程
构建父类对象
初始化自身属性
执行构造方法中的逻辑代码
父类的构造方法,用private修饰的属性和方法,其他包默认值修饰的都不可以被继承
多态
概念:父类引用指向子类对象,从而产生多种形态
二者之间具有直接或间接的继承关系时,父类引用可指向子类对象,即形成多态
父类引用仅可调用父类所声明的属性和方法,不可调用子类独有的属性和方法
多态中的方法覆盖
实际运行过程中,依旧遵循覆盖原则,如果子类覆盖了父类中的方法,则执行子类中覆盖后的方法,否则执行父类中的方法
使用方法
场景一:使用父类作为方法形参,实现多态
调用方法时,可传递的实参类型包括:本类型对象+其所有的子类对象
场景二:使用父类作为方法返回值实现多态,是方法可以返回不同子类对象
调用方法后,可得到的结果类型包括:本类型对象+其所有的子类对象。
向上转型(装箱)
父类引用中保存真实子类对象,称为向上转型(即多态核心概念)
注意:仅可调用父类中所声明的属性和方法
向下转型(拆箱)
将父类引用中的真实子类对象,强转回子类本身类型,称为向下转型
向下转型时,如果父类引用中的子类对象类型和目标类型不匹配,则会发生类型转换异常
instanceof
向下转型前,应判断引用中对象的真实类型,保证类型转换的正确性
语法 父类引用 instanceof 类型//返回Boolean类型结果
作用
屏蔽子类间的差异
灵活,耦合度低
抽象
抽象类
应用场景,
你的类不想被实例,不想被new出来
你需要定义抽象方法的时候
你判断我们要做的业务功能或者说这个类后面开发会使用到抽象方法的时候
按生活中没有实际存在的时候,就可以考虑把他作为抽象类
抽象方法
应用场景
在抽象类中父类必须满足一个条件
当你发现这个方法不是大部分的子类都适用的时候
当你发现这个方法是所有子类都必须要完成的方法,即必须要重写实现的时候
abstract:
意思:抽象的,似是而非的,像却又不是,具备某种对象的特征,但不完整
修饰类,意为不够完整,不够具体,不该独立存在
即为抽象类不可以独立new对象
可以被子类继承对子类提供共性的属性和方法
可声明引用,更纯粹的使用多态
访问修饰符
private 本类
不能设置类为私有类
default本类,同包
protected 本类,同包,非同包子类
也不可以使用受保护的类
public 本类,同包,非同包子类,其他
static(静态)
与实例的区别
实例属性是每个对象各自持有的独立空间(多份),对象单方面修改,不会影响其他对象
静态属性是整个类共同持有的共享空间(一份),任何对象修改都会影响其他对象
概念
static可以修饰属性和方法,即为静态属性(类属性)、静态方法(类方法)
静态成员是全类所有对象共享的,全类只有一份,不因创建多个对象而产生多份
不必创建对象,也可通过类名,直接访问静态成员
经验:访问静态属性和方法时,可直接通过”类名.静态属性名“以及”类名。静态方法名“(推荐)
特点
静态方法允许直接访问静态成员
静态方法不能直接访问非静态成员
静态方法中不允许使用this或super关键字
静态方法可以继承,不能覆盖没有多态
类加载
jvm首次使用某个类时,将该类的.class文件加载到内存中进行保存
加载时机
创建对象
创建子类对象
调用静态属性和方法
class.forName("全限定名");//主动的加载一个类
静态代码块
类加载时,触发静态代码块的执行(仅一次)
执行地位:静态属性初始化之后
作用:可为静态属性赋值,或必要的初始行为
总结
static修饰的成员为静态成员,无需创建对象,可直接通过类名范围跟
静态方法不能直接访问非静态成员
静态方法中不可以使用this和super
静态方法可以继承、不能重写、没有多态
静态代码块在类加载时被执行,且只执行一次
final
修饰类:此类不可以被继承
修饰方法:此方法不能被覆盖
修饰变量:此变量不可改变即常量(无初始值、只允许赋值依次)
局部常量:显示初始化
实例常量的赋值:显式初始化,动态代码块、构造方法
实例常量赋值最终期限:在构造方法完成之前为实例常量赋值即可
如果在构造方法中为实例常量赋值,必须保证所有的构造方法都可正确赋值
不同常量类型的特点
基本数据类常量:值不可变
引用数据类型常量:地址不可变
面向对象思想:世界是由无数个对象组成的。
对象是什么:一切客观存在的事物都是对象,万物皆对象
初期:看得见摸得着真实存在
任何对象一定有自己的特征和行为
特征:称之为属性一般为名词,代表对象都有什么
行为:称之为方法,一般为动词,代表对象能做什么
比如手机
分析一个对象有什么(属性)
颜色
品牌
价格
型号
重量
尺寸
材质
品牌
价格
型号
重量
尺寸
材质
分析一个对象能做什么(方法)
打电话(拨号->发射)
拍照
上网(app聊天、游戏)
拍照
上网(app聊天、游戏)
接口
概念:接口相当于特殊的抽象类,定义方式、组成部分与抽象类类似。使用interface关键字定义
接口。
接口。
微观概念
接口是一种能力和约定
接口的定义:代表了某种能力
方法的定义:能力的具体要求
经验
接口支持多实现、可为类扩充多种能力
Java为单继承,当父类的方法种类无法满足子类需求时可实现接口扩充子类能力
宏观概念
接口是一种标准
耦合度:模块与模块之间的关联程度,关联的越密切,耦合度越高,关联的越松散,耦合越低
特点
没有构造方法,不可以创建对象
只能定义:公开静态常量、公开抽象方法
与抽象类的区别
相同点
可编译成字节码文件
不能创建对象
可以作为引用类型
具备object类中所定义的方法
不同点
所有属性都是公开静态常量、隐式使用pubic static final修饰
所有方法都是公开抽象方法、隐式使用public abstract
没有构造方法、动态代码块、静态代码块
规范
任何类在实现接口时,必须实现接口中所有的抽象方法,否则此类为抽象类
实现接口中的抽象方法时,访问修饰符必须是public,具体原因参考方法重写
引用
同父类一样,接口也可以声明为引用,并指向实现类对象
注意
仅可调用接口中所声明的方法,不可调用实现类中独有的方法
可强转回实现类的本身类型,进行独有的属性和方法的调用(强转前通过instanceof判断)
多态
与继承的多态不同,继承关注类型,接口则关注行为
常见关系
类与类:单继承,extends 父类名称
类与接口:多实现,implements 接口名称1、接口名称2、。。。
接口与接口:多继承,extends 父接口名称1、父接口名称2、、、
常量接口
将多个常用于表示状态和固定值的变量,以公开静态常量的形式定义在接口中统一管理,提高代码的可读性
接口回调原理
先有接口的使用者,后有接口的实现者
java与数据库技术
数据库基本概念
引言
现有的数据存储方式有哪些
Java程序存储数据(变量、对象、数组、集合),数据保存在内存中,属于瞬时状态存储
文件(file)存储数据,保存在硬盘上,属于持久状态存储
以上存储方式存在哪些缺点
没有数据类型的区分
存储数据量级较小
没有访问安全限制
没有备份、恢复机制
数据库
概念
数据库是"按照数据结构来组织、存储和管理数据的仓库、是一个长期存储在计算机内的、有组织的、有共享的、统一管理的数据集合"
数据库的分类
网状结构数据库:美国通用电气公司IDS,以节点形式存储和访问
层次结构数据库:IBM公司IMS定向有序的树状结构实现存储和访问
关系结构数据库:Oracle、DB2、MySQL、SQL Server,以表格存储,多表间建立关联方式,通过分类、合并、连接、选取等运算实现访问
非关系型数据库:ElastecSearch、MongoDB、Redis,多数使用哈希表,表中以键值对的方式实现特定的键和一个指针指向的特定数据
数据库管理系统
概念
数据库管理系统(DBMS):指一种操作和管理数据库的大型软件,用于建立、使用和维护数据库,
对数据库进行统一管理和控制,以保证数据库的安全性和完整性。用户通过数据库管理系统访问数据库中的数据
对数据库进行统一管理和控制,以保证数据库的安全性和完整性。用户通过数据库管理系统访问数据库中的数据
常见数据库管理系统
Oracle:被认为是业界目前比较成功的关系型数据库管理系统。Oracle数据库可以运行在Unix、Windows等
主流操作系统平台,完全支持所有的工业标准,并获得最高级别的ISO标准安全性认证
主流操作系统平台,完全支持所有的工业标准,并获得最高级别的ISO标准安全性认证
DB2:IBM公司的产品,DB2数据库系统采用多线程多线索体系结构,其功能足以满足大中公司的需要,并可灵
活的服务于中小型电子商务解决方案
活的服务于中小型电子商务解决方案
SQL Server:Microsoft公司推出的关系型数据库管理系统,具有使用方便可伸缩性好与相关软件集成程度高等优点
SQLLITE:应用在手机端的数据库
MySQL(触发器还没写完)
简介:MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,属于Oracle旗下产品
MySQL是最流行的关系型数据库管理系统之一,在web应用方面,MySQL是最好的RDBMS
(关系数据库管理系统)应用软件之一
MySQL是最流行的关系型数据库管理系统之一,在web应用方面,MySQL是最好的RDBMS
(关系数据库管理系统)应用软件之一
官网:http://www.mysql.com/
下载地址:http://www.mysql.com/downloads/mysql/
下载地址:http://www.mysql.com/downloads/mysql/
SQL语言
概念:SQL结构化查询语言,用于存取数据、更新、查询和管理关系数据库系统的程序设计语言
经验:通常执行对数据库的增删改查,简称C(Create)R(Read)U(Update)D(Delete)
MySQL应用
对于数据库的操作,需要在进入MySQL环境下进行指令输入,并在一句指令的末尾使用;结束
基本命令
mysql>SHOW DATABASES;显示当前MySQL中包含的所有数据库
数据库名称
information_schema:信息数据库其中保存着关于所有数据库的信息(元数据)
元数据是关于数据的数据,如数据库名或表明,列的数据类型、或访问权限等
元数据是关于数据的数据,如数据库名或表明,列的数据类型、或访问权限等
mysql:核心数据库,主要负责存储数据库的用户、权限设置、关键字等,
以及需要使用的控制和管理信息,不可以删除
以及需要使用的控制和管理信息,不可以删除
performance_schema:性能优化的数据库,MySQL5.5版本中新增的一个性能优化的引擎
sys:系统数据库,MySQL5.7版本中新增的可以快速了解元数据信息的系统库
便于发现数据库的多样信息,解决性能瓶颈问题
便于发现数据库的多样信息,解决性能瓶颈问题
客户端工具
Navicate
Navicate是一套快速、可靠并价格相宜的数据库管理工具,专为简化数据库的管理及降低系统管理成本而设
他的设计符合数据库管理员、开发人员及中小企业的需要、Navicate是以直觉化的图形用户界面而建的,
让你可以以安全并且简单的方式创建、组织、访问并共用信息
他的设计符合数据库管理员、开发人员及中小企业的需要、Navicate是以直觉化的图形用户界面而建的,
让你可以以安全并且简单的方式创建、组织、访问并共用信息
SQLyog
MySQL可能是世界上最流行的开源数据库引擎,但是使用基于文本的工具和配置文件可能很难进行管理
SQLyog提供了完整的图形界面,即使初学者也可以轻松使用MySQL的强大功能。其拥有广泛的预订义
工具和查询、友好的视觉界面、类似Excel的查询结果编辑界面的等优点
SQLyog提供了完整的图形界面,即使初学者也可以轻松使用MySQL的强大功能。其拥有广泛的预订义
工具和查询、友好的视觉界面、类似Excel的查询结果编辑界面的等优点
SQL语句编写顺序
select 列名
from 表名
where 条件
group by 分组
having 过滤条件
order by 排序列(ASC|DESC)
limit 起始行,总条数
from 表名
where 条件
group by 分组
having 过滤条件
order by 排序列(ASC|DESC)
limit 起始行,总条数
SQL语句执行顺序
FROM:指定数据来源表
where:对查询数据做第一次过滤
group by 分组
having 对分组后的数据进行第二次过滤
select 查询各字段的值
order by 排序
limit 限定查询结果
where:对查询数据做第一次过滤
group by 分组
having 对分组后的数据进行第二次过滤
select 查询各字段的值
order by 排序
limit 限定查询结果
约束
实体完整性约束
表中的一行数据代表一个实体,实体完整性的作用即是标识每一行数据不重复、实体唯一
主键约束
primary key 唯一,标识表中的一行数据,此列的值不可重复,且不能为null
唯一约束
unique 唯一,标示表中的一行数据,不可重复,可以为null
自动增长列
auto_increment 自动增长,给主键数值列添加自动增长,从1开始,每次加1,不能单独使用,必须和主键配合
域完整性约束
限制列的单元格的数据正确性
非空约束
not null 非空,此列必须有值
默认值约束
default 值 为此列赋予默认值,当新增数据不
指定值时,书写default,已制定的默认值进行填充
指定值时,书写default,已制定的默认值进行填充
引用完整性约束
constraint 引用名 foreign key(列名) references 被引用表名(列名)
foreign key引用外部表的某个列的值,新增数据时,约束此列的值必须时引用表中存在的数据
foreign key引用外部表的某个列的值,新增数据时,约束此列的值必须时引用表中存在的数据
注意当两张表存在引用关系时,要执行删除操作,一定要先删除从表(引用表),再删除主表(被引用表)
创建关系表时,一定要先创建主表,在创建从表
事务
事务是一个原子操作,是一个最小执行单元,可以由一个或多个SQL语句组成,在同一个事务当中
所有的SQL语句都成功执行时,整个事务成功,有一个SQL语句执行失败,整个事务都执行失败
所有的SQL语句都成功执行时,整个事务成功,有一个SQL语句执行失败,整个事务都执行失败
事务的边界
开始:连接到数据库,执行一条dml语句,上一个事务结束后,以后输入了一条dml语句,即事务的开始
结束:1.提交1.1显示提交:commit 1.2隐式提交:一条创建、删除的语句,正常退出(客户端推出连接)
2.回滚:2.1显示回滚:rollback;2.2隐式回滚:非正常退出(断电,宕机),执行了创建、删除的语句,但是失败了
会为这个无效的语句执行回滚
2.回滚:2.1显示回滚:rollback;2.2隐式回滚:非正常退出(断电,宕机),执行了创建、删除的语句,但是失败了
会为这个无效的语句执行回滚
原理:数据库会为每一个客户都维护一个空间独立的缓存区(回滚段),
一个事务中所有的增删改语句的执行结果都会缓存在回滚段中
,只有事务中所有的sql语句均正常结束(commit),才会将回滚段中
的数据同步到数据库,否则无论因为哪种原因失败,整个事务将回滚
一个事务中所有的增删改语句的执行结果都会缓存在回滚段中
,只有事务中所有的sql语句均正常结束(commit),才会将回滚段中
的数据同步到数据库,否则无论因为哪种原因失败,整个事务将回滚
事物的特性
atomicity(原子性)
表示一个事务内的所有操作是一个整体,要么全部成功要么全部失败
consistency(一致性)
表示一个事务内有一个操作失败时,所有更改过得数据都必须回到修改前状态
lsolation(隔离性)
事务查看数据操作时数据所处的状态,要么是另一并发事务修改它之前的状态,要么
是另一事务修改它之后的状态,事务不会查看中间状态的数据
是另一事务修改它之后的状态,事务不会查看中间状态的数据
Durability(持久性)
持久性事务完成之后,他对系统的影响是永久性的
SQL语言分类
数据查询语言DQL
查看当前所使用的数据库
mysql>select database() 查看当前使用的数据库
数据查询语言DQL基本结构是由SELECT子句,FROM子句,WHERE子句组成的查询块:
SELECT <字段名表> FROM <表或视图名> WHERE <查询条件>
SELECT <字段名表> FROM <表或视图名> WHERE <查询条件>
重点:数据查询
数据库表的基本结构
关系结构数据库是以表格进行数据存储,表格有行和列组成
经验:执行查询语句返回的结果集是一张虚拟表
基本查询
基本理解
语法:SELECT列名 FROM表名
关键字
SELECT:指定要查询的列
FROM:指定要查询的表
注意
生产环境下,优先使用列名查询
*的方式需转换成全列名,效率低,可读性差
运算符与java一样区别在于%是占位符并非模运算
别名
列 AS '别名'
也可以AS换成空格
查询结果去重
distinct 列名
排序查询
对查询的结果进行排序
语法SELCET 列名 FROM 表名 ORDER BY 排序列[排序规则]
排序规则
asc:升序
desc:降序
可以多列排序每个以逗号隔开,每个条件都有单独的排序规则
条件查询
语法:SELECT 列名 FROM 表名 WHERE 条件
注意与java不同,mysql中等值判断使用=
逻辑判断:AND,OR,NOT(与或非)
不等值判断(>,<,>=,<=,!=,<>)
判断不等于优先使用<>
判断不等于优先使用<>
区间判断(BETWEEN 小值 AND 大值)
区间判断小值在前,大值在后,反之得不到正确结果
区间判断小值在前,大值在后,反之得不到正确结果
null值判断
列名 is null
列名 is not null
枚举查询 (in(值1,值2,值3))
注意in 的查询效率较低,可以通过多条件拼接
注意in 的查询效率较低,可以通过多条件拼接
模糊查询(LIKE 通配符)
列名 LIKE '_'单个任意字符
列名 LIKE '%'多个任意字符
注意:模糊查询只能和like关键字结合使用
分支结构查询
语法:case when条件一 then结果一else 结果2end
通过使用case end进行条件判断,每条数据对应一个结果
类似java中的多重选择结构
时间查询
语法select 时间函数(参数列表)
sysdate:当前系统时间
curdate:获取当前日期
curtime:获取当前时间
week(date()):获取为一年中的第几周
year(date):获取年份
hour(time())获取小时
minute(time)获取分钟
datediff(date1,date2)获取之间相隔的天数
adddate(date,n)计算时间加上n天之后的日期
执行时间函数查询,会自动生成一张虚拟表(一行一列)
字符串查询
select 字符串函数([参数列表])
concat(str1,str2,...)将多个字符串连接
insert(str,pos,len,newStr)讲str中pos位置开始len长度的内容替换为newstr
lower转小写
upper转大写
substring(str,num,len)讲str字符串指定num位置开始截取len个字符
执行字符串函数查询会自动生成一张虚拟表(一行一列)
聚合函数
select 聚合函数(列名) from表名
sum():求所有行中单列结果的综合
avg():平均值
max()最大值
min()最小值
count():总行数
会自动生成一张虚拟表
分组查询
select 列名 from 表名 where 条件 group by 分组依据(列)
分组查询中,select显示的列只能是分组依据列,或者聚合函数列,不能出现其他列
分组过滤查询
select 列名 from 表名 where 条件 group by 分组依据(列) having 过滤规则
having 是对分组之后的数据做过滤
限定查询
select 列名 from 表名 limit 起始行,查询行数
起始行是从0开始,代表第一行,第二个参数代表的是从指定行开始查询几行
子查询
作为条件判断
select 列名 from 表名 where 条件(子查询结果)
一行一列的结果才能作为外部查询的等值判断或不等值条件判断
作为枚举查询条件
select 列名 from 表名 where 列名 in(子查询结果)
将子查询多行一列的结果作为外部查询的枚举查询条件,做第二次查询
当子查询结果集形式为多行单列时可以使用any或all关键字
作为一张表
select 列名 from (子查询的结果集) where 条件
将子查询多行多列的结果作为外部查询的一张表作第二次查询
子查询作为临时表必须为其赋予一个临时表名
合并查询(了解)
合并两张表的结果(去除重复数据,有默认排序效率低)
select *from t1 union select *from t2
合并两张表的结果(保留重复记录,无默认排序效率高)
select *from t1 union all select *from t2<br>
注意:合并结果的两张表,列数必须相同,列的数据类型可以不同
使用union合并结果集,会去除掉两张表中的重复的数据
表连接查询
select 列名 from 表1 连接方式 表2 on 连接条件
内连接查询(inner join on)
sql标准
select *from 表1 inner join 表2 on 条件
select *from 表1 inner join 表2 on 条件
mysql标准
select *from 表1 ,表2 where 条件
select *from 表1 ,表2 where 条件
SQL标准其他数据库通用
多表连接查询:套娃
左外连接(left join on)
以左表为主表,依次向右匹配,匹配到,返回结果,反之以null值填充
右外连接(right join on)
以右表为主表,依次向左匹配,匹配到,返回结果,反之以null值填充
select,where,order by,group by,having
数据定义语言DDL
数据定义语言DDL用来创建数据库中的各种对象-----表、视图、索引、同义词、聚簇等如:
CREATE TABLE/VIEW/INDEX/SYN/CLUSTER
CREATE TABLE/VIEW/INDEX/SYN/CLUSTER
数据定义语言,这些语句定义了不同的数据段、数据库、表、列、索引等数据库对象的定义。
常用的语句关键字主要包括 create、drop、alter等
常用的语句关键字主要包括 create、drop、alter等
创建自定义数据库
mysql>CREATE DATABASE mydb1:创建mydb数据库
mysql>CREATE DATABASE mydb2 CHARACTER SET gbk:创建数据库并设置编码格式为gbk
mysql>CREATE DATABASE IF NOT EXISTS mydb4:如果mydb4数据库不存在,则创建,反之则不创建
查询数据库创建信息
mysql> SHOW CREATE DATABASE mydb2:查看创建数据库时的基本信息
数据表操作
数据类型
mysql支持多种类型,大致分为三类:数值,日期时间和字符串字符类型,对于我们约束数据有很大帮主
数值类型:int ,double,decimal
日期类型:date(yyyy-mm-dd) time(hh:mm:ss) year(yyyy)
datetime(yyyy-mm-dd hh:mm:ss) timestamp(yyyymmddhhmmss)
datetime(yyyy-mm-dd hh:mm:ss) timestamp(yyyymmddhhmmss)
字符串类型:char(定长字符串)varchar(变长字符串)
blob(二进制长文本数据,图片等等)text(长文本数据)
blob(二进制长文本数据,图片等等)text(长文本数据)
char与varchar类型类似,但他们保存和检索的方式不同,他们最大长度和是否尾部空格被保留等方面也不同
在存储或检索过程中不进行大小写转换
在存储或检索过程中不进行大小写转换
bolo是一个二进制大对象,可以容纳可变数量的数据有四种类型
tinyblob,blob,mediumblob,longblob,只是容纳长度不同
tinyblob,blob,mediumblob,longblob,只是容纳长度不同
数据表的创建(create)
create table表名(列名 数据类型 [约束])[charset utf8]
注意最后一列末尾不加都好,可以根据需要指定表的字符编码集
数据表的修改(ALTER)
alter table 表名 操作
add增加
modify修改
修改表中的某列时,也要些全列的名字,数据类型,约束
修改表中的某列时,也要些全列的名字,数据类型,约束
drop删除
删除列时,每次只能删除一列
删除列时,每次只能删除一列
change修改列名
修改列名时,再给定新列名称时,要指定列的类型和约束
修改列名时,再给定新列名称时,要指定列的类型和约束
rename修改表名
数据表的删除(drop)
drop table 表名
数据操纵语言DML
数据操纵语句,用于添加、删除、更新和查询数据库记录,并检查数据完整性,
常用的语句关键字主要包括 insert、delete、udpate 和select 等。(增添改查)
常用的语句关键字主要包括 insert、delete、udpate 和select 等。(增添改查)
数据操纵语言DML主要有三种形式:
1) 插入:INSERT
2) 更新:UPDATE
3) 删除:DELETE
主要对数据库数据进行写入和读取
1) 插入:INSERT
2) 更新:UPDATE
3) 删除:DELETE
主要对数据库数据进行写入和读取
基本语法
概念
DML:数据操作语言
对数据表的增,删,改操作
插入
insert into 表名(列1,列2,列3...) values(值1,值2,值3...)
注意:表名后的列名和values里的值要一一对应(个数,顺序,类型)
更新
update 表名 set 列1 =新值1....where条件
set后多个列名=值
绝大多数情况下都要加where条件指定修改,否则为整表更新
删除
delete from 表名 where条件
删除时,如不加where删除的是整张表的数据
事务处理语言TPL
commit rollback提交与回滚
数据控制语言DCL
crant ,revork 授权与取消
数据控制语言DCL用来授予或回收访问数据库的某种特权,并控制数据库操纵事务发生的时间及效果,对数据库实行监视等。如:
1) GRANT:授权。
2) ROLLBACK [WORK] TO [SAVEPOINT]:回退到某一点。
回滚---ROLLBACK
回滚命令使数据库状态回到上次最后提交的状态。其格式为:
SQL>ROLLBACK
1) GRANT:授权。
2) ROLLBACK [WORK] TO [SAVEPOINT]:回退到某一点。
回滚---ROLLBACK
回滚命令使数据库状态回到上次最后提交的状态。其格式为:
SQL>ROLLBACK
视图
视图即虚拟表,从一个表或多个表中查询出来的表,作用和真实表一样
作用
作用和真实表一样,包含一系列带有行和列的数据
视图中,用户可以使用select语句查询数据,也可以使用dml操作记录
视图可以使用户操作方便,并保障数据库安全
优缺点
优点
简单化,数据所见即所得
安全性,用户只能查询或修改他们所能见得到的数据
缺点
性能相对较差,简单的查询也会变得稍显复杂
修改不方便,特别是复杂的聚合视图基本无法修改
与存储过程一样移植性较差
创建视图
create view 视图名 AS 查询数据源表语句
修改
alter view 视图名 as 修改后的查询语句
create view 视图名 AS 查询数据源表语句
如果视图存在则替换,反之新建
如果视图存在则替换,反之新建
删除
drop view 视图名
注意:视图的删除不会影响原表
注意事项
视图不会独立存储数据,原表发生改变,视图也会发生改变
没有优化任何查询性能
如果视图包含以下结构中的一种,则视图不可更新
聚合函数,distinct去重后的结果,group by分组后的结果
having 筛选过滤后的结果 union,union all 联合后的结果
having 筛选过滤后的结果 union,union all 联合后的结果
SQL编程(存储过程)
什么是存储过程
mysql 5.0版本开始支持存储过程
存储过程是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象
他是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户
可通过指定存储过程的名字并给定参数(需要时)来调用执行
可通过指定存储过程的名字并给定参数(需要时)来调用执行
存储过程思想上较为简单,就是数据库SQL语言层面的代码封装与重用
存储过程的创建与调用
存储过程就是具有名字的一段代码,用来完成一个特定的功能
创建的存储过程保存在数据库的数据字典中
存储过程体
存储过程体包含了在过程调用时必须执行的语句,例如dml,ddl语句
if-then-else和while-do语句、声明变量的declare语句等
if-then-else和while-do语句、声明变量的declare语句等
过程体格式:以begin开始,以end结束(可嵌套)
其中每个嵌套块及其中的每条语句,必须以分号结束,表示过程体结束的begin-end块
又叫符合语句compound statement,则不需要分号
又叫符合语句compound statement,则不需要分号
关键语法
基本使用语法示例
#定义结束符号为$$
DELIMITER $$
#声明存储过程
CREATE PROCEDURE demo()
#开始结束符号
BEGIN
#声明变量
DECLARE v_name VARCHAR(20);
DECLARE v_salary DOUBLE(10,2);
#给变量设值
SET v_name = '张三';
SET v_salary = 12000;
#使用变量
SELECT v_name;
SELECT v_salary;
END $$
DROP PROCEDURE demo;
#调用存储过程
CALL demo();
DELIMITER $$
#声明存储过程
CREATE PROCEDURE demo()
#开始结束符号
BEGIN
#声明变量
DECLARE v_name VARCHAR(20);
DECLARE v_salary DOUBLE(10,2);
#给变量设值
SET v_name = '张三';
SET v_salary = 12000;
#使用变量
SELECT v_name;
SELECT v_salary;
END $$
DROP PROCEDURE demo;
#调用存储过程
CALL demo();
关键字解析
DELIMITER:定义结束符号
CREATE PROCEDURE:声明存储过程与名字类似java的方法声明
begin开始符号类似java方法的{
DECLATE 声明变量
SET 给变量设置
end结束符号类型java方法的}
调用存储过程需要使用call关键字
声明语句结束符可以使用delimiter来自定义
使用create procedure 存储过程名()来声明
结束符:默认情况下mysql的命令是以分号结束的,当在遇到mysql时,就会执行命令
mysql中的delimiter会告诉mysql解释器,命令的结束符是什么,然后mysql解释器,当碰到
delimiter指定的结束符才会开始执行命令
因为存储过程中会使用大量sql可能会有很多分号结束符,不能让mysql在中间就执行sql,
所以才需要自定义结束符
mysql中的delimiter会告诉mysql解释器,命令的结束符是什么,然后mysql解释器,当碰到
delimiter指定的结束符才会开始执行命令
因为存储过程中会使用大量sql可能会有很多分号结束符,不能让mysql在中间就执行sql,
所以才需要自定义结束符
优缺点
优点
存储过程可封装,并隐藏复杂的商业逻辑
存储过程可以回传值,并可以接受参数
存储过程无法使用select指令来运行,因为他是子程序,
与查看表,数据表或用户定义函数不同
与查看表,数据表或用户定义函数不同
存储过程可以用在数据检验,强行实行商业逻辑等。
缺点
存储过程往往定制化与特定的数据库上,因为支持的编程语言不同,当
切换到其他厂商的数据库系统时,需要重写原有的存储过程,移植性较差
切换到其他厂商的数据库系统时,需要重写原有的存储过程,移植性较差
存储过程的性能调校与撰写,受限于各种数据库系统
存储过程的变量
局部变量
变量定义:局部变量声明一定要放在存储过程体的开始
通过declare 变量名 数据类型声明变量通过set来给变量赋值
作用范围为存储过程的begin到end语句块之间
用户变量
变量名需要使用@开头
可以直接使用set声明并赋值,默认值为null
跟mysql客户端是绑定的,设置的变量,只对当前用户使用的客户端生效也叫会话变量
作用范围为mysql客户端
存储过程的参数
mysql存储过程的参数用在存储过程的定义,共有三种参数类型,in,out,inout,形式
存储过程名(in | out | inout ) 参数名 数据类型
in输入参数:表示调用者向过程传入值(传入值可以是字面量或变量)
out输出参数:表示过程向调用者传出值(可以返回多个值)(传出值只能是变量)
inout输入输出参数:即表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量)
mysql还不提供对已存在的存储过程的代码修改,只能先删然后重新创建
流程控制
条件判断
if-then-else
示例DELIMITER $$
CREATE PROCEDURE demo9(IN num DOUBLE)
BEGIN
DECLARE result VARCHAR(20);
IF num > 10000
THEN SET result='有钱人';
ELSEIF num>5000
THEN SET result='一般人';
ELSESET result='穷人';
-- if结束一定要写end if 每个分支都有;结束
END IF;
SELECT result;
END $$
CALL demo9(8000);
CREATE PROCEDURE demo9(IN num DOUBLE)
BEGIN
DECLARE result VARCHAR(20);
IF num > 10000
THEN SET result='有钱人';
ELSEIF num>5000
THEN SET result='一般人';
ELSESET result='穷人';
-- if结束一定要写end if 每个分支都有;结束
END IF;
SELECT result;
END $$
CALL demo9(8000);
case、
等值判断示例
DELIMITER $$
CREATE PROCEDURE demo10(IN num INT)
BEGIN
DECLARE result VARCHAR(20);
CASE num
WHEN 1 THEN SET result = '星期一';
WHEN 2 THEN SET result = '星期二';
WHEN 3 THEN SET result = '星期三';
WHEN 4 THEN SET result = '星期四';
WHEN 5 THEN SET result = '星期五';
WHEN 6 THEN SET result = '星期六';
ELSE SET result = '星期七';
END CASE;
SELECT result;
END $$
CALL demo10(4);
DELIMITER $$
CREATE PROCEDURE demo10(IN num INT)
BEGIN
DECLARE result VARCHAR(20);
CASE num
WHEN 1 THEN SET result = '星期一';
WHEN 2 THEN SET result = '星期二';
WHEN 3 THEN SET result = '星期三';
WHEN 4 THEN SET result = '星期四';
WHEN 5 THEN SET result = '星期五';
WHEN 6 THEN SET result = '星期六';
ELSE SET result = '星期七';
END CASE;
SELECT result;
END $$
CALL demo10(4);
不等值判断示例
DELIMITER $$
CREATE PROCEDURE demo10(IN num INT)
BEGIN
DECLARE result VARCHAR(20);
CASE
WHEN num=1 THEN SET result = '星期一';
WHEN num=2 THEN SET result = '星期二';
WHEN num=3 THEN SET result = '星期三';
WHEN num=4 THEN SET result = '星期四';
WHEN num=5 THEN SET result = '星期五';
WHEN num=6 THEN SET result = '星期六';
ELSE SET result = '星期七';
END CASE;
SELECT result;
END $$
CALL demo10(4);
DELIMITER $$
CREATE PROCEDURE demo10(IN num INT)
BEGIN
DECLARE result VARCHAR(20);
CASE
WHEN num=1 THEN SET result = '星期一';
WHEN num=2 THEN SET result = '星期二';
WHEN num=3 THEN SET result = '星期三';
WHEN num=4 THEN SET result = '星期四';
WHEN num=5 THEN SET result = '星期五';
WHEN num=6 THEN SET result = '星期六';
ELSE SET result = '星期七';
END CASE;
SELECT result;
END $$
CALL demo10(4);
循环语句
while...end while
示例
DELIMITER $$
CREATE PROCEDURE demo12(IN num INT)
BEGIN
--设置循环初始化
DECLARE num INT DEFAULT 1;
DECLARE word VARCHAR(50) DEFAULT '1';
--设置循环条件
WHILE num<10
DO
--循环迭代
SET num = num +1;
SET word=CONCAT(word,'-',num);
--离开循环
END WHILE;
SELECT word;
END $$
CALL demo12(10);
DELIMITER $$
CREATE PROCEDURE demo12(IN num INT)
BEGIN
--设置循环初始化
DECLARE num INT DEFAULT 1;
DECLARE word VARCHAR(50) DEFAULT '1';
--设置循环条件
WHILE num<10
DO
--循环迭代
SET num = num +1;
SET word=CONCAT(word,'-',num);
--离开循环
END WHILE;
SELECT word;
END $$
CALL demo12(10);
loop.....endloop
示例
DELIMITER $$
CREATE PROCEDURE demo13(IN num INT)
BEGIN
DECLARE num INT DEFAULT 1;
DECLARE word VARCHAR(50) DEFAULT '1';
--设置循环 取名
f_loop:LOOP
--迭代
SET num = num +1;
SET word=CONCAT(word,'-',num);
--判断如果小于10就继续
IF num < 10 THEN ITERATE f_loop;
END IF;
--执行打断 否则死循环
LEAVE f_loop;
--结束循环语句
END LOOP;
SELECT word;
END $$
CALL demo13(10);
DELIMITER $$
CREATE PROCEDURE demo13(IN num INT)
BEGIN
DECLARE num INT DEFAULT 1;
DECLARE word VARCHAR(50) DEFAULT '1';
--设置循环 取名
f_loop:LOOP
--迭代
SET num = num +1;
SET word=CONCAT(word,'-',num);
--判断如果小于10就继续
IF num < 10 THEN ITERATE f_loop;
END IF;
--执行打断 否则死循环
LEAVE f_loop;
--结束循环语句
END LOOP;
SELECT word;
END $$
CALL demo13(10);
iterate相当于java的continue
leave相当于java的break
leave相当于java的break
游标
什么是游标
要处理存储过程中的结果集,请使用游标
游标可以获得结果集,逐行进行处理,相当于java的iterator
MySQL游标为只读,不可滚动和敏感
只读:无法通过游标指针更新修改表中的数据
不可滚动:只能按照select语句确定的顺序获取行,不能反顺序获取行,不能跳过行或跳到结果集中的其他行
敏感:有两种游标:敏感游标和不敏感游标。敏感游标指向实际数据,不敏感游标使用数据的临时副本。
敏感游标比一个不敏感的游标执行得更快,因为它不需要临时拷贝数据。MySQL游标是敏感的。
敏感游标比一个不敏感的游标执行得更快,因为它不需要临时拷贝数据。MySQL游标是敏感的。
游标语法
声明游标
declare 游标名 cursor for 查询声明(查询哪张表)
注意:游标声明必须在变量声明之后。如果在变量声明之前声明游标,
MySQL将会发出一个错误。游标必须始终与select语句相关联。
MySQL将会发出一个错误。游标必须始终与select语句相关联。
处理not found情况
declare continue handler for not fount set 变量名 = 1 为产生的notfound进行赋值作为结束条件
在mysql中必须声明一个not found条件判断来处理,游标找不到任何行时的情况。
在每次调用fetch语句时,游标会尝试读取结果集中的下一行。
当游标到达结果集的末尾时,它将无法获得数据并产生一个notfound
在每次调用fetch语句时,游标会尝试读取结果集中的下一行。
当游标到达结果集的末尾时,它将无法获得数据并产生一个notfound
打开游标
open 游标名
open语句初始化游标的结果集,因此你必须在从结果集中提取行之前调用open语句
检索游标指向数据行
fetch 游标名 into 提取的变量名
fetch语句来检索游标指向的下一行,并将游标移动到结果集中的下一行,
以检查是否有任何行记录可用,然后再提取它
以检查是否有任何行记录可用,然后再提取它
fetch相当于java的iterator里面的hasnext()
关闭游标
close 游标名
当游标不在使用时,应该使用close语句来停用游标并释放与之关联的内存
触发器
触发器是一种与表操作有关的数据库对象,当触发器所在表上出现指定事件时
将调用该对象,即表的操作事件触发表上的触发器的执行
将调用该对象,即表的操作事件触发表上的触发器的执行
类似JavaScript的事件
语法
创建触发器
create trigger 触发器名称
标识触发时机,取值为before或after
标识触发事件,取值为insert,update或delete
on 标识建立触发器的表名,即在哪张表上建立触发器
for each row
触发程序体,可以是一句SQL语句,或者用begin end包含的多条语句
标识触发时机,取值为before或after
标识触发事件,取值为insert,update或delete
on 标识建立触发器的表名,即在哪张表上建立触发器
for each row
触发程序体,可以是一句SQL语句,或者用begin end包含的多条语句
可以建立六种触发器 即:BEFORE INSERT、BEFORE UPDATE、
BEFORE DELETE、AFTER INSERT、AFTER UPDATE、AFTER DELETE
BEFORE DELETE、AFTER INSERT、AFTER UPDATE、AFTER DELETE
限制:不能同时在一个表上建立2个相同类型的触发器
jdbc
初识
概念
jdbc是java链接数据库的规范
使用jdbc完成crud操作
核心思想
Java中定义了访问数据库的接口,可以为多种关系型数据库提供统一的访问方式
由数据库厂商提供驱动实现类(Driver数据库驱动)
mysql数据库驱动
驱动:所有的数据库驱动都是以jar包的形式存在,jar包当中有很多.class文件
这些文件就是对jdbc接口的实现
驱动不是sun公司提供的,是各大数据库厂家负责提供,下载驱动jar包需要去数据库官网下载
这些文件就是对jdbc接口的实现
驱动不是sun公司提供的,是各大数据库厂家负责提供,下载驱动jar包需要去数据库官网下载
为什么sun制订一套jdbc接口呢
因为每一个数据库的底层实现原理都不一样
Oracle数据库有自己的原理
mysql等等都有自己的原理
mysql等等都有自己的原理
环境搭建
在项目下新建lib文件夹,用于存放jar文件
将mysql驱动mysql-connector-java-5.1复制到文件夹中
选中lib文件夹右键add as libraay点击ok
jdbc的本质
jdbc是sun公司制定的一套接口(interface)
接口都有调用者和实现者
面向接口调用、面向接口写实现类这都属于面向接口编程
为什么要面向接口编程?
解耦合:降低程序的耦合度,提高程序的扩展力
多态机制就是非常典型的面向抽象编程
开发步骤
1.注册驱动/加载驱动
使用Class.forname(“com.mysql.jdbc.driver”)手动加载字节码文件到JVM中
2.连接数据库
connection con = drivermanager.getconnection(url,username,password)
获取数据库连接对象
获取数据库连接对象
3.获取发送SQL的对象
statement s = con.createstatement()
通过connection对象获取statement对象
用于对数据库进行通用访问
通过connection对象获取statement对象
用于对数据库进行通用访问
4.执行SQL语句并接收结果
s.executeupdate(sql)//DML语句增删改,用int接收返回的是影响的行数
s.executequery(sql)//DQL语句查询,用resultset来接收查询的结果
注意:在编写dml语句时,一定要注意字符串参数的符号是单引号
5.处理结果
核心resultset.next()当获取到数据返回true
受影响行数:逻辑判断、方法返回
查询结果集:迭代、依次获取
6.释放资源
遵循先开后关原则,释放所使用的资源对象
resultset(结果集)
概念:在执行查询SQL后,存放查询到的结果集数据
接收结果集:resultset 名字 = statement.execuleQuery(sql)
注意:作用就是完成了查询结果的存储功能,而且只能读取一次,不能够来回的滚动读取
遍历resultset
resultset以表结构进行临时结果的存储,通过jdbc api将其中数据进行依次获取
方法
next() 返回值类型boolean
数据行指针,没调用一次,指针向下移动一行
结果为true,表示当前行有数据
数据行指针,没调用一次,指针向下移动一行
结果为true,表示当前行有数据
getstring(编号) 返回值类型string
代表根据列的编号顺序获得,从1开始
代表根据列的编号顺序获得,从1开始
getstring(列名) 返回值类型string
代表根据列名获得
代表根据列名获得
经验:getxx方法可以获取的类型有:基本数据类型和引用数据类型
常见错误
SQL注入
原因
用户输入的数据中有SQL关键字或语法并且参与了SQL语句的编译,导致SQL语句
编译后的条件含义为true,一直得到正确的结果,这种现象称为SQL注入
编译后的条件含义为true,一直得到正确的结果,这种现象称为SQL注入
如何避免
由于编写的SQL语句是在用户输入数据,整合后在进行编译
我们要使SQL语句在用户输入数据前就已编译成完整的SQL语句在进行填充数据
preparedstatement(定义预准备的对象)
概念
preparedstatement继承了statement接口,执行SQL语句的方法无异
作用
预编译SQL语句,效率高
安全,避免SQL注入
可以动态的填充数据,执行多个同构的SQL语句
应用
预编译SQL语句,参数使用?占位
preparedstatement pstmt = null;
pstmt = conn.preparestatement("select*from user where uname=?and pwd=?")
preparedstatement pstmt = null;
pstmt = conn.preparestatement("select*from user where uname=?and pwd=?")
为参数下标赋值
pstmt.setstring(1,"gavin")
pstmt.setstring(2,"123456")
pstmt.setstring(1,"gavin")
pstmt.setstring(2,"123456")
注意
jdbc中的所有参数都由?符号占位,这被称为参数标记
在执行SQL语句之前,必须为每个参数提供值
封装工具类
背景
在jdbc的使用中,连接数据库、关闭连接等存在大量的重复代码
把传统的jdbc代码进行重构,抽取出通用的jdbc工具类
重用性方法
封装获取连接方法
public static connection getconnection(){}
public static connection getconnection(){}
封装释放资源方法
public static void closeAll(connection conn,statement sm.resultset rs){}
public static void closeAll(connection conn,statement sm.resultset rs){}
配置文件
背景
重用性方案中的参数都是硬编码,当驱动、URL等参数需要更换时,需要重新编译
通过配置文件读取配置信息,使用软编码方式,更灵活的方案
跨平台方案
创建properties配置文件
创建properties集合
public static final properties prop = new properties()
静态代码块中,使用输入流,读取配置文件
orm(对象关系映射)
概念
object relational mapping:对象关系映射
对结果集(resultset)遍历时,取出的都是零散的数据
在实际应用开发的,我们需要将零散的数据进行封装整理
实体类(Entity)
一行数据中,多个零散的数据进行整理
通过entity的规则对表中的数据进行对象的封装
表名=类名;列名= 属性名;提供各个属性的get、set方法
提供无参构造方法(视情况添加有参构造)
DAO(数据访问对象)
概念
data access object:数据访问对象
dao实现了业务逻辑与数据库访问相分离
对同一张表的所有操作封装在xxxdaoimpl对象中
根据增删改查提供具体的方法(insert/update/delete/select/selectall)
service
什么是业务
代表用户完成的一个业务功能,可以由一个或多个DAO的调用组成
软件所提供的的一个功能叫业务
事务
概念
事务是一个原子操作,是一个最小执行单元,可以由一个或多个SQL语句组成,
在同一个事务当中<br>所有的SQL语句都成功执行时,整个事务成功,有一个
SQL语句执行失败,整个事务都执行失败
在同一个事务当中<br>所有的SQL语句都成功执行时,整个事务成功,有一个
SQL语句执行失败,整个事务都执行失败
事务的边界
在JDBC中,先获得connection对象
开始事务:conn.setautocommit(false)
手动提交事务:conn.commit()
手动回滚事务:conn.rollback()
在service中,调用了多次DAO操作。每一个业务功能都要控制事务
数据库连接池
Druid连接池
支持所有jdbc兼容的数据库,包括Oracle
Javaee,web开发
servlet
Servlet核心
Servlet核心的接口和类
除了实现Servlet接口,还可以通过继承GenericServlet或HttpServlet类完成编写
servlet接口
一脸懵逼背不住无法就业
游览器
开发人员负责控制游览器请求行为【三要素】
请求地址控制<a></a><from></from>
请求方式控制post/get
请求参数控制<a></a>表单域标签[input/select/textares]
既可以由前端工程师负责,也可以由服务端工程师负责
开发人员控制游览器接收响应数剧行为【服务端工程师】
控制游览器采用对于编译器将接收二进制数据转换为【文字、图片、视频、命令】
控制游览器将编译后命令进行执行或者将接收数据在游览器窗口展示【全局刷新展示/局部刷新展示】
控制用户与游览器展示内容之间交流【JavaScript--->jquery】【前端/服务端】
请求:得到emp.frm文件数据行带着http请求协议包往下走
服务端计算机
概念
servlet规范来自于javaee规范中的一种
作用
在servlet规范中指定【动态资源文件】开发步骤
指定HTTP服务器调用动态资源文件规则
指定http服务器管理动态资源文件实例对象规则
servlet接口实现类
servlet接口来自于servlet规范下一个接口,这个接口存在http服务器
提供的jar包
提供的jar包
Tomcat服务器下lib文件有一个servlet-api.jar存放servlet接口
servlet规范中认为http服务器能调用的【动态资源文件】必须是一个servlet接口实现类
servlet开发步骤
第一步创建Java类继承httpservlet父类,
第二步重写httpservlet父类两个方法。diget或者dopost
游览器以什么方式发送请求,就用什么方法
游览器以什么方式发送请求,就用什么方法
第三部将servlet接口实现类信息【注册】到Tomcat服务器
意外收获
抽象类的作用
降低接口实现类对接口实现过程难度
将接口中不需要使用抽象方法教给抽象类进行完成
这样接口实现类只需要对接口需要方法进行重写
将接口中不需要使用抽象方法教给抽象类进行完成
这样接口实现类只需要对接口需要方法进行重写
设计模式(模板设计模式)
通过父类决定在何种情况下调用子类中方法
servlet对象声明周期
网站中所有的servlet接口实现类的实例对象,只能由http服务器负责创建
开发人员不能手动创建servlet接口实现类的实例对象
开发人员不能手动创建servlet接口实现类的实例对象
在默认的情况下http服务器接收到对于当前servlet接口实现类第一次请求时自动创建这个servlet接口实现类的实例对象
在手动配置情况下,要求http服务器在启动时自动创建某个servlet接口实现类的实例对象
在手动配置情况下,要求http服务器在启动时自动创建某个servlet接口实现类的实例对象
在http服务器运行期间,一个servlet接口实现类只能被创建出一个实例对象
在http服务器关闭时刻,自动将网站中所有的servlet对象进行销毁
httpservletresponse接口
介绍
来自于servlet规范中,在tomcat中存在servlet-api.jar
实现类由http服务器负责提供
负责将doget/dopost方法执行结果写入到【响应体】交给游览器
开发人员习惯于将该接口修饰的对象称为【响应对象】
主要功能
将执行结果以二进形式写入到【响应体】
设置响应头中的[content-type]属性值,从而控制游览器使用
对应编辑器将响应体二进制数据编译为【文字,图片,视频,命令】
对应编辑器将响应体二进制数据编译为【文字,图片,视频,命令】
设置响应头中的【location】属性,将一个请求地址赋值给location
从而控制浏览器向指定服务器发送请求
从而控制浏览器向指定服务器发送请求
HTTP协议
概念
超文本传输协议
是互联网上应用最为广泛的一种网络协议
是一个基于请求与响应模式、无状态的、应用层的协议,运行于TCP协议基础之上
特点
支持客户端(游览器)/服务器模式
简单快速
灵活
无状态
无连接
通信流程
客户端与服务器建立连接(三次握手)
客户端向服务器发送请求
服务器接收请求,并根据请求返回相应的文件作为应答
客户与服务器关闭连接(四次挥手)
报文
HTTP请求报文
当游览器向Web服务器发出请求时,向服务器传递了一个数据块,就是请求报文
HTTP响应报文
当web服务器收到游览器的请求后,服务器要对报文做出响应,就是响应报文
常见状态码
200
客户端请求成功
302
临时重定向
403
服务器收到请求,但是拒绝提供服务
服务器通常会在响应正文中给出不提供服务的原因
服务器通常会在响应正文中给出不提供服务的原因
404
请求的资源不存在,例如输入错误的URL
500
服务器发生不可预期的错误,导致无法完成客户端请求
转发与重定向
转发
概念
转发的作用在服务端
将请求发送给服务器上的其他资源,以共同完成一次请求的处理
实现
request.getRequestDispatcher("/目标YRL-pattern").forwad(request,response)
注意
使用forward跳转时,实在服务器内部跳转,地址栏不发生变化属于同一次请求
数据传递
forward表示一次请求
是在服务器内部跳转,可以共享同一次request作用域中的数据
request作用域
拥有存储数据的空间,作用范围是一次请求有效
存储数据
request.setAttribute(key,value);
获取数据
request.getAttribute(key);
转发特点
转发是服务器行为
转发是游览器只做了一次访问请求
转发游览器地址不变
转发两次跳转之间传输的信息不会丢失,所以可以通过request进行数据的传递
转发只能将请求转发给同一个web应用中的组件
重定向
概念
重定向作用在客户端
客户端请求服务器,服务器响应给客户端一个新的请求地址,客户端重新发送新请求
实现
response.sendredirect("目标uri")
URI
用来表示服务器中定位的一个资源,资源在web项目中的路劲()
注意
使用redirect跳转时,是在客户端跳转,地址栏发生变化,属于多次请求
数据传递问题
sendredirect跳转时,地址栏发生改变,代表客户端重新发送的请求,属于两次请求
response没有作用域,量词request请求中的数据无法共享
实现数据传递
可以通过URI的拼接进行数据传递(?username=value)
获取数据:request.getParameter("username")
特点
重定向是客户端行为
游览器做了至少两次的访问请求
浏览器地址改变
两次跳转之间传输的信息会丢失(request范围)
可以指向任何的资源
包括当前应用程序中的其他资源、同一个站点上的其他应用程序中的资源、其他站点的资源
总结
当需要传递数据时,选择forward转发,不建议使用sendredlirect进行数据传递
servlet生命周期
概念
servlet从创建到销毁的整个过程
整个过程
1.instance实例化
创建实例化,只执行一次
调用init方法
2.initialize初始化
调用init方法,初始化Servlet,init()方法只执行一次
接受请求
3.service服务
当客户端发送请求时,执行Service对请求做处理及响应操作
容器停止
4.destroy销毁
当容器停止或重启,执行destory方法
destroy方法只执行一次
destroy方法只执行一次
Servlet特性
线程安全
servlet在访问之后,会创建一个Servlet对象
Tomcat容易可以同时多个线程并发访问年同一个Servlet
如果在方法中对成员变量做修改操作,就会有线程安全的问题
如何保住线程安全
synchronized
实现SingleThreadMode接口
尽可能使用局部变量
状态管理
现有问题
http协议是无状态的,不能保证每次提交的信息
客户端发送一个新的请求,服务器无法知道它是否与上次的请求有联系
对于需要多次提交数据才能完成的Web操作,比如登录来说,较为麻烦
概念
将游览器与web服务器之间多次交互当作一个整体来处理
将多次交互所涉及的数据(即状态)保存下来
分类
客户端状态管理技术:将状态保存在客户端,代表性的是cookie技术(缓存)
服务器状态管理技术:将状态保存在服务器端,代表性的是Session技术(会话)
cookie
概念
web服务器在http响应消息头中附带传送给游览器的一小段数据
当游览器保存cookie,之后每次访问该服务器时,会通过请求头回传该cookie数据
cookie主要由表示该信息的名称(name)和值(value)组成
创建cookie
cookie不是客户端有的东西,而是服务器写给我们浏览器的
创建cookie
cookie cookie = new cookie("name",value)
设置cookie的路径即作用范围
cookie.setPath("/webs")
设置cookie的生命周期
cookie.setMaxAge(-1)
取值有三种:>0有效期单位秒;=0游览器关闭 <0内存存储,默认-1永久保存
响应给客户端
response.addCookie(cookie)
获取cookie
获取所有cookie
cookie[] cks = request.getcookies()
循环遍历检索出自己的cookie
for(cookie ck : cks){
if(ck.getName().equals("code"))
{记录cookie的值
code=ck.getvalue()
break}}
if(ck.getName().equals("code"))
{记录cookie的值
code=ck.getvalue()
break}}
修改cookie
只要保证cookie的名的路径一致即可修改
注意:如果改变cookie的name和有效路径会新建cookie,而改变cookie的值,有效期会覆盖原来cookie
cookie编码与解码
cookie默认不支持中文,只能包含ASCII字符,所以cookie
需要对Unicode字符进行编码,否则会出现乱码
需要对Unicode字符进行编码,否则会出现乱码
编码可以使用java.net.URLEncoder类的encode(String str,String encoding)方法
解码使用java.net.URLDecoder类的decode(String str,String encoding)方法
创建带中文cookie
使用中文的cookie.name与value都是用utf-8编码
cookie cookie =new cookie(编码方法("name","utf-8"),
编码方法("value","utf-8"))
cookie cookie =new cookie(编码方法("name","utf-8"),
编码方法("value","utf-8"))
读取带中文cookie
String name = 解码方法("name","utf-8")
cookie的优点和缺点
优点
可配置到期规则
简单性:cookie是一种基于文本的轻量结构,可以包含简单的键值对
数据持久性:cookie默认在过期之前是可以一直存在客户端游览器上的
缺点
大小收到限制:大多数游览器对cookie的大小有4k8k字节的限制
用户配置为禁用:有些用户禁用了浏览器或客户端设备接收cookie的能力,因此限制了这一功能
潜在的安全风险:cookie可能会被篡改,会对安全性造成潜在风险或者导致依赖于cookie的应用程序失败
cookie禁用解决方案
背景
服务器在默认情况下会使用cookie的方式将sessionid发送给游览器
如果用户禁止cookie,则sessionid不会被游览器保存
解决方案
URL重写
访问服务器上的某个地址时,对地址做重写即在地址后加上sessionid
实现
response.encodeRedirectURL(String url)生成重写的url
session
概念
session用于记录用户的状态
session指的是在一段时间内,单个客户端与web服务器的一连串相关的交互过程
在一个session中,客户可能会多次请求访问同一个资源或不同的服务器资源
session原理
服务器会为每一次会话分配一个session对象
同一个游览器发起的多次请求,同属于一次会话(session)
首次使用到session时,服务器会自动创建session,并创建cookie存储sessionid发送会客户端
注意
session是由服务器创建的
session使用
session作用域
拥有存储数量的空间作用范围是一次会话有效
一次会话时使用同一游览器发送的多次请求,一旦游览器关闭,则结束会话
可以将数据存入session中,再一次会话的任意位置进行获取
可以传递任何数据(基本数据类型、对象、集合、数组)
获取session
session是服务器自动创建的,通过request对象获取
HttpSession session = request.getsession()//唯一标记
session保存数据
setAttribute(属性名,object)保存数据到session中
session.setAttribute("key",value)//以键值对形式存储在session作用域中
session获取数据
getattribute(属性名),获取session中的值
session.getAttribute("key")//通过String类型的Key访问object类型的value
session移除数据
removeattribute(属性名)从session中删除数据
session.removeattribute("key")//通过键移除session作用域中的值
session修改数据
覆盖就好
session清空数据
session.invalidate();
清空的是session对象
session与request应用区别
request是一次请求有效,请求改变则request改变
session是一次会话有效,浏览器改变,则session改变
session的生命周期
开始
第一次使用到session的请求产生,则创建session
结束
游览器关闭,则失效
看游览器设置,有的设置了退出清缓存
看游览器设置,有的设置了退出清缓存
session超时,则失效,默认30分钟
session.setMaxinactiveinterval(seconds);//设置最大有效时间秒
session.setMaxinactiveinterval(seconds);//设置最大有效时间秒
手工销毁,则失效
session.invalidate()登录退出、注销
session.invalidate()登录退出、注销
servletcontext
概念
全局对象,拥有作用域,对应一个Tomcat中的web应用
当web服务器启动时,会为每一个web应用程序创建一块共享的存储区域
servletcontext在web服务器启动时创建,服务器关闭时销毁
获取servletcontext
this.getservletcontext()
作用
获取项目真实路径
servletcontext.getrealpath("/")
out文件下里面的部署包。即tomcat运行是部署包
获取应用上下文路径
sout.servletcontext.getcontextpath
全局容器
servletcontext拥有作用域,可以存储数据到全局容器中
存储数据
servletcontext.setattribute("name",value)
获取数据
servletcontext.getattribute("name")
移除数据
servletcontext.removeAttribute("name")
特点
唯一性,一个应用对应一个servletcontext
生命周期,只要容器不关闭或应用不卸载,servletcontext一直存在
作用域总结
httpservletrequest
一次请求,请求响应之前有效
httpsession
一次会话开始,游览器不关闭或不超时之前有效,全局使用
servletcontext
服务器启动之后,关闭之前有效,全局使用
过滤器
现有问题
在以往的servlet中,有许多冗余的代码,多个servlet都要进行编写
概念
过滤器(Filter)是处于客户端与服务器目标资源之间的一道过滤技术
过滤器作用
执行地位在servlet之前,客户端发送请求时,会先经过filter在到达目标servlet中
响应时会根据执行流程再次反向执行filter
响应时会根据执行流程再次反向执行filter
可以解决多个servlet共性代码的冗余问题(例如乱码处理,登录验证)
编写过滤器
servlet api中提供了一个filter接口,开发人员编写了一个java类实现了这个接口即可
这个Java类称之为过滤器
这个Java类称之为过滤器
实现过程
编写Java类实现filter'接口
在dofilter方法中编写拦截逻辑
设置拦截路径
过滤器配置
注解配置
在自定义的filter类上使用注解@webfilter(value="过滤目标资源")
xml配置
与servlet一样将servlet改成filter
过滤器路径
过滤器的过滤路径共有三种方式
精确过滤/name
后缀过滤*.jsp/*.jpg
通配符匹配/aaa/*
过滤器链与优先级
过滤器链
客户端对服务器请求之后服务器调用servlet之前会执行一组过滤器(多个)
那么这组过滤器就称为一条过滤器链
那么这组过滤器就称为一条过滤器链
每个过滤器实现某个特点的功能,当第一个filter的dofilter方法被调用时,web服务器会创建一个代表filter链的
filterchain对象传递该方法,在dofilter方法中开发人员如果调用了filterchain对象的dofilter方法,则web服务器
会检查filterchain对象中是否还有filter,如果有,则调用第二个filter如果每有则调用目标资源
filterchain对象传递该方法,在dofilter方法中开发人员如果调用了filterchain对象的dofilter方法,则web服务器
会检查filterchain对象中是否还有filter,如果有,则调用第二个filter如果每有则调用目标资源
优先级
注解则按类全名称的字符串顺序决定作用顺序
如果web.xml,按照filter mapping注册顺序,从上到下
web.xml配置高于注解方式
如果注解和web.xml同时配置,会创建多个过滤器对象,造成过滤多次
应用
解决编码
权限验证
jsp
概念
简化的servlet设计,在html标签中嵌套java代码,用以高效开发web应用的动态网页
作用
替换显示页面部分的servlet(使用.jsp文件替换java)
jsp开发
创建jsp
在web目录新建.jsp问你件(与web-inf平级)
使用<%%>java脚本标签编写java代码
使用<%= %>输出标签
在游览器中输入http://ip:port/项目路径/资源名称
JSP与Servlet
关系
JSP文件在容器中会转换成servlet执行
JSP是对servlet的一种高级封装,本质还是servlet
区别
与servlet相比,JSP可以很方便的编写或者修改HTML网页而不用去面对大量println语句
实现原理
tomcat服务器会将jsp文件转换成java代码编译成class文件,最终运行结果通过response响应给客户端
jsp.java源文件存放目录
使用IDEA开发工具,tomcat编译后的jsp文件(xxx_jsp.java)的存放地点
脚本
脚本可以编写Java语句,变量,方法或表达式
普通脚本
语法<%java代码%>
普通脚本可以使用所有的java语法,除了定义函数
注意:脚本与脚本之间,与HTML标签之间都不可以嵌套
声明脚本
语法<%!定义变量,函数%>
声明脚本声明的变量是全局变量
声明脚本的内容必须在普通脚本<%%>中使用
如果声明脚本中的函数具有返回值,可以使用输出脚本调用<%= %>
输出脚本
语法<%=表达式%>
输出脚本可以输出带有返回值的函数
输出脚本中不能加
JSP注释
主要有两个作用为脚本代码作注释以及HTML内容注释
语法
<%--注释--%>
jsp注释,注释内容不会被发送至游览器甚至不会被编译
jsp注释,注释内容不会被发送至游览器甚至不会被编译
<!--注释-->
HTML注释,通过游览器查看网页源代码时可以看见注释内容
HTML注释,通过游览器查看网页源代码时可以看见注释内容
JSP指令
JSP指令用来设置与整个JSP页面相关的属性
指令
page指令
<%@page...%>
定义页面的依赖属性,比如脚本语言,error页面,缓存需求等等
contenttype:指定当前jsp页面的HTML类型和字符编码格式
errorpage:指定当jsp页面发生异常时需要转向的错误处理页面
iserrorpage:指定当前页面是否可以作为另一个jsp页面的错误处理页面
ioport:导入需要使用的java类
language:定义jsp页面所用的脚本语言默认java
session:指定jsp页面是否使用session,默认为true立即创建,false为使用时创建
pageencoding:指定jsp界面的解码格式
include指令
<%@indlude file="被包含的指定jsp路径"%>
通过include指令来包含其他文件
被包含的文件可以是jsp文件、html文件或文本文件,包含的文件就好像是当前
jsp文件的一部分,会被同时编译执行(静态包含)相当于复制粘贴内容一样
jsp文件的一部分,会被同时编译执行(静态包含)相当于复制粘贴内容一样
可能会有重名的风险
taglib指令
<%@taglib uri =外部标签库路径 prefix=前缀%>
引入jsp的标准标签库
动作标签
<jsp:actiuon_name attribute=value/>
动作标签指的是jsp页面在运行期间的命令
内容
include
会将外部文件输出结果包含在jsp中(动态包含)
<jsp:include page=相对URL地址>
相当于方法的返回值
注意,include指令是将外部文件的输出代码复制到了当前jsp文件中
include动作标签则是将输出结果引入到当前jsp文件中
include动作标签则是将输出结果引入到当前jsp文件中
usebean
<jsp:usebean id=''' class="对象地址"/>
在类载入后,我们可以通过jsp:setproperty与jsp:getproperty来修改获取bean的属性
相当于new对象
setproper
可以在jsp:usebean之后进行属性的赋值
属性
name:是必须的他表示要设置属性的是哪个bean,类
property:是必须的他表示要设置那个值,属性
value:是可选的该属性用来指定bean属性的值,值
getproperty
提取指定bean的值,转换成字符串然后输出
属性
name:要检索的bean属性名称,bean必须已定义
property:表示提取bean的值
forward
jsp:forward page="相对URL地址"
jsp:forward动作把请求转到另外的页面
类似转发
param
jsp:param name="" value=""
在转发的动作内部使用,做参数传递
内置对象
由jsp自动创建的对象,可以直接使用
对象
request
response
session
application
config
大量包含jsp的相关配置
exception
iserrorpage="false"开关
out
pagecontext
页面对象
page
相当于java的this
四大域对象
jsp有四大域对象,存储数据和获取方式一样,不同的是取值的范围有差别
对象
pagecontext
用于获取其他八个内置对象或者操作其他对象的作用域
get对象名
get对象名
基本
当前jsp页面范围
pagecontext对象拥有作用域,用来代表整个jsp页面
当前页面的作用域对象,一旦跳转则失效
当前页面的作用域对象,一旦跳转则失效
通过setattribute("name","value")存储值
通过getattribute("name")获取值
基本不会使用它存数据
操作其他内置对象的作用域
pagecontext.setattribute("name",value,域范围)
域范围
request_scope
session_scope
application_scope
page_scope
pagecontext.findattribute("name")
从四个域中依次查找:pagecontext,request,session,application找到位置
如果都没有则返回null
request
一次请求有效
session
一次会话有效(关闭游览器失效)
application
整个web应用有效(服务器重启或关闭失效)
EL表达式(重要)
概念
EL使jsp写起来更简单、简洁。主要用于获取作用域中的数据
作用
用于替换:域对象.getattribute("name")
应用
${scop.name}获取具体某个作用域中的数据
${name}获取作用域中的数据,逐级查找
注意:从域中取数据钱,必须先把数据放入域中
EL和JSP脚本的区别
<%=requset.getattribute(nume)%>没有找到返回null
${name}没找到返回""空
el表达式对用户更友好
获取引用类型的数据
获取对象数据
${name.属性}
必须要有getset方法
获取数组集合数据
${name[下标]}
$(name[下标].属性)
获取map类集合数据
${name.key}
${name[key]}
EL表达式可以使用各种运算符
与java一样
empty
判断是否为空
字母版
==相当于eq
>相当于gt
<相当于lt
空字符串也是0 "" null
<=相当于le
>=相当于ge
!=相当于ne
/相当于div
%相当于mod
隐式对象
EL表达式语言定义了11个隐式对象
对象
pagescope:page作用域
requestscope:request作用域
sessionscope:session作用域
applicationscope:session作用域
param:request对象的参数,字符串
与楼下一样获取url参数,?传参的参数
paramvalues:request对象的参数,字符串集合
header:http信息头,字符串
headervalues:http信息头,字符串集合
initparam:上下文初始化参数
cookie:cookie值
pagecontext:当前页面的pagecontext
pagecontext.servletcontext.contextpath获取上级目录
配合herf拼接路径,保证路径不会出错
可以确定文件的路径,自动进行字符串拼接
获得应用上下文
<%=request.getcontextpath()%>
${pagecontext.request.contextpath}
获取cookie对象
${cookie.cookiename}
${cookie.cookiename.value}获取cookie的value值
JSTL
什么是JSTL
全称java server pages Standard tag Library
JSP标准标签库(JSTL)是一个JSP标签集合
JSTL的作用
可以对EL获取到的数据进行逻辑操作
可与EL合作完成数据的展示
JSTL使用
导入两个jar文件:standard.jar和jstl.jar文件拷贝到/web-inf/lib/下
在jsp页面引入标签库<%@taglib uri="http://java.sun.con/jsp/jstl/core" prefix="c">
核心标签
条件标签
if判断
语法:<c:if test="条件"></c:if>
注意:test属性中是条件,但是条件需要使用EL表达式来书写
多条件choose判断
语法:<c:choose>
<c:when test="条件1">结果1<c:/when>
...
<c:otherwise>结果4</c:otherwise>
</c:choose>
<c:when test="条件1">结果1<c:/when>
...
<c:otherwise>结果4</c:otherwise>
</c:choose>
迭代foreach标签
语法<c:foreach var="变量名"items="集合" begin="起始下标" end="结束下标" step="间隔长度" varstatus="遍历状态">
</c:foreach>
</c:foreach>
url标签
在cookie禁用的状态下,通过重写URL拼接jsessionid来传递id值,便于下一次访问时仍可查找到上一次的session对象
经验:所有涉及到页面跳转或者重定向跳转时,都应该使用URL重写
文件的上传和下载
要有一个form标签,method=post请求
form标签的enctype属性值必须为multipart/form-data值
表示提交的数据以多段(每一个表单项为一个数据段)的形式进行拼接然后以二进制流的形式发送给服务器
Content-Type:表示提交的数据类型
---------------------------28359286838911458633044697036
是由游览器每次随机生成,它就是每段数据的分界符
是由游览器每次随机生成,它就是每段数据的分界符
在form标签中使用input type=file添加上传的文件
编写服务器代码接收,处理上传的数据
MVC框架(Model-View-Controller)
MVC概念
mvc又称为编程模式,是一种软件设计思想,将数据操作、页面展示、
业务逻辑分为三个层级(模块),独立完成,相互调用
业务逻辑分为三个层级(模块),独立完成,相互调用
模型层(Mode;)
视图(View)
控制器(Controller)
MVC模式详解
MVC并不是Java独有的,现在几乎所有的B/S架构都采用了MVC模式
视图:视图即用户看到并与之交互的页面,比如html(静态资源)
jsp(动态资源)等等
jsp(动态资源)等等
控制器:控制器即是控制请求的处理逻辑,对请求进行处理,负责流程跳转(转发和重定向)
模型:对客观世界的一种代表和模拟(业务模拟,对象模拟)
层级属性
视图层:jsp收集并展示信息
控制器:收参,调用业务方法,流程跳转
模型层:Service+Dao+Entity
优点
低耦合性:模块与模块之间的关联性不强,不与某一种具体实现产生密不可分的关系
高维护性:基于低耦合性,可做到不同层级的功能模块灵活更换、插拔
高重用性:相同的数据操作,可以服务于不同的业务处理,将数据作为独立模块,提高重用性
MVC在框架中应用
MVC模式广泛用于Java的各种框架中,比如Struts2,springMVC等等都用到了这种思想
三层架构与MVC
三层架构
VIEW(表示|界面层)
收集用户数据
调用业务逻辑,完成业务方法
展示数据,展示操作结果
service(业务逻辑层)
开启事务
调用DAO层
处理数据
提交或回滚
DAO层(数据访问层)
查询相关业务逻辑的数据
根据相关业务逻辑修改的数据
MVC与三层架构的区别
MVC强调的是视图和业务代码的分离,严格说MVC其实关注的是Web层。
View就是单独的页面,比如就是JSP、HTML等,不负责业务处理,只负责
数据的展示,而数据封装到model里,有controller负责在VM之间传递,
MVC强调业务和视图的分离
View就是单独的页面,比如就是JSP、HTML等,不负责业务处理,只负责
数据的展示,而数据封装到model里,有controller负责在VM之间传递,
MVC强调业务和视图的分离
三层架构是数据访问层、业务逻辑层、表示层,指的是代码之间的解耦,方便维护和复用
分页
概念
分页是Web应用程序非常重要的一个技术。数据库中的数据可能是成千上万的,不可能把这么多的数据一次显示在游览器上面
一般根据每行数据在页面上所占的空间设置每页显示若干行,比如一般20行是一个比较理想的显示状态
一般根据每行数据在页面上所占的空间设置每页显示若干行,比如一般20行是一个比较理想的显示状态
分页实现思路
对于海量的数据查询,需要多少就取多少,显然是最佳的方法
select*from表名 limit 0,20;//第一页
select*from表名 limit 20,20//第二页
git
项目的约定俗成
method参数后的值作为方法名称
方法的返回字符串如果是以forward开头,表示是以转发进行跳转
如果以redirect开头,则以重定向跳转
如果以redirect开头,则以重定向跳转
方法定义的形参要与请求参数的名字一样
前端
0 条评论
下一页