/*001
* 面向对象
* 面向过程和面向对象
* 面向过程 先做什么后做什么 强调过程
* 面向对象 用谁对谁做点什么 让谁做什么 强调角色和作用
*
* 面向过程解决微观层次问题
* 面向对象解决宏观层次问题
*
* 面向对象底层要依靠面向过程
*
* 类 一类事物的统称,多个性质相同或者相近的实物抽象成的一种认识
* 对象 一类事物中,具体的实际存在的可以使用的实例
*
* 类三大成员
* 成员变量 模拟类的属性
* 成员方法 模拟类的功能
* 构造方法 构造和初始化对象
*
* 构造方法
* 构造方法又叫做构造器
* 帮助我们实例化和初始化对象
* 使用new关键字调用
* 名称必须和类名相同 没有返回值也没有void关键
* public Student(){}
*
* 构造方法可以进行重载
* 构造方法 可以调用同类中其他的构造方法
* 使用this() this()必须是当前构造方法的第一行代码
*
* 对象和对象数组作为方法参数
*
* this关键字
* 在普通成员方法中,可以使用this关键字区分成员变量和局部变量
* this代表当前对象,就是调用当前方法的那个对象,this其实就是调用方法的对象的堆内存的地址
*
*
* */
/*002
* 1静态 static
* 1修饰成员变量 静态成员变量
* 占用方法区 只有一份 被当前类所有的对象共享
* 推荐使用类名.变量的方式访问
* 2修饰方法 静态方法
* 只能直接使用静态的成员变量
* 推荐使用类名.方法名的方式访问
* 内部不可以使用this关键
* this代表当前对象,就是调用了方法的那个对象 但是静态方法往往是类名.方法名调用的 不需要对象就可以调用的方法
* 3修饰代码块
* 静态代码块
* 在类加载进入的内存的时候执行,只执行一次
* 一般用来初始化静态成员变量
* 普通代码块
* 在每次构造对象的时候执行一次
* 一般用来初始化实例成员变量
* 4static可以修饰导入 import
* import 导入当前类要使用的在别的包的其他的类
* static 可以用作静态导入,导入一个类中所有的静态成员
*
* 5static修饰类, 静态内部类
*
*
*
* 2封装
* 封装:隐藏实现的细节,仅仅对外公开使用的接口/方式
* 好处:1提高安全性 2降低耦合度
* 对类进行封装
* 1属性私有化 使用private修饰符修饰所有的成员变量
* 2定义公有的get和set方法
* 静态成员变量的get和set方法应该也是静态的方法
* 布尔类型成员变量get方法不叫get.... 叫做 is...
* alt + insert
* constructor 构造器
* getter setter
*
*
*
* 3继承
* java中由已知类派生(创建)新类的一种特殊机制
* 已知类 父类 超类
* 新类 子类
* 子类可以拥有父类所有的属性和方法,子类还可以自己定义独有的属性和方法
* 子类其实就是对父类的一种扩展
*
* 方法的重写
*
* 子类对父类同名方法的再次定义
* 1子类和父类在完成相同的功能时,采取的算法不一致
* 2子类要在父类方法的基础之上,做到更多的事
* 3多态性的主要的体现之一
*
*
* 方法重写要求
* 1在子类中
* 2方法名,必须相同
* 3返回值类型 子类重写的方法的返回值类型必须是父类方法返回值类型的同类或者是子类
* 4参数列表 重写的方法参数的级别要大于等于父类的参数级别
* 5访问修饰符 子类方法访问权限要大于等于父类方法的访问权限
* 6异常列表 子类方法抛出的异常要比父类方法抛出的异常个数更少,范围更小
*
* 对比方法的重写和重载
*
*
*
* */
/*003
* 1继承中的构造方法
* 构造方法不能被继承 子类构造方法中一定会调用父类构造方法
* 通过super()调用父类构造方法 如果父类中存在 无参构造方法 super() 可以省略不写
* 如果父类中不存在无参构造方法,那么必须写super() 同时传入参数
* super() 必须是子类构造方法的第一句
*
* 继承中 代码块和构造方法的执行顺序
* 1父类中的静态代码块
* 2子类中的静态代码块
* 3父类中的普通代码块
* 4父类的构造方法
* 5子类的普通代码块
* 6子类的构造方法
*
*
* 2多态
* 一种事物有多重表现形态
* 一个对象由于其子类的不同,调用同一个方法时,可能会出现不同的形态
* 多态三个必要条件 继承 方法的重写 父类引用子类对象(子类对象声明成父类)
*
* 向上转型 子类声明成父类对象 OK 子类具有父类所有的功能
*
* 向下转型 父类转换为子类对象 不OK 父类不能保证具备所有子类的功能
* 可以通过强制转换让代码通过编译 运行时会出现 ClassCastException
* 如果本来就是有子类声明成的父类对象,再转换为子类 OK
* instanceof 判断一个对象是否属于某个类
* 对象 instanceof 类
*
* 父类作为参数列表的类型,所有的子类对象都可以 作为实参传入
* 父类作为返回值类型,所有的子类对象都可以做为返回的结果
*
* 抽象类
* 1没有方法体的方法 抽象方法 由关键字abstract关键字修饰
* 2抽象方法必须在抽象类中 抽象类由abstract关键字修饰
* 3抽象类不能被实例化 抽象类中可以有构造方法
* 4抽象方法必须被子类重写为普通方法
* 5可以创建子类对象声明成抽象类
* 6如果子类不想重写抽象方法,那么子类必须也是抽象类
* 7最终的子类必须重写所有层级的类中抽象方法
* 8抽象类中可以有普通方法,供子类继承
*
* 3Object类
* JAVA中的根基类 是所有类直接或者间接父类
* 定义了一些所有的JAVA类都必须具有的方法
* equals hashcode toSting clone wait notify notifyAll
*
* equals 判断两个对象是否同一 重写之后达到同一个类中的两个对象 ,只要属性值相同则返回true
* hashcode 给对象生成哈希码的方法 重写之后达到同一个类的中的两个对象, 只要属性值相同,生成的哈希码就相同
* toString 返回对象的字符串表达形式 重写之前 类的全路径名+@+哈希码 重写之后使用对象的所有属性名和属性值拼接字符串
* clone方法 返回对象的副本 重写clone方法后 将访问修饰符改为public 让类实现 Cloneable接口
*
* 4组合关系
*
* 整体和部分的关系 一个类可以作为另一个类的组成部分
* 代码表现为:一个类的属性可以是另一个类 仅仅基本数据类型可以作为成员变量, 类也可以作为成员变量
*
*
*
* 5 思考
* 方法的重写
* 1可以重写也可以不重写 普通的实例方法
* 2必须重写的是 抽象方法
* 3不能重写的 静态方法 final修饰的最终方法
* */
/*004
* 1final
* 修饰局部变量 只能赋值一次
* 修饰成员变量 常量
* 修饰类 最终类
* 修饰发方法 最终方法
*
* 必须被重写的方法 抽象方法
* 不能被重写的方法 final修饰的方法 静态方法(不具备多态性)
*
* 2接口
* 比抽象类更抽象的一种数据类型
* 接口是一种规范 是一种规则和要求
* 接口中的成员变量都是共有静态常量 抽象类中没有这个要求
* 接口中的方法都是共有抽象方法 (JDK default1.8 static1.8 private1.9) 抽象类中可以有非抽象方法
* 接口不能被普通类继承,只能被普通类实现 抽象类是需要被普通类继承
* 只有接口可以继承接口,一个接口可以继承多个接口 抽象类和普通类都可以继承抽象类
* 一个实现类可以同时实现多个接口(解决JAVA单继承) 一个普通类只能直接继承一个JAVA(JAVA单继承)
* 接口中没有构造方法 抽象类中有构造方法
* 接口出现的位置其实现类对象就可以出现 接口作为方法的参数和返回值
*
* 对象数组/集合排序时可以采用下面两个接口完成排序
* Comparable 让元素所属类实现的 代表当前类的对象具备互相对比的功能
* Comparator 单独定义类实现的 帮助我们对比一个类中两个对象大小关系的比较器
*
*
* 3内部类
* 普通内部类
* 静态内部类
* 局部内部类
* 匿名内部类
* 1帮助我们快速为接口/抽象类产生实现对象/继承对象的一种方法
* 2语法结构 接口/抽象类 对象名= new 接口/抽象类(){ 匿名内部类 };
* 3匿名内部类作为局部内部类的一种,只能使用方法的中常量
* 4匿名内部类没有类名,所以也没有构造方法
* 5匿名内部类中的get set方法 往往无法调用
* 6匿名内部类的成员变量可以使用代码块的形式进行初始化
* 7当一个接口/抽象类中的抽象方法比较少 器实现类/子类对象应用位置也比较少
*
*
*
*
* */
/*
* 1异常
* 在程序运行时可能会造成程序出现问题的一些情况
*
* 检查型异常 checked Exception
* java编码时必须要通过异常处理机制编码处理的异常
* 一般来说无法通过严密的编码避免
*
* 运行时异常 Runtime RuntimeException extends Exception
* java编码时,可以不用编码特殊处理的异常
* 一般来说,可以童工严密的编码避免
*
* 捕获处理
* try catch finally
* try 将可能出现异常的代码进行监控
* catch 当监控的代码出现异常是,由该语句块捕获并作出相应处理
* finally 无论异常是否出现 是否成功捕获都会执行的代码 用来做资源释放
*
* catch中可以捕获多个不同类型的异常
* 多重catch捕获不同的异常 子类异常在前 父类异常在后
* try catch嵌套 子类异常在内 父类异常在外
* 在方法体中finally一定在return 之前执行
*
* 抛出处理
* throw 人为抛出一个异常 只能方法异常对象
* throws 用于申明方法的异常列表
*
* 2设计原则
* 单一职责原则 :不要将大量功能不相关代码放在一个类中 ,根据功能多分类
* 开闭原则 : 对修改关闭,多拓展开发 软件的功能新增应该增加代码,不要对现有代码产生修改
* 里氏替换 : 父类/接口/抽象类 出现的地方法 其子类/实现类对象都可以出现
* 依赖倒置 : 让功能依赖抽象 不要依赖具体的细节 方法的参数 组合关系 尽量选择用接口 少用JAVA类
* 接口分离 : 不要在一个接口中编写大量不相关的方法 ,为不同的模块准备具体的接口
* 迪米特法则: 不要和陌生人说话, 不要让一个类和过多的类产生关联,可以通过中间类降低耦合度
* 合成/聚合复用: 一个类获得另一个类功能时,能选择组合关键,那么就少用继承关系
*
* 3类和类的六种关系PowerDesinger
* 继承 extends
* 实现 implements
* 依赖 另一个类作为方法参数或者是局部变量
* 关联 另一个类作为属性 不表示整体和部分
* 聚合 另一个类作为属性 表示整体和部分 整体和部分的生命周期不同
* 组合 另一个类作为属性 表示整体和部分 整体和部分的生命周期相同
*
*
*
*
* */
/*
* 算法
* 计算机解决特定的问题的而编写的一系列代码的集合
* 如何评价算法
* 时间复杂度
* 当数据规模产生变化时,时间频度的变化趋势量级
* 常数阶 O(5)
* log2N
* n
* n*log2n
* n的平方
* n!
* 空间复杂度
* 当数据规模产生变化时,空间占用的变化趋势量级
*
* 排序 冒泡 选择
* 查找 顺序 二分(循环 递归)
*
* 数据结构
*
* 逻辑
* 线性表 除了开头 每个结点都有且只有一个直接前继 除了结尾 每个结点有且只有一个直接后继
* 非线性表
* 树 哈希 索引 图 ... ...
* 栈 先进后出 后进先出
* 队列 先进先出 后进后出
*
* 存储
* 顺序存储
* 链式存储
* 二叉树/红黑树
* 哈希
*
* */
/*
* 集合 容器
* 数组
* 1长度不可变 增删数据效率低
* 2根据索引查询快, 根据内容查询慢
* 3本身API
*
* 集合
* Collection 不考虑重复性和有序性
* List 考虑到顺序性 可以重复的
* ArrayList
* 内部维护了一个Object数组用于存储数据
* 增删效率略低 根据索引查询效率高 根据内容查询略低
* LinkedList
* 使用双向链表的结构实现
* 增删效率高 根据索引和内容查询略低
*
* Set 不考虑顺序 不可以重复
* HashSet 使用哈希表结构
* 本质还是一个数组
* 在存储元素时,根据元素的哈希码算出在数组上的位置,
* 如果该位置为空,直接放入元素即可
* 如果该位置上有其他元素,通过equals方法判断是否相同,如果相同则不放入
*
* 增 删 根据内容查询效率高
* TreeSet 使用红黑树结构
* 在存储数据时 ,根据元素的大小进行运算
* 如果目标元素比根元素大,放入元素的右边,如果小,放入左边,
* 如果相同,认为是重复元素,不放入
*
* Map 存储的是键值对
* HashMap
* TreeMap
* 键不能重复 值可以重复
* 后放入的键值对如何和之前的键重复了 值会覆盖原有的值
* HashMap中键可以为null
* TreeMap中的键不可以为null
*
*
*
*
*
*
*
*
*
* */
/*
* Map
* HashMap
* TreeMap
* HashSet
* TreeSet
* 迭代器
* Iterator
* ListIterator
* 泛型
* 数据类型的站位符
* 泛型方法 public <T,K,X,V> T 方法名( K) {}
* 泛型类 class A<T,K... ...>
* 泛型接口 interface I <T,K ... ...>
* 泛型的向上和向下限定 ? super extends
* 1当泛型不处理时,数据类型默认是Object
* 2在方法重载时,泛型的不同不能当成参数的不同(泛型的擦除)
* 集合工具类
* Collections
* addAll binarySearch sort fill copy ... ...
*
*
* 旧集合
* 重安全,轻效率 重效率,轻安全
* Vector >>> ArrayList
* HashTable>>> HashMap
* 新一代并发集合
* HashMap >>> CurrentHashMap 分段锁 volitale +cas
* ArrayList >>> CopyOnWriteArrayList 当发生修改时 先对数据进行复制,在复制的数组上进行操作
* HashSet >>> CopyOnWriteArraySet 去重的CopyOnWriteArrayList
* Lambda
* 简化针对于接口的匿名内部类的一种写法
* 要求接口中有且只有一个抽象方法需要重写
* (参数列表)-> {方法体}
*
* 1 方法体中只有一行代码 那么大括号可以省略不写
* 2 参数列表中的数据类型是可以省略不写
* 3 当参数只有一个时 ,小括号可以省略不写
* 4 有返回值且只有一行时,return和大括号可以同时省略不写
*
* 函数式接口
* 只有一个需要重写的抽象方法的接口就是函数式接口 一般都配合Lambda表达式使用 函数式编程
* @FuncationalInterface 放在接口上帮助我们在编码过程中对接口进行是否符合函数式接口的检验注解
* JDK中函数式接口
* Comparator
* 消费型 Consumer
* 供给型 Suplier
* 函数型 Function
* 断言型 Predict
*
* 方法引用
* 继续简化Lambda表达式
* 在我们重写一个抽象方法时,该抽象方法功能的实现完全靠另一个方法运行,就可以引用另一个方法代替我们要重写的抽象方法
* 类名/对象民:: 方法名
* 被引用的方法的参数列表和返回值必须和要重写的抽象方法相同
*
* Stream
* 将数组/集合 放到一个流水线上进行连续的处理
* 1 获得一个Stream流
* 2 添加中间操作 可以有多个 limit sorted distinct skip filter ... ...
* 3 添加结束操作 只能用有一个 max foreach findFirst ... ...
*
*
*
*
* */
/*
* xml 可扩展的标记语言 配置文件
* 语法结构
* 第一行是文档声明 前边不能有空格换行和注释
* 有一个且只能有一个根标签
*
* 约束 了解
* DTD 简单 不够强大 可以对xml结构进行约束
* schema 复杂 比较强大 同时可以对数据进行约束
*
* 解析技术
* DOM 演示
* SAX
* JDOM
* DOM4j 操作
*
*
* */
/*
* 多线程
*
* 1如何产生多线程
*
* 继承Thread 能不用就不用
* 实现Runnable 能用就用
* 实现Callable 1.5 返回值 控制线程状态 泛型 支持抛异常
*
* 2线程的生命周期
* 新生 就绪 运行 阻塞 死亡
* new start running block dead
*
* 运行 >>> 死亡 阻塞 就绪
* 什么情况会造成线程的阻塞
* 1Thread.sleep
* 2join
* 3wait wait(1000)
* 4IO ... ... sc.next()
*
* 3线程的控制
* start 启动
* join 加入
* sleep 睡眠
* stop 停止
* interrupt 打断
* setDeamon 伴随 垃圾回收机制
*
* 4线程全问题
* 多个线程共享同一资源
* 5解决线程全问题
* 线程的同步
* synchronized
* 同步代码块 synchronized(){}
* 同步代码函数 public synchronized 返回值类型 方法名 ... ...
* 多个线程要使用同一把锁
* 经常把多个线程共享的资源作为锁
* 同步代码块需要我们自己手动指定锁
* 同步函数自动指定锁 1实例方法锁为this 2静态方法锁为当前类的字节码
* lock
* Lock ReadLock WriteLock ReentrantLock
* ReadWriteReentrantLock
* lock.lock() 上锁
* lock.unLock() 解锁 一定要放在finally中
*
* ReadWriteReentrantLock 读取锁 写入锁
* 多个读取线程可以并发 写入线程不可以并发
* 公平锁:多个线程在获得锁时,锁优先让等待时间最长的线程获得
*
* 死锁
* 多个线程共享多个资源
*
*
*
*
* */
/*
* 1 JUC volatile +CAS
* 线程同步的三个条件 原子性 有序性 可见性
* volatile 可见性 有序性 CAS对比并设置 Lock
*
* 2 线程通信
* 多个线程,共享相同的数据,存在数据的争夺问题,多个线程之间要进行协调和调度,尽量避免争夺
* 线程通信的条件
* 1多个线程
* 2共享资源
* 3相同的同步监视器
* 其实就是使用同步监视器作为媒介实现通信
* wait 让当前线程进入阻塞状态 等待被唤醒或者时间到达自动唤醒
* notify 唤醒一个线程 notifyAll 唤醒所有线程
*
* Lock
* 将不同的线程放入不同的阻塞队列
* Condition con= lock.newCondition();
* con.awati()
* con.signal() signalAll
*
* 阻塞队列
* BlockingQueue 自带阻塞效果的集合 Linked Array
* put 放入数据 达到容量限制 阻塞线程
* take取出数据 数据完全取空 阻塞线程
*
* 3 线程池
* ThreadPool 提前准备多个线程对象,多个线程对象反复使用
* 减少线程对象的反复创建和销毁,提高程序的响应速度
*
* Executors 工具类 可以帮助我们直接获取线程池服务对象
* ExecuterSerivce
*
* */
/*
约束
主键 primary KEY
非空 not null
检查 check
唯一 unique
自增 auto_increment
默认值DEFAULT
外键 foreign key REFERENCES
delete
TRUNCATE
DQL
select
字段选择和运算 *
别名 AS "别名"
去重 DISTINCT
排序 order by 字段名 别名 列号 表达式/函数 ASC DESC
where
关系判断
> < >= <= = != <>
is null is not null
逻辑判断
and or in between and ()
模糊查询
like ''
%
_
\%
\_
'' \'
"
\\\
函数
单行 一行数据作为参数 输出一个结果
字符串 数值 日期 流程控制 JSON 其他... ...
多行 多条数据作为参数 输出一个结果
AVG SUM MAX MIN COUNT group by
业务逻辑从JAVA代码转移到SQL语句
*/
/*
1多行函数
sum avg count max min
count() 列名
2分组
group by
select
from
where
group by
having
order by
where 行级过滤器 在分组及多行函数之前执行 不能使用多行函数作为判断条件
having 组级过滤器 在分组及多上函数之后执行 可以使用多行函数作为判断条件
优先将条件放在where中
在分组函数中,可以依据一个或者多个字段进行分组
select 后面的字段只能是 分组依据的字段或者多行函数
3多表查询
理论基础 笛卡尔积
字段数是多个表字段的和
信息条数为多个表信息乘积
使用多个表生成笛卡尔积之后,添加筛选条件
SQL99 cross join natural join
内连接
select
from 表a inner join 表b on 关联条件
inner join 表c on 关联条件
where 其他筛选条件
只能显示满足关联条件的数据
外连接
主表和从表
无论是否满足关联条件 主表的数据全都显示,从表根据主表显示,如果没有对应数据,自动补充一行null
左外 左边为主表
右外 右边为主表
select
from table1 left outer join table2 on condition
left outer join table3 on condition
where other condition
自连接查询 ... ...
4子查询
查询条件不明确,需要先用一条SQL语句查询出结果后,再次作为条件
语句分为 父语句和子语句
单行子查询 子语句的结果是一个
多行子查询 子语句的结果可以能是多个甚至是多列
不相关子查询 子语句可以独立运行 和父语句不相关
相关子查询 子语句不可以独立运行 和父语句相关
*/
/*
* MyBatis 一款持久层框架 操作数据库的
* 1 jar包 mysql-connecter mybatis核心jar mybatis依赖的其他一堆jar log4j
* 2 配置文件
* 核心配置文件一个
* properties 导入外部properties文件
* settings 日志打印方式 设置一些性能参数
* typeAliases实体类别名 package = "实体类包"
* enviroments 多个数据库链接信息
* enviroment 一个数据库链接信息
* mappers 导入多个mapper映射文件的
* 映射文件多个
* pojo mapper table
* mapper select insert delete update
* 3 项目包结构 mapper pojo
*
*
* 编码过程
* SqlSessionFactoryBuilder builder =new .....
* SqlSessionFactory factory =builder.builde(stream>>> mybatis.xml)
* SqlSession sqlSession=factory.openSqlSession(true/false);
* sqlSession.selectOne selectList(baseQuery) selectMap insert delete update(baseUpdate)
*
* sql语句属性
* id SQL语句的唯一标识
* resultType 数据封装类型 结果集用哪个类的对象进行封装 增删改没有该属性
* paramaterType 参数类型
*
* #{} 使用预编译语句对象
* ${} 使用普通语句对象做字符串的拼接
*
* MyBatis 基于传统DAO模式开发
* 1 过度依赖SqlSession的方法
* 2 SqlSession的API参数传递不够灵活
* 3 项目中仍然要保留传统的DAO层 SQLSession仅仅是DAO实现类的实现依赖
* 4 SQL语句没有动态变化
*
*
* MyBatis 代理模式下开发项目
* MyBatis 动态SQL
*
*
* MyBatis 多表关联查询
* MyBatis 性能调试
*
*
*
*
* */
MyBatis
1基于Mapper代理模式的开发
mapper
接口文件名和映射文件名相同
映射文件中的namespace和接口的全路径名相同
SQL语句的id和对应的方法名相同
2参数问题 主键回填
1单个基本数据类型 #{}随便写
2多个基本数据类型 #{}别名/arg0 ... param1 ...
3单个引用类型 #{}属性名
4多个引用类型 #{} 别名/arg0.属性名 param1.属性名
5集合/数组 foreach
3动态SQL
if test "ognl表达式"
where 补充where关键字 去掉and前缀
choose when otherwise
<choose>
<when test="">
</when> ... ...
<otherwise>
</otherwise>
</choose>
set 补充了set关键字 去掉了 , 后缀
trim prefix prefixOverride suffix suffixOverride
foreach collection 遍历的集合或者数组 list array
item 中间变量名称 open separator close index
bind
sql片段 include