02-janycode.github.io
2021-07-26 09:52:27 3 举报
AI智能生成
JavaSE、JavaWeb、Java分布式开发学习
作者其他创作
大纲/内容
Tools
<font color="#00a650">JDK1.8-API中文版</font><br>
Notepad++
<font color="#f15a23">Eclipse</font>
常规使用
* 创建项目:File > new > project > Java Project<br>* src下创建包:[右键]new > Package<br>* package下创建类:[右键]new > Class (.java文件)<br>* 修改编辑字体:Windows > Preferences > Gerenal > Appearance > Colors and Fonts > Basic > Text Font > Edit > "Microsoft YaHei Mono"-11<br>* 修改输出字体:Windows > Preferences > Gerenal > Appearance > Colors and Fonts > Debug > Text Font > Edit > "Microsoft YaHei Mono"-11<br>* 重置窗体排布:Windows > Perspective > Reset Perspective<br>
导入项目
* 导入项目:File > Import > General > Existing Projects into Workspace > Browse > [项目根文件夹] > finish
附加源码
* 默认正确,无需改动,如需改动,参考步骤:<br>Windows > Preferences > Java > Installed JRES > 选中JRE > Edit > 选中..\rt.jar > Source Attachment > External location > 找到src.zip
快捷键
* Ctrl+1 快捷修复<br>* <b><font color="#c41230">Ctrl+D</font></b> 快捷删除行<br>* <b><font color="#c41230" style="">Shift+Enter</font></b> 无视光标直接跳入下一行<br>* <b><font color="#00a650">Ctrl+F11</font></b> 一键运行<br>* <b><font color="#c41230">Alt+↑/↓</font></b> 快速移动单/多行<br>* <b><font color="#c41230">Ctrl+Alt+↑/↓</font></b> 快速复制单/多行<br>* Ctrl+M 将当前代码编辑框放大/恢复<br>* <b><font color="#c41230">Alt+/</font></b> 快速补全代码<br> >> sout:System.out.println();<br>* <b>Ctrl+/</b> 快速注释单/多行和恢复(单行注释符 // )<br>* <b>Ctrl+Shift+/</b> 快速注释单/多行和恢复,需选中 (多行注释符 /* */)<br>* /** 快速创建函数的javadoc文档注释<br>* <b>Ctrl+Shift+F</b> 格式化代码(注意印象笔记&搜狗输入法的快捷键冲突)<br><br>* <b><font color="#f15a23">Ctrl+E</font></b> 弹出快速文件选择窗然后上下选择<br>* <font color="#f15a23"><b>Alt+Shift+W</b></font> 选择第一个Package Explorer即可快速定位<br><br>* <b><font color="#c41230">Alt+Shift+R</font></b> 然后修改即可修改所有相同变量<br>* <b><font color="#31a8e0">Ctrl+Q</font></b> 返回上一个Ctrl+鼠标单击跳转的原始位置<br>* <b><font color="#31a8e0">F3</font></b> 在关键字上按,可以跳转进入源码<br>* <b><font color="#31a8e0">Alt+←/→</font></b> 浏览F3跳转源码的轨迹<br>* <b><font color="#c41230">Ctrl+Shift+O</font></b> 快速导包:导入需要的包同时去掉无用的包<br>* <b><font color="#c41230">Alt+Shift+Z</font></b> 选中代码行后,快速创建try-catch块<br><br>* <b><font color="#c41230">Ctrl+O</font></b> 快速显示OutLine悬浮窗,搜索和浏览成员方法<br>* <b><font color="#c41230">Ctrl+2,L </font></b>为调用方法时返回值的本地变量赋值<br>
快速生成代码
<b><font color="#f15a23">Alt+Shift+S</font></b> 弹出源码选项
<b><font color="#f15a23">+o</font></b> 完成构造方法
<b><font color="#f15a23">+r</font></b> 添加geter和seter
<b><font color="#f15a23">+s</font></b> 添加覆盖Object父类toString()方法
<b><font color="#f15a23">+v</font></b> 继承覆盖方法
<b><font color="#f15a23">+c</font></b> 继承构造方法
<b><font color="#f15a23">+m</font></b> 成员的方法
<b><font color="#f15a23">+h</font></b> 添加 hashcode() 和equals()
<font color="#c41230">IntelliJ IDEA</font>
<b>基本使用</b>
<b>Web项目</b>
<font color="#c41230">IDEA创建Web项目</font>
如果已打开项目 File >> Close Project<br>初识启动界面中 <b><font color="#000000">+ Create New Project</font></b><br>
<font color="#000000"><b style="">Java Enterprise</b> >> ☑<b style="">Web Application</b> >> Next</font><br>
<font color="#c41230">IDEA生成war包</font>
配置:<br><b><font color="#000000">Project Structure</font></b>图标 >> <b><font color="#000000">Artifacts</font></b> >> <b><font color="#000000">+</font></b>新增<font color="#000000"><b>Web Application: Arichive</b></font>选择当前项目<b><font color="#000000">xxx:war</font></b> >> OK<br>
生成:<br><b><font color="#000000">Build</font></b> >> <b><font color="#000000">Build Artifacts</font></b> >> 选择<b><font color="#000000">xxx:war</font></b>点击<b><font color="#000000">Build</font></b> >> out/artifacts/xxx_war/xxx_war.war<br>
部署:<br>将xxx_war.war包放在 Tomcat 的 <font color="#f15a23">webapps</font> 目录下,启动服务器会自动解压该web项目,便于直接访问
<b>UML类图</b>
<b>Ctrl+Shift+S</b> 打开全局设置 >> <b>Tools</b> 工具 >> <b>Diagrams</b> 图表 >><br><b>Java Class Diagrams</b> >> <b>☑Fields</b>属性 <b>☑Constructors</b>构造方法 <b>☑Methods</b>成员方法<br><b><font color="#f15a23">Ctrl+Alt+Shift+U</font></b> 显示类图到新标签栏(<b><font color="#c41230">Ctrl+/</font></b>按1:1比例显示,<b><font color="#c41230">Ctrl</font></b>按住可拖动,<b>Alt</b>按住为放大镜)
<b><font color="#0076b3">MySQL Console 关键字大写</font></b>
Settsings(<b>Ctrl+Alt+S</b>) -->Editor --> Code Style --> SQL --> MySQL 将keywords设置为大写(To upper)
快捷键
窗口菜单
<b><font color="#5c5c5c">Ctrl+Alt+S</font></b> 全局设置菜单窗口<br><br><b><font color="#f15a23">Ctrl+P</font></b> 方法的参数提示<br><b><font color="#f15a23">Ctrl+Q</font></b> 方法的注释+声明提示<br><b><font color="#00a650">Ctrl+F12</font></b> 显示当前文件的结构(快速跳转)<br><b>Ctrl+[ </b>/<b> ]</b> 跳转{ }作用域开始 / 结束位置<br><br><b><font color="#00a650">Ctrl+E</font></b> 显示最近打开过的文件<br><font color="#00a650" style="">Ctrl+Tab</font> 切换编辑文件或项目树,Ctrl需按住<br><b><font color="#00a650">Alt+←/→</font></b> 前后切换编辑的文件标签,结合Ctrl+Tab摆脱鼠标<br><br>Alt+` 弹出版本控制窗口,如history、Git等<br><b><font color="#f15a23">Alt+1</font></b> 切到<b>Project</b>项目窗口(已打开则收缩) >> ESC 切回代码区<br>Alt+2 切到Favorites收藏夹窗口(已打开则收缩)<br><b><font color="#f15a23">Alt+4</font></b> 切到<b>Run</b>运行窗口(已打开则收缩)<br>Alt+6 切到TODO窗口(已打开则收缩)<br>Alt+7 切到Structure结构窗口(已打开则收缩) - <b><font color="#00a650">Ctrl+F12</font></b>更好<br><b><font color="#f15a23">Alt+8</font></b> 切到<b>Service</b>窗口(已打开则收缩),如MySQL运行结果<br>Alt+0 切到Message窗口(已打开则收缩)<br><br><b><font color="#f15a23">Ctrl+B</font></b> 跳转进入调用方法<br><b><font color="#f15a23">Ctrl+Alt+B</font></b> 跳转进入继承的子类方法<br><b><font color="#f15a23">Ctrl+Shift+B</font></b> 跳转进入接口的实现类方法<br><b><font color="#f15a23">Ctrl+ALt+←/→</font></b> 返回跳转的上一步或下一步<br><br><b><font color="#c41230">Ctrl+Alt+U</font></b> 显示类的继承/实现关系图<br><b>Ctrl+Alt+B</b> 显示继承子类或实现类<br><b>Ctrl+Alt+P</b> 显示被继承父类或被实现的接口<br><b><font color="#c41230">F4</font></b> 跳转到实现源码<br>-----------------------------------------------------------<br>
无敌通用
<font color="#00a650"><b>Alt+Insert</b> </font> 插入一切<br><b><font color="#00a650">双击Shift+Tab</font></b> 搜索一切
快速编辑
-----------------------------------------------------------<b><font color="#c41230"><br>m</font>ain+Tab</b> 生成main方法,类名下 m 即可<br><b><font color="#c41230">so</font>ut+Tab</b> 生成输出语句,so 即可<br>new Xxxx( )<b><font color="#c41230">.var</font></b> 快速生成引用赋值<br><b><font color="#f15a23">fori</font></b> 快速生成for循环 - i 整数遍历<br><b><font color="#f15a23">iter</font></b> 快速生成增强for循环 - foreach<br><b>itar</b> 快速生成array for循环 - 字符串遍历<br><b>itit</b> 快速生成iterator迭代-while( ) next( )<br><b>itco</b> 快速生成Collection迭代 - for<br><b><font color="#f15a23">.foreach</font></b> 快速foreach循环<br><br><b><font color="#c41230">Ctrl+X</font></b> 删除+剪切当前行<br><b>Ctrl+C</b> 高亮+复制当前行<br><b><font color="#c41230">Ctrl+D</font></b> 立即复制当前行到下一行<br><b><font color="#c41230">Ctrl+Shift+↑/↓</font></b> 快速移动代码行<br><br>Ctrl+/ 或 Ctrl+Shift+/ 单行 或 多行注释<br><b><font color="#c41230">Ctrl+O</font></b> 重写方法(继承)<br>Ctrl+i 实现方法(实现接口) Alt+Enter代替<br><b>Ctrl+Shift+U</b> 大小写转换<br>Ctrl+Shift+J 合并选中的行变1行<br><b><font color="#00a650">Ctrl+Alt+L</font></b> 自动缩进及格式化代码<br><b><font color="#f15a23">Ctrl+"+/-"</font></b> 当前方法展开、折叠<br>Ctrl+Shift+"+/-" 全部展开、折叠<br><br><b>Alt+/</b> 代码提示(默认自动提示)<br><b style="color: rgb(241, 90, 35);">F2 </b><font color="#5c5c5c">快速定位到错误代码</font><br><b style="color: rgb(241, 90, 35);">Alt+Enter</b> 自动修正波浪线错误<br><b><font color="#00a650">Alt+Insert</font></b> 生成代码(构造、get/set等)<br><b><font color="#f15a23">Ctrl+Alt+T</font></b> 生成try-catch等各种代码块<br><b><font color="#c41230">Ctrl+Alt+O</font></b> 优化导入的类和包(顺序)<br>
查找替换
-----------------------------------------------------------<b><br><font color="#00a650">双击Shift+Tab</font></b> 查找一切<br><b><font color="#f15a23">Ctrl+N+N</font></b> 全局搜索Class<br><b>Ctrl+F</b> 当前文件执行查找<br>Ctrl+Shift+F 整个项目查找文本<br><b><font color="#c41230">Ctrl+R</font></b> 当前文件执行替换<br><b><font color="#f15a23"><br>Ctrl+W</font></b> 自动按语法选中代码(递增范围)<br><b><font color="#f15a23">Shift+F6</font></b> 批量重命名同1个变量名<br><b><br>Ctrl+G</b> 定位行<br><b><font color="#c41230">Ctrl+Alt+←/→</font></b> 前后跳转编辑过的位置<br>Alt+F7 查看函数/变量/类的所有引用到的地方<br><b><font color="#c41230">F4</font></b> 当前类中查找变量的定义位置<br><b>Ctrl+Shift+F7</b> 高亮显示选中的相同文本,ESC取消高亮<br>
编译运行
-----------------------------------------------------------<b><font color="#00a650"><br>Ctrl+Shift+F10</font></b> 编译运行当前文件目标<br><b>Shift+ESC </b>关闭运行结果显示窗口【通用】
<b>插件</b>
<b><font color="#fdb813">Translation</font></b>
谷歌翻译插件<br><b>Ctrl+Shift+Y</b> 可快捷翻译<br><b>Ctrl+Shift+X</b> 可将中文翻译英文后替换(变量取名)
<b><font color="#fdb813">CamelCase</font></b><br>
大/小/驼峰/下划线切换<br><b>Alt+Shift+U</b> 来回切换字符串样式,直到满意
<b><font color="#fdb813">SequenceDiagram</font></b><br>
生成方法调用序列图<br>方法名上右键选择 <b>Sequence Diagram</b>
<b><font color="#fdb813">GenerateAllSetter</font></b>
生成局部变量的所有set方法调用<br>变量上 <b>Alt+Enter</b>
<b><font color="#fdb813">Key Promoter X</font></b><br>
右侧折叠小窗记录常用操作,显示快捷键提示
<b><font color="#fdb813">Jclasslib Bytecode Viewer</font></b>
查看字节码文件<br><b>View</b> >> <b>Show ByteCode With Jclasslib</b>
<b><font color="#fdb813">Gson Format</font></b>
直接类内 Alt+Insert 选最后一个<br>或者类内 <b>Alt+S</b> 贴入json字符串,自动生成属性+get/set方法
<b><font color="#fdb813">Easy Code</font></b>
右侧小窗 Database 数据库中连接后<br>右键 <b>表名</b> 选择 <b>Easy Code </b>>><b> Generate Code</b> 自动生成数据映射关系的包和类
<b><font color="#fdb813">Code Glance</font></b>
代码编辑区右侧缩略图,同Sublime Text
<b><font color="#fdb813">GamelCase</font></b>
对单词组合命名的变量/方法/类名使用:<br><b>Alt + Shift + U</b> 可以调整不同方式命名,不停按6种直到满意。
<b><font color="#fdb813">Alibaba Java Coding Guidelines</font></b>
阿里巴巴 Java 编程规范,自动提示/警告/报错<br><b>Alt + Enter</b> 修复
<font color="#0076b3">SQLyog</font>
装好MySQL后,该客户端工具只需要输入<font color="#c41230">密码</font>即可使用。
工具 >> 首选项 >> 字体编辑器设置
<font color="#0076b3">Navicat</font>
Hbuilder[X]
Hbuilder
Java实现,集成插件。
<font color="#c41230">HbuilderX</font>
C++实现,没有集成插件,更快更轻量。
插件安装:工具 >> 插件安装
<b><font color="#000000">快捷键方案</font></b>:工具 >> 预设快捷键方案切换 >> Intellij IDEA/Webstorm
快捷键
Ctrl+/ 快速注释<br>Ctrl+N 快速新建
JavaSE
环境搭建
概述
特点
面向对象
模拟现实世界,解决现实问题。<br>
简单
Java有虚拟机,内置了垃圾收集器(GC),<font color="#c41230">自动完成内存空间的管理</font>。<br>
跨平台
跨操作系统(Windows<C#>,Unix-Linux,MacOS,Solaris)、服务器、数据库。
由来
1995年推出<br><font color="#c41230"> 1996</font>年发布JDK1.0<br> 2009年被Oracle收购<br> 2014年由Oracle发布Java 8.0<JDK1.8><br>
分类
JavaSE
Java Platform Standard Edition (Java平台标准版) CoreJava<br>
JavaEE
Java Platform Enterprise Edition (Java平台企业版) 企业级开发<br>
JavaME
Java Platform Micro Edition (Java平台微小版) Java最初的定位(机顶盒)
运行机制
先编译,再解释。<br>
*.java(源文件) -> 编译 -> *.class(字节码文件) -> 执行 -> Win/Unic/MacOS/Others-(JVM)<br>
Java设计理念:Write Once Run Anywhere.<br>
名词解释
JVM
(Java Virtual Machine)虚拟机:使用软件在不同操作系统中模拟相同的环境。
JRE
(Java Runtime Environment)运行环境:包含JVM和解释器,完整的Java运行环境。
JDK
(Java Development Kit)开大环境:包含JRE[JVM+解释器] + 类库 + 开发工具包(编译器+调试工具)。
环境搭建
JDK获取
oracle官网获取,JDK1.8使用最为广泛。
https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html<br>
JDK安装
非C盘<br>
路径不带中文或空格
JDK包含JRE可跳过不装JRE
建议:<b><font color="#c41230">D:\Java</font></b>
JDK环境变量配置<br>
win+E >> 右键(空白处) >> 属性 >> 环境变量
* <font color="#c41230">新建</font>系统变量:<br> 变量名:<font color="#f15a23"><b>JAVA_HOME</b></font><br> 变量值:D:\Java\jdk1.8.0_231 (找到实际安装路径)
* <font color="#c41230">新建</font>系统变量:<br>变量名:<font color="#f15a23"><b>CLASS_PATH</b></font><br>变量值:.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar
* <font color="#c41230">编辑</font>Path变量:<br>变量名:<font color="#f15a23"><b>Path</b></font><br> 变量值:;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin; (末尾添加)
验证:cmd命令窗口中输入"javac -version"
常用DOS命令
更换盘符:d:<br> 查看当前目录下的文件和文件夹:dir<br>创建文件夹:mkdir 文件夹名字<br>进入文件夹:cd 文件夹名字<br>返回上一级目录:cd ..<br>清空屏幕:cls<br>删除文件:del 文件名<br>删除文件夹:rd 文件夹名称<br>退出:exit
第1个Java程序
源码
class HelloWorld {<br> public static void main(String[] args) {<br> System.out.println("Hello, Java!!!");<br> }<br>}
编译
javac HelloWorld.java<br>
运行
java HelloWorld
类的阐述
* 同一个源文件中可以定义多个类<br>* 相同源文件中的多个类编译后会生成各自的.class文件<br>* <font color="#c41230">一个类中只能有一个主函数main</font>,每个类都可以有各自的主函数main<br>* public修饰的类成为<font color="#c41230">公开类,要求类名与文件名必须相同</font>,包括大小写<br>* <font color="#c41230">一个源文件中只能有一个public公开类</font><br>
Package(包)
作用:类似文件夹,用于管理归纳字节码(.class)文件。
语法:<font color="#f15a23"><b>package</b> 包名;</font>
多级:<font color="#f15a23"><b>package</b> 包名.包名;</font>
位置:必须写在源文件的第一行。
带包编译:<font color="#f15a23"><b>javac -d 目录名 源文件.java</b> </font>(会自动创建package包目录)
带包运行:<font color="#f15a23"><b>java 包名.类名</b></font> (包名+类名又称全限定名)
doc文档生成
生成外部文档:<b><font color="#f15a23">javadoc -d 目录名 源文件.java</font></b>
文档注意事项:<br>1.源文件编码问题,中文使用utf-8;<br>2.主要查看index.html文件
编码规范
终极参考:《阿里巴巴JAVA开发手册.pdf》
语言基础
变量
计算机内存中一块存储空间,是存储数据的基本单位
组成部分
数据类型
变量名
值
声明方式
先声明,再赋值
<font color="#f15a23">数据类型 变量名;<br>变量名 = 值;</font>
声明并赋值
多个同类型变量的声明与赋值
数据类型
基本数据类型
整数
<font color="#c41230">byte</font>
1个字节 -128 ~ 127
<font color="#c41230">short</font>
2个字节 -32768 ~ 32767
<font color="#c41230">int</font>
4个字节 -2^31 ~ 2^31-1
<font color="#c41230">Java中任何一个整数,默认的类型为int,如果整数超过int取值范围,则均报错为过大的整数</font>
<font color="#c41230">long</font>
8个字节 -2^63 ~ 2^63-1
long类型的赋值整数如果超过了int类型取值范围,则需要在数字后加 "<font color="#f15a23">L</font>" 以标记为long类型
小数
<font color="#c41230">float</font>
4个字节 Float.MIN_VALUE ~ Float.MAX_VALUE
如果使用单精度float类型,则需要在数字后面加"<font color="#f15a23">F</font>"表示单精度值
<font color="#c41230"><b>double</b></font>
8个字节 Double.MIN_VALUE ~ Double.MAX_VALUE
<font color="#c41230">Java中任意一个小数默认类型为双精度类型double</font>
布尔
<font color="#c41230">boolean</font>
1个字节(根据具体环境) true / false
<font color="#c41230">Java中的boolean类型变量不能参与算术运算!</font>
字符
<font color="#c41230">char</font>
2个字节
转义字符 \
\' \" \\ \n \t
赋值
<font color="#c41230">通过字符直接赋值【常用】</font>
引用数据类型
字符串
<font color="#c41230">String</font>
任何""之间的内容都是字符串,包括空格
数组
对象
类型转换
自动类型转换
两种类型兼容,目标类型<font color="#c41230">大于</font>源类型
强制类型转换
两种类型兼容,目标类型<font color="#c41230">小于</font>源类型
转换规则
整数长度足够,数据完整
整数长度不够,数据截断
小数强转整数,数据截断
字符整数互转,数据完整
保证正整数转换成字符,可以正常显示
<font color="#c41230">boolean不可与其他类型转换</font>
自动类型提升
提升优先级规律:<font color="#c41230">double << float << long <</font> <b>int</b> <font color="#0076b3"><< short/byte</font><br>
<font color="#c41230">两个</font>操作数中有一个为优先级中的类型,计算结果提升为优先级中对应类型
任何类型与String相加(+)时,实为拼接,结果自动提升为String
<b>【<font color="#381e11">坑</font>】</b>num1+num2+string1:<font color="#c41230">两个</font>操作数为数值时,相加;<font color="#c41230">两个</font>操作数中有一个为String时,拼接。
运算符
算术运算符
+ - * / %
赋值运算符
= += -= *= /= %=
关系运算符
> < >= <= == !=
逻辑运算符
&& || !
三元运算符
布尔表达式 ? 结果1 : 结果2
控制台输入
1.导包
导包语法:<font color="#f15a23"><b>import</b> 包名.类名;</font><br>
功能: 将外部class文件功能引入到自身文件中
位置: jdk1.8.0_121\jre\lib\rt.jar 压缩包中
import java.util.Scanner
2.声明
<font color="#5c5c5c">Scanner 类型的变量</font>
Scanner input = new Scanner(System.in);
3.接收
输入类型
<font color="#f15a23">.nextInt();</font> // 获得整数<br><font color="#f15a23"> .nextDouble();</font> // 获得小数<br><font color="#f15a23">.next();</font> // 获得字符串<br><font color="#f15a23">.next().charAt(0);</font> // 获得字符串的第一个字符
如果输入了不匹配的数据,则会产生 <font color="#c41230">java.util.InputMismatchException</font> 异常
TestScanner.java
选择与分支结构
概念:根据已知条件进行逻辑判断,满足条件执行操作
选择结构
基本if选择结构
if-else选择结构
多重if选择结构
适用于区间判断
嵌套if选择结构
语法正确、任意嵌套
分支结构
switch-case
可判断:<font color="#c41230">byte,short,int,char,String(JDK7+)</font>
switch中多个case的取值不可以相同
switch自动向下贯穿的特性,如需中止使用break关键字
局部变量
概念:声明在函数内部的变量,必须先赋值再使用
作用范围:从定义行开始到所在的代码块结束
注意:<font color="#c41230">多个变量在一个重合的作用范围内,不可出现重名</font>
循环结构
概念:通过某个条件,重复执行一段逻辑代码<br>
基本结构
while循环
首次即有入口条件,适用于循环次数明确的情况
先判断,再执行。
次数:0-n
do-while循环
首次没有入口条件,适用于循环次数不明确的情况
先执行,再判断。
次数:<font color="#c41230">1-n</font>
for循环
首次即有入口条件,适用于循环次数明确的情况
初始部分只执行一次,且可以省略
次数:0-n
流程控制关键字
<b><font color="#f15a23">break</font></b>
终止循环,<font color="#c41230">跳出</font>当前层级循环(1层)
跳出switch结构、跳出循环结构
<b><font color="#f15a23">continue</font></b>
结束本次,<font color="#c41230">跳过</font>当前层级循环(1层),进入下一次
函数
概念:实现特定功能的一段代码,可以反复使用。
设计:遵循单一职能原则,一个函数只做一件事
规则:一个类中可以定义多个函数,函数之间是并列关系,不可嵌套
格式: <br>
<font color="#f15a23"><b>public static void</b> 函数名称 () {<br> // 函数主体<br>}</font>
调用:函数名();
参数:
调用函数时,所传入的数据被称为"参数"
定义
public static void 函数名称 (<font color="#c41230">函数形参</font>) { // 形参 等价于 局部变量的声明<br> // 函数主体<br>}
调用:函数名(<font color="#c41230">实际参数</font>); // 实参 等价于 局部变量的赋值操作
Tips:<b>【字符串比较】</b>
== 默认比较的地址值,不是字符串内容
str1<font color="#f15a23"><b>.equals(</b></font>str2<font color="#f15a23"><b>);</b></font> 含义:比较s1中存储的字符串是否与s2相同, true相同
!str1.equals(str2); 含义:比较s1中存储的字符串是否与s2不同, true不同
返回值和返回值类型
定义返回值类型:基本数据类型、引用数据类型、void
return value; // 函数可以返回一个结果,类型必须与函数定义的返回值一致<br>
一个函数只能有一个返回值,如果函数中包含分支条件,需要保证所有的分支都有返回值
return 的两种用法
return value; // 表示结束当前函数,并伴有返回值,返回到函数的调用处<br>
return; // 表示结束当前函数,直接会返回到函数调用处<br>
多级调用
递归需要设置有效的出口条件,避免无穷递归<br>
出口条件可能为多个
递归经典:斐波那契数列
TestFibonacci.java<br>
数组
概念:一组连续的存储空间,存储多个相同数据类型的值
特点:<font color="#c41230">类型相同,长度固定</font>。<br>
组成
数组中每个格子称为数组的元素<br>
数组的<font color="#c41230">下标从 0 开始</font>,有效范围:0 ~ 数组长度-1<br>
数组<font color="#c41230">默认值</font>:整数0, 小数0.0, 字符\u0000, 布尔false, 其他null<br>
创建
①声明并分配空间<br><font color="#f15a23">数据类型[] 变量名 = <b>new</b> 数据类型[数组大小值];</font><br>eg:<br>int[] arr = new int[5];
②先声明,再分配空间<br><font color="#f15a23">数据类型[] 变量名;<br>变量名 = <b>new</b> 数据类型[数组大小值];</font><br>eg:<br>int[] arr;<br>arr = new int[5];
③声明并赋值(繁)<br><font color="#f15a23">数据类型[] 数组名 = <b>new</b> 数据类型[]{value1, value2, value3, ...};</font><br>eg:<br>int[] arr = new int[]{11, 22, 33, 44, 55, 66};
④声明并赋值(简)<br><font color="#f15a23">数据类型[] 数组名 = {value1, value2, value3, ...};</font><br>eg:<br>int[] arr = {11, 22, 33, 44, 55, 66};
访问
<font color="#f15a23">数组名[下标];</font><br> eg:<br>int[2];<br>
长度
<font color="#f15a23">数组名.length</font><br>eg:<br>arr.length<br>
数组创建之后,<font color="#c41230">长度不可变</font>。
遍历
for (int i = 0; i < <font color="#c41230">arr.length</font>; i++) {<br> // arr[i] 使用数组元素<br>}<br>
扩容
思路:创建一个新的更大的数组,将原数组内容复制到新数组中。
3种方式
循环将原数组内容逐一复制到新数组
<font color="#f15a23"><b>System.arraycopy</b>(原数组, 原数组起始, 新数组, 新数组起始, 长度);</font>
<font color="#f15a23"><b>java.util.Arrays.copyOf</b>(原数组, 新长度);</font> // 返回带有原数组值的新数组
数组变量中存储的是数组的首地址
返回值为数组类型,<font color="#c41230">可直接赋值给原数组</font>
【增删改查】
TestArrayAction.java
基本数据类型与引用数据类型
基本数据类型变量中存储的是 <font color="#c41230">值</font><br>
引用数据类型变量中存储的是 <font color="#c41230">地址</font>
排序
冒泡排序
相邻两个值比较大小(<font color="#c41230" style="">arr[j] > arr[j+1]</font>),互换位置
记忆:外层<font color="#c41230">0 ~ <<b>length-1</b></font>, 内层<font color="#c41230">0 ~ </font><<font color="#c41230"><b>length-1-i</b></font>
选择排序
固定值与其他值比较大小(<font color="#c41230">arr[i] > arr[j]</font>),互换位置
记忆:外层<font color="#c41230">0 ~ <<b>length-1</b></font>, 内层<font color="#c41230">i+1 ~ <<b>length</b></font>
JDK排序
<font color="#f15a23"><b>java.util.Arrays.sort</b>(数组名);</font>
默认升序,降序需手工倒序
二维数组
概念:一维数组中的一维数组,数组中的元素还是数组
访问:<font color="#f15a23">数组名[高维下标][低维下标]</font>
高维数组中的每一个元素,存储了低维数组的<font color="#c41230"><b>地址</b></font>。
定义方式
* 先声明、再分配<br><font color="#f15a23"> 数据类型[][] 数组名;<br> 数组名 = new 数据类型[高维长度][低维长度];</font>
* 声明并分配空间<br><font color="#f15a23"> 数据类型[][] 数组名 = new 数据类型[高维长度][低维长度];</font>
* 声明并赋值(繁)<br><font color="#f15a23"> 数据类型[][] 数组名 = new 数据类型[高维长度][];</font> //不规则数组<br><font color="#f15a23">数组名[i] = new 数据类型[j];</font> //自行new低维属组
* 声明并赋值(简)<br><font color="#f15a23"> 数据类型[][] 数组名 = {{v1, v2, v3}, {v4, v5, v6}, {...}};</font> //显示初始化
经典案例:杨辉三角
Demo
面向对象(OOP)
对象
万物皆对象。对象一定拥有自己的特征和行为。
特征:称之为<b><font color="#f15a23">属性</font></b>,一般为名词,代表对象有什么。
行为:称之为<b><font color="#f15a23">方法</font></b>,一般为动词,代表对象能做什么。
程序中的对象:来自于模板(<font color="#c41230">类</font>)创造出来程序中的实体(<font color="#c41230">对象</font>)
类与对象
类:定义了对象应具有的特征和行为,<font color="#c41230">类是对象的模板</font>
类的抽取:在一组相同或者类似的对象中,抽取共性的特征和行为。
对象:拥有多个特征和行为的实体,<font color="#c41230">对象是类的实例</font>
实例变量&局部变量
定义位置
局部变量:方法或方法内的结构中
实例变量:类的内部,方法的外部
默认值
局部变量:无默认值
实例变量:字面值(与数组相同0/null)
使用范围
局部变量:从定义行到其结构结束行
实例变量:本类有效
命名冲突
局部变量:不允许重名
实例变量:可与局部变量重名,局部变量优先
方法重载(Overload)
概念:一个类中定义多个相同名称的方法
到底采用哪种形式,需要取决于调用者给定的方法的参数。
要求
<font color="#c41230"><b>方法名称相同</b></font><br>
<font color="#c41230"><b>参数列表不同</b></font>(类型、个数、顺序)
与<font color="#0076b3">访问修饰符、返回值类型、形参的名称</font>均无关
构造方法(Constructor)
概念:类中的特殊方法,主要用于创建对象
要求
<b><font color="#c41230">名称与类名完全相同</font></b>(包括大小写)<br>
<b><font color="#c41230">没有返回值类型修饰符</font></b>(void也没有)
<font color="#0076b3">创建对象时触发构造方法的调用</font>,不可通过.访问符访问<br>
对象创建过程
内存堆区中开辟对象空间
为各个属性赋予初始值(默认0 / 0.0 / null)
执行构造方法中的代码
[将对象的地址赋值给变量]
注意
<font color="#c41230">构造方法也可以重载</font>,遵循重载规则
如果没有显示定义构造方法,编译器会<font color="#c41230">默认提供一个无参</font>构造方法
如果显示定义了有参构造方法,则<font color="#c41230">无参构造方法必须也要显示定义</font>
this关键字
概念:this是类中的默认引用,代表当前实例(当前对象)
语法
<font color="#f15a23"><b>this.</b>属性名 / <b>this.</b>函数名( )</font>
<font color="#f15a23"><b>this([</b>参数列表<b>])</b></font>
三种用法
调用实例属性、实例方法,eg:this.name、this.sayHi()
调用本类中的其他构造方法,eg:this( )、this(实参)
this([实参])必须在<font color="#c41230"><b>构造方法</b></font>的<font color="#c41230"><b>首行</b></font>,仅可在构造方法中使用
表示当前方法(暂未用到)
三大特性
封装
概念:尽可能隐藏对象的内部实现细节,控制对象的修改和访问权限
访问修饰符: <b><font color="#f15a23">private</font></b> <font color="#f15a23">类型 属性;</font>(可将属性全修饰为私有,仅本类可见)
<b><font color="#f15a23">get</font></b>/<b><font color="#f15a23">set</font></b>方法是外界访问对象私有属性的唯一通道,方法内部对属性检测和过滤
提供<b>public公共访问方法</b>,以保证数据可以正常录入和访问
继承
程序中的继承,是类与类之间<font color="#c41230">特征</font>和<font color="#c41230">行为</font>的一种赠予或获得。
类与类之间必须满足 <font color="#c41230">is a</font> 的关系。
父类的选择:功能越精细,重合点越多的,就越接近直接父类。<br>
父类的抽象:<br>根据程序需要使用到的多个具体类,进行<font color="#c41230"><b>共性提取</b></font>,进而定义父类。<br>在一组相同或类似的类中,<b><font color="#c41230">抽取特征和行为</font></b>,定义在父类中,实现重用。
继承语法:<font color="#f15a23">class 子类名 <b>extends</b> 父类名{ }</font> //定义子类时,显式定义父类<br>
完整的子类:完整子类 = 父类共性 + 子类独有<br>
Java为<b><font color="#c41230">单继承</font></b>,一个类只能有一个直接父类,但<font color="#c41230"><b>可以多级继承</b></font>,属性和方法逐级叠加。
不可继承
<font color="#c41230">构造方法</font>:类中的构造方法,只负责创建本类对象,不可继承
<font color="#c41230">private修饰的属性/方法</font>:仅本类可见,不可继承
<font color="#c41230">父子类不在同一个package中,且default修饰的属性和方法</font>,不可继承
访问权限修饰符:<br><b><font color="#f15a23">private/</font><font color="#381e11">default</font><font color="#f15a23">/</font><font color="#0076b3">protected</font><font color="#f15a23">/</font><font color="#c41230">public</font></b>
public 任何
<font color="#c41230">protected 父子</font>
<font color="#c41230">default 同包</font>
private 本类
跨包访问
<font color="#c41230">写全限定名</font>(包名.类名),eg: java.util.Arrays.copyOf(...);
<font color="#c41230">导包</font>(import),eg: import java.util.Arrays;
方法重写(Override)
同名:<b>方法覆盖</b>
当父类提供的方法无法满足子类的需求时,可在子类中定义和父类相同的方法进行覆盖(Override)
方法覆盖原则
<b><font color="#f15a23">方法名称、参数列表、返回值类型</font><font color="#c41230">必须与父类相同</font></b>;
<b><font color="#f15a23">访问修饰符</font><font color="#c41230">应与父类相同或更宽泛</font></b>;
执行机制:子类覆盖父类方法后,调用时优先执行子类覆盖后的方法
super关键字
用法1:子类去<font color="#c41230">访问</font>父类重名的属性/方法时(属性遮蔽、方法覆盖),使用<b><font color="#f15a23">super.</font></b>专项访问父类的属性/方法
用法2:子类构造方法在<font color="#c41230">调用</font>父类构造方法时
<b><font color="#f15a23">super( )</font></b> 默认调用父类无参构造方法,<font color="#c41230">隐式存在于构造方法的首行</font>
<b><font color="#f15a23">super(参数)</font></b> 指定调用父类有参构造方法,<font color="#c41230">显式调用且编译器不在提供super( )执行</font>
this与super
同一个子类构造方法中,<b><font color="#c41230">super( )和this( )不可同时存在</font></b>
当子类构造中使用了this()或this(实参),即不可再同时书写super()或super(实参),会由this()指向的构造方法完成super()的调用
继承关系下对象的创建
创建
继承关系下构建子类对象时,会先构建父类对象
由"父类共性" + "子类独有" 组合成一个完整的子类对象
流程
<font color="#c41230">① 构建父类对象</font>
<font color="#c41230">② 初始化自身属性</font>
<font color="#c41230">③ 执行自身构造方法中的逻辑代码</font>
多态
概念:父类引用指向子类对象,从而产生多种形态。eg: Animal a = new Dog();
二者具有直接或者间接的继承关系时,<font color="#c41230">父类引用可指向子类对象</font>,形成多态。
父类引用仅可调用父类所声明的属性和方法,<font color="#c41230">父类不可调用子类独有的属性和方法</font>。
多态场景下,如果<font color="#c41230">子类覆盖过父类的方法,优先执行子类覆盖后的方法</font>;否则执行父类的方法
多态的两种使用场景
<b><font color="#c41230">父类引用作为方法的【形参】</font></b>,实现多态,使方法参数的类型更为宽泛 (该父类任一子类均可作为实参传入)
<b><font color="#c41230">父类引用作为方法【返回值】</font></b>,实现多态,使方法可以可以返回不同的子类对象
<font color="#0076b3">向上转型(装箱)</font>
概念:<font color="#0076b3">父类引用中保存真实子类对象</font>。(<b>多态核心概念</b>)
eg: Animal a = new Dog(); // <font color="#16884a">对象层面的自动类型转换</font>
调用:仅可调用父类中所声明的属性和方法(遵循属性遮蔽/方法覆盖原则)
<font color="#0076b3">向下转型(拆箱)</font>
概念:<font color="#0076b3">将父类引用中的真实子类对象,强转回子类本身类型</font>。
eg: Animal a = new Dog();<br> Dog dog = (Dog)a; // <font color="#16884a">对象层面的强制类型转换</font><br> <strike>Cat cat = (Cat)a;</strike> // <b><font color="#c41230">Error</font></b>: 不是真实子类对象new Dog(),编译OK,运行则会抛出类型转换异常:<font color="#c41230">java.lang.ClassCastException</font>
调用:只有转回子类真实类型,才可调用子类独有的属性和方法。
向下转型前应该判断引用中的对象真实类型,保证类型转换的正确性。
语法: <font color="#f15a23" style="">父类引用<b> instanceof </b>子类类型</font> // <font color="#16884a">返回boolean类型结果,意为:父类包含子类对象真实类型,true包含,false不包含</font>
三修饰符
<font color="#381e11">abstract</font>
修饰 <b>类</b>
概念:不够完整,不够具体,不能独立存在 的对象模型
语法:<font color="#f15a23" style=""><b>abstract </b>class 类名 {}</font>
作用
抽象类,<font color="#c41230">不能直接独立new对象</font>;
<font color="#c41230">可被子类继承</font>,提供共性属性和方法;
<font color="#c41230">可声明为引用,强制使用多态</font>(更纯粹的多态);
抽象类的构造方法作用:<font color="#c41230">构建子类对象时,先构建父类对象</font>(父类共性 + 子类独有 = 完整子类对象)
经验:abstract修饰后的抽象父类,依附于子类对象存在
修饰 <b>方法</b>
概念:抽象方法,不够完整、不够具体 的方法
语法:<font color="#f15a23" style="">访问权限修饰符 <b>abstract</b> 返回值类型 函数名([参数列表]);</font>
作用
<font color="#c41230">只有方法声明</font>,没有方法实现;
<font color="#c41230">必须包含在抽象类中</font>(abstract class XX{});
<font color="#c41230">强制子类必须实现该方法</font>,提供完整的、具体的调用版本;
总结
子类继承抽象类,<b><font color="#c41230">子类必须覆盖父类中所有的抽象方法</font></b>,否则子类还是抽象类;
抽象类中不一定有抽象方法,但<font color="#c41230">有抽象方法的类一定是抽象类</font>。
<font color="#381e11">static</font>
实例属性,是每个对象各自持有的独立内存空间(多份),对象单方面修改,不会影响其他对象。
静态属性,是整个类共同持有的共享空间(<b><font color="#c41230">一份</font></b>),<font color="#c41230">任何对象修改,都会影响其他对象</font>。
Java中规定:<font color="#c41230">不能将方法体内的局部变量声明为 static!</font>
<b><font color="#f15a23">static</font></b> 修饰的成员
静态属性 - 类属性
静态方法 - 类方法
不必创建对象,可直接通过类名访问【推荐】:<b><font color="#f15a23">类名.静态成员</font></b>
静态方法规则
静态方法<font color="#c41230">允许直接访问静态成员</font>(不需要this.);
静态方法<font color="#c41230">不允许直接访问非静态成员</font>;
静态方法中<font color="#c41230">不允许使用this或super关键字(构造方法可以)</font>;
静态方法<font color="#c41230">可以继承</font>,<font color="#c41230">不能重写</font>(覆盖)、<font color="#c41230">没有多态</font>;
静态代码块
在执行类时,希望先执行的初始化动作,<br>可以使用static定义一个静态代码区域,在类加载时即会被执行仅有的一次。
代码示例
类加载
JVM<font color="#c41230">首次使用</font>某个类时,需通过CLASSPATH查找该类的.class文件
将.class文件中对类的描述信息<font color="#c41230">加载到内存中,进行保存</font>
单独调用类加载语法:<b><font color="#f15a23">Class.forName("全限定名");</font></b>
类加载时
触发:静态属性和静态代码块的执行 - (<font color="#c41230"><b>仅1次</b></font>)
顺序:静态属性初始化之后执行静态代码块
作用:可谓静态属性赋值,或必要的初始化行为
<b><font color="#381e11">final</font></b>
概念:最后的,不可更改的。—— 保护类/方法/变量的功能和值
修饰内容
类(最终类)
此类<font color="#c41230">不能被继承</font>,eg:String, Math, System均为final修饰的类
方法(最终方法)
此方法<font color="#c41230">不能被覆盖</font>。
变量(最终变量)
此变量<font color="#c41230">值不能被改变</font>(<b><font color="#f15a23">常量</font></b> - 通常变量名全大写),eg: Math.PI
实例常量赋值
<font color="#0076b3"><b>显式初始化、动态代码块、构造方法</b></font>
要求
①DeadLine:在<font color="#c41230">构造方法完成之前</font>,为实例常量赋值即可;
②如果在构造方法中为实例常量赋值,必须<font color="#c41230">保证所有的构造方法都能对其正确赋值</font>。
静态常量赋值
<b><font color="#0076b3">显式初始化、静态代码块</font></b>
要求
①Deadline:在<font color="#c41230">类加载完成之前</font>,为静态常量赋值即可。
对象常量赋值
final修饰基本类型:<font color="#c41230">值不可变</font>
final修饰引用类型:<font color="#c41230">地址不可变</font>
final作为形参使用
拷贝引用,<font color="#c41230">为了避免引用值(地址)发生改变</font>。<br>例如被外部类的方法修改等,而导致内部类得到的值不一致,于是用final来让该引用不可改变。
接口【重要】
什么是接口
Java为单继承,当父类的方法种类无法满足子类需求时,可<font color="#c41230"><b>实现接口用以扩容子类能力</b></font>。<br>即:Java中使用抽象类/父类表示通用属性时,每个类只能继承一个类,假如子类已经从一个父类继承了,就不能再继续继承另外的父类。<br>但每个类可以实现多个接口,这样子类就拥有了更多的能力。
微观概念:<font color="#c41230">接口是一种能力和约定</font>。
接口的定义:代表了某种能力
方法的定义:能力的具体要求
宏观概念:<font color="#c41230">接口是一种标准</font>。
耦合度:模块与模块之间的关联程度。<br>关联的越密切,耦合越高;<br><font color="#c41230">关联的越松散,耦合越低。√</font>
接口相当于<font color="#c41230">特殊的抽象类</font>,定义方式、组成部分与抽象类类似。
接口的语法
定义
<b>定义</b>语法:<b><font color="#f15a23">interface 接口名 { }</font></b><br>
public <b><font color="#f15a23">interface</font></b> MyInterface {<br> <font color="#f15a23">public static final</font> String FIELD = "value";<br> String S = "str"; // <font color="#00a650">public static final 默认隐式存在、修饰</font><br> <font color="#f15a23">public abstract</font> void method( );<br> void m( ); // <font color="#00a650">public abstract 默认隐式存在、修饰</font><br>}<br>//<font color="#00a650">public 关键字仅限用于接口在于其</font><b style=""><font color="#924517">同名文件</font></b><font color="#00a650">中被定义</font>
定义要求:
没有构造方法,不能创建对象
只能定义:<font color="#c41230" style="font-weight: bold;">公开静态常量、公开抽象方法、</font><font color="#0076b3" style="font-weight: bold;">公开静态方法</font><font color="#662c90">(jdk1.8新特性-可有方法体,接口名直接调用)</font>
使用
<b>使用</b>语法:<b><font color="#f15a23">implements 接口名,接口名,...</font></b>
// <font color="#00a650">增加/赋予1种/多种能力(逗号分隔) [约定]</font><br><b> calss</b> Sub <b>extends</b> Super <b><font color="#f15a23">implements</font></b> <font color="#f15a23">接口名,接口名</font> {<br> @OverRide<br> <b>public</b> 返回值 <b>method</b>( ) { ... }<br> @OverRide<br> <b>public</b> void <b>m</b>( ) { ... }<br> }
使用规范:
任何类在实现接口时,<font color="#c41230">必须实现接口中所有抽象方法</font>,否则此类为抽象类
实现接口中的<font color="#c41230">抽象方法,访问修饰符必须是public</font>
对比抽象类
相同
1.可编译为字节码文件(.class)<br>2.不能创建对象(接口不是类,也没有构造方法)<br>3.可以作为引用类型<br>4.具备Object类中所定义的方法<br>
不同
1.所有属性都<font color="#c41230">只能且默认是公开静态常量</font>,隐式使用public static final修饰<br>2.所有方法都<font color="#c41230">只能且默认是公开抽象方法</font>,隐式使用public abstract修饰<br>3.没有构造方法、没有动态/静态代码块<br>
<font color="#c41230">接口引用【重要】</font>
同父类一样,接口也可声明为引用,并指向真实类对象。
【注意】
使用<font color="#c41230">接口引用作为方法形参</font>,实现更自然的<b>多态</b>(<font color="#c41230">只关注能力-具备能力的类对象均可传入</font>)
<font color="#c41230">仅可调用接口中所声明的方法</font>,不可调用实现类中独有的方法
可<font color="#c41230">强转回真实类本身类型</font>,进行独有方法调用(注意判断真实类对象 <b>instanceof</b>)
常见关系
类与类:单继承,extends 父类名称
类与接口:多实现,implements 接口名1,接口名2,接口名3
接口与接口:多继承,<b><font color="#f15a23">extends 父接口1,父接口2,父接口3</font></b>
常量接口
将多个常用于表示状态或者固定值的变量,以静态常量的形式定义在接口中同一管理,提高代码可读性。<br>
常量接口使用语法:<font color="#f15a23"><b>接口名.常量名</b></font>
常量接口示例代码
<font color="#c41230">接口回调【重要】</font>
思路顺序:<br>(1)接口/标准<br>(2)接口使用者<br>(3)接口实现者
重在理解、应用。
先有接口的使用者,后有接口的实现者。
对象数组排序
对象数组排序使用Java已知的<font color="#c41230">接口/标准</font><br>
intreface <b>Comparable </b>{ ... }
<font color="#c41230">接口使用者</font>,在工具类中成员方法传参形式调用(接口回调)
java.util.Arrays.<b><font color="#c41230">sort</font></b>(对象数组);
<font color="#c41230">接口实现者</font>,在实现类中编写对应覆盖方法逻辑(方法覆盖)
class 类名 implements <b><font color="#c41230">Comparable<类名></font></b> {<br> @Override<br> public int <b><font color="#c41230">compareTo(类名 o)</font></b> { /* 参考JDK文档 */ }<br>}
测试类 main( ) 中调用测试验证
常类方法
内部类
内部类
概念:在一个类的内部再定义一个完整的类。
语法:
<font color="#f15a23">class</font> Outer {<br> <font color="#f15a23">class</font> Inner {<br> } <br>}
编译:Outer$Inner.class 和 Outer.class
特点:<br>
* 编译之后可生成<font color="#c41230">独立的字节码文件</font><br>* 内部类可<font color="#c41230">直接访问外部类的私有成员</font>,而不破坏封装<br>* 可为外部类提供必要的内部功能组件
成员内部类
概念:<br>在<b>类的内部定义</b>,与实例变量、实例方法同级别的类。<br>属于外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象
语法:
// 定义语法同 <b>内部类<br></b><br>// 创建内部类对象<br>Outer out = <font color="#f15a23">new</font> Outer();<br>Inner in = out.<font color="#f15a23">new</font> Inner(); // 特殊:不具普适性<br><br>// 成员内部类访问外部类的重名属性<br>Outer<font color="#f15a23">.this.属性名</font>
特点:
* 当外部类、内部类存在<font color="#c41230">重名属性时,会优先访问内部类属性</font>。<br>* <font color="#c41230">成员内部类不能定义静态成员</font>
静态内部类
概念:不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员
语法:
<font color="#f15a23">static</font> 内部类 { }
特点:
* 只能<font color="#c41230">直接访问外部类的静态成员</font>(势力成员需实例化外部类对象)
局部内部类
概念:定义在<b>外部类的成员方法中</b>,作用范围和创建对象范围仅限于当前方法
语法:
<font color="#f15a23">class</font> Outer {<br> public void m( ) {<br> <font color="#f15a23">class</font> Inner {<br> }<br> }<br>}
特点:
* <font color="#c41230">不能有静态成员</font>(属性/方法)<br>* 局部内部类访问外部类当前方法中的局部变量时,<font color="#c41230">因无法保障变量的生命周期与自身相同</font>,变量必须修饰为<font color="#f15a23"><b>final</b></font><br>* 隐藏类的信息,<font color="#c41230">限制类的使用范围</font>
匿名内部类
概念:<b>没有类名的局部内部类</b>(一切特征都与局部内部类相同)
语法:
<font color="#f15a23">class</font> Outer {<br> public OutInterface m ( ) {<br> return <font color="#f15a23">new</font> OutInterface<b style="color: rgb(241, 90, 35);">( ) { </b><font color="#5c5c5c">// 匿名内部类</font><br> private int i = 0;<br> public int getValue() {<br> return i;<br> }<br> <font color="#f15a23"><b>};</b></font><br> }<br>}
特点:
* 必须<font color="#c41230">继承一个父类或者实现一个接口</font><br>* 定义类、实现类、创建对象的<font color="#c41230">语法合并</font>,只能创建一个该类的对象<br>* 使用场景:<font color="#c41230">① 显式继承父类时 ② 实现接口时</font><br>* 优点:可以减少代码量,书写的思路流畅<br>* 缺点:可读性较差
包装类
* 基本数据类型所对应的引用数据类型(<b><font color="#c41230">8种</font></b>)。<br>* Object可统一所有数据,包装类的默认值是null。<br>* 包装类中实际上就是持有了一个基本类型的数据,作为数据的存储空间(Byte中有一个byte的value属性),还提供了常用的转型方法,以及常量。既可以存储值,又具备了一系列功能。<br>* 包装类型中提供了若干转型的方法,可以让自身类型与其他包装类型、基本类型、字符串相互之间进行转换。
8种包装类:<b>Byte / Short / Integer / Long / Float / Double / Boolean / Character</b>
转型方法
① <b><font color="#f15a23">xxxValue( )</font></b><br>成员转型方法,java.lang.Number 父类为所有子类分别提供了6种对应类型互相转型的方法,将自身类型转换成其他数字型;
② <b><font color="#f15a23">parseXxxx(String s)</font></b><br>静态转型方法,服务7种包装类型(除了Character包装类型都可以通过String构建);
③ <b><font color="#f15a23">valueOf(基本类型)、valueOf(字符串类型)</font></b><br>静态转型方法,服务8种包装类型;
④ JDK5之后,赋值时提供<b><font color="#c41230">自动装箱、拆箱</font></b>:<br> Byte b4 = 40; // 【自动装箱】将基本类型直接赋值给包装类型,调用valueOf(short s)<br> byte b5 = b4; // 【自动拆箱】将包装类型引用赋值给基本类型(赋的是值),调用byteValue()返回基本类型
⑤ Java预先创建了256个常用的整数包装类型对象(-128~127的常数),在实际应用当中,对已创建的对象进行复用,节约内存效果明显。
【注意】使用字符串构建包装类型对象时,要保证类型的兼容,否则产生 <font color="#f384ae">NumberFormatException</font> 异常。
Object类
简介:超类、基类,所有类的直接或间接父类,位于继承树的最高层
特点:
* 任何类,如果没有书写extends显式继承某个类,都<font color="#c41230">默认继承Object类</font><br>* Object类中所定义的方法,是<font color="#c41230">所有对象都具备的方法</font><br>* Object类可以存储任何对象:<font color="#c41230">作为参数,可接收任何对象</font>;<font color="#c41230">作为返回值,可返回任何对象</font>。
方法:
getClass().getName()
返回引用中存储的实际对象类型。<br>应用:通常<font color="#c41230">用于判断两个引用中实际存储对象类型</font>是否一致。
toString()
返回该对象的字符串表示(表现形式)。<br>可以根据程序需求覆盖该方法,如展示对象各个属性值。<br>特点:<br>* 对象中属性的表现形式,常用于展示对象的各个属性。
hashCode()
返回该对象的十六进制的哈希码值(<font color="#c41230">对象在内存中的数字型名字</font>)。<br>哈希算法根据对象的地址或者字符串或者数字计算出来的int类型的数值。<br>哈希码并不唯一,可保证相同对象返回相同的哈希码,尽量保证不同对象返回不同的哈希码值。
equals()
默认实现为 this == obj, 比较两个地址是否相同。<br>特点:<br>* 可进行覆盖,比较两个对象的内容是否相同。
重写覆盖父类Object.equals()方法五步走
判断<font color="#c41230">引用地址</font>是否相同
判断引用地址是否为<font color="#c41230">空</font>
确认对象<font color="#c41230">类型是否一致</font>
转型 - 向下转型<font color="#c41230">拆箱</font>
<font color="#c41230">比较</font>对象中的实际内容
基本数据类型:==
字符串类型:str1.equals(str2)
finalize()
protected void finalize() throws Throwable { }
当对象被判定为辣鸡对象时,由JVM自动调用此方法,用以标记辣鸡对象,进入回收队列。<br>辣鸡对象:没有有效引用只想此对象时,为辣鸡对象。<br>垃圾回收:由GC销毁辣鸡对象,释放数据存储空间。<br>自动回收机制:JVM的内存耗尽,一次性回收所有辣鸡对象。<br>手动回收机制:使用<b><font color="#f15a23">System.gc( );</font></b>通知JVM触发垃圾回收。
<b><font color="#381e11">面试题:final finalize finally</font></b><br>* final 修饰词,类不可继承/方法不可覆盖/基本类型值不能修改/引用类型地址不可修改<br>* finalize 方法,JVM自动调用,标记辣鸡对象进入回收队列;手动调用,使用System.gc()方法触发<br>* finally 关键字,作为异常处理的一部分,它只能用在try/catch语句中,并且附带一个语句块,表示这段语句最终一定会被执行(不管有没有抛出异常),经常被用在需要释放资源的情况下。
wait(),wait(long),wait(long,int),notify(),notifyAll()
String类
特点
* 字符串是常量,创建后不可改变;<br>* 字符串字面值存储在字符串池中,可以共享;
创建
String s = "Hello"; // 产生<b><font color="#c41230">1</font></b>个对象,字符串池中存储(方法区常量池中字符串池)<br>String s = new String("Hello"); // 产生<b><font color="#c41230">2</font></b>个对象,堆、方法区常量池中各存储一个
方法
1.根据下标获取字符
s.charAt(0);
2.判断是否包含子字符串
s.contains("llo");
3.将字符串转换为数组
s.toCharArray();
4. 查找子字符串在字符串中第一次出现的位置,不存在返回-1
s.indexOf("o");
5. 查找子字符串在字符串中最后一次出现的索引,不存在返回-1
s.lastIndexOf("ld");
6. 判断字符串是否为空
str.isEmpty()
7. 返回字符串长度
s.length()
8. 去掉字符串前后空格
s2.trim()
9. 大小写转换 - 返回字符串副本,不会修改原字符串
hi.toUpperCase();
hi.toLowerCase();
10. 忽略大小写比较
upper.equals(lower) // 字符串完全一样返回true,否则false
upper.equalsIgnoreCase(lower)
11. 判断是否以某个字符串结尾
filename.endsWith(".java");
12. 替换字符串中的字符 - 返回字符串副本,不会修改源字符串
s.replace('o', 'O');
s.replace("Hello", "GoodBye");
13. 字符串分割,返回字符串数组
text.split(",");
14. 从指定下标位置到结尾,获取子字符串,通常嵌套使用
text.substring(8);
可变长字符串
StringBuilder
可变长字符串,JDK5.0提供,运行效率快、线程不安全。
StringBuffer
可变长字符串,JDK1.0提供,运行效率慢、线程安全。
BigDecimal类
位置:<b><font color="#f15a23">java.math</font></b>包中<br>作用:精确计算浮点数<br>创建:BigDecimal bd = new BigDecimal("1.0");
方法
BigDecimal add(BigDecimal db) //加<br>BigDecimal subtract(BigDecimal bd)//减<br>BigDecimal multiply(BigDecimal bd)//乘<br>BigDecimal divide(BigDecimal db) //除
【注意】
除法:BigDecimal(BigDecimal bd, int scal, RoundingMode mode)<br>@scal, 指定精确到的小数位数<br>@mode, 指定小数部分的取舍模式,通常采用四舍五入模式(BigDecimal.ROUND_HALF_UP)
集合框架
集合
概念:对象的容器,存储对象的对象,绝大多数情况下可替代数组。
特点:容器的工具类,定义了多个对象进行操作的常用方法。
位置:<b><font color="#f15a23">java.util.*</font></b>
泛型集合与工具类
泛型集合及用法
概念:参数化类型、类型安全的集合,<font color="#c41230"><b>强制集合元素的类型必须一致</b></font>。
特点<br>
1. <font color="#c41230">编译时即可检查</font>,而非运行时抛出异常;<br>2. 访问时,<font color="#c41230">不必类型转换</font>(拆箱);<br>3. 不同泛型之间引用不能相互赋值,<font color="#c41230">泛型不存在多态</font>。 <br>
高级
<T>
* <b><font color="#f15a23"><T></font></b> 代表某种通配类型,还有诸如<E><K,V>等<br>* <b><T extends Object></b> 约定类型T为Object的子类<br>* <b><T extends MyClass></b> 约定类型T只能为MyClass类的子类<br>* <b><font color="#f15a23"><T extends MyClass & MyInterFace></font></b> 约定类型T为MyClass子类同时实现了MyInterFace接口,<font color="#c41230">父类必须写在最前面</font>且可&上多个接口<br>* <b><T extends MyInterFace></b> 约定类型T只要实现了MyInterface接口<br>* <b><T extends MyInterFace<T>></b> 约定类型T要实现了MyInterface接口(且必须为T泛型的接口)
<?>
* <b><font color="#f15a23"><?></font></b> 代表任意通配泛型<br>* <b><? extends FatherClass></b> 泛型类型?必须是FatherClass的子类<br>* <b><? extends MyInterface></b> 泛型类型?必须是MyInterface的实现类<br>* <b><? super SubClass></b> 泛型类型?必须是SubClass类或SubClass的父类<br>* <b><? extends MyInterface<? extends T>></b> 泛型类型?必须是MyInterface的实现类,且接口又指定了泛型(必须T类型的子类)<br>* <b><font color="#f15a23"><T extends MyInterface<? super T>></font></b> 要求T所代表的类型必须实现MyInterface接口,同时,<font color="#c41230">接口泛型必须是T类型或T的父类</font><br>
普通泛型
* 类:创建对象时,为类所定义的泛型,进行参数化赋值<br> * 接口:实现接口时,为接口所定义的泛型,进行参数化赋值<br>
静态泛型
* 定义在<b><font color="#c41230">方法的返回值类型前</font></b>:<T>/<T extends Object>/<T extends Comparable<T>>/<T extends Comparable<? super T>>,<font color="#c41230">可使用&多接口</font><br> * 定义在<b><font color="#c41230">方法的形参列表当中</font></b>:<?>/<? extends Object>/<? super SubClass>,<font color="#c41230">不可使用&</font>
<font color="#f15a23">Collections</font>工具类
概念:集合工具类,定义了除了存储以外的集合常用方法。
方法
public static void <b><font color="#f15a23">sort</font></b>(List<?> list) // 排序,要求:必须实现Comparable接口,必须可与自身类型比,以及父类类型比<br>public static void <b><font color="#f15a23">reverse</font></b>(List<?> list) // 反转,倒置元素<br>public static void <b><font color="#f15a23">shuffle</font></b>(List<?> list) // 随机重置顺序(洗牌)
Collection体系集合
概念:代表该体系结构的根接口,代表一组对象,称为“集合”;每个对象都是该集合的“元素”
特点:代表一组任意类型的对象,无序、无下标。(Collection为父接口)
方法:参考jdk1.8-API文档
boolean <font color="#f15a23">add</font>(Object obj) // 添加一个对象<br>boolean <font color="#f15a23">addAll</font>(Collection c) // 将一个集合中的所有对象添加到此集合中<br>void <font color="#f15a23">clear</font>() // 清空此集合中的所有对象<br>boolean <font color="#f15a23">contains</font>(Object o) // 检查次集合中是否包含o对象<br>boolean <font color="#f15a23">equals</font>(Object o) // 比较此集合是否指定对象相等<br>boolean <font color="#f15a23">isEmpty</font>() // 判断此集合是否为空<br>boolean <font color="#f15a23">remove</font>(Object o) // 在此集合中移除o对象<br>int <font color="#f15a23">size</font>() // 返回此集合中的元素个数<br>Object[] <font color="#f15a23">toArray</font>() // 将此集合转换成数组
List接口与实现类
继承:父接口<b><font color="#c41230">Collection</font></b>
特点:有序、有下标、元素可重复
方法:继承了父接口<font color="#5c5c5c">Collection</font>提供的共性方法,同时定义了一些独有的与下标相关的操作方法
实现类
<b><font color="#f15a23">ArrayList</font></b>类(<b><font color="#00a650">数组</font></b>)【重点】
特点:<br> 1. 数组结构实现,<font color="#c41230">查询快、增删慢</font>;<br> 2. JDK1.2版本,<font color="#0076b3">运行效率快、线程不安全</font>;<br>
场景:注册(1次) -> 查询(n次)
注意:<br>* JDK7之前,无参构造方法实际创建长度为 <font color="#c41230" style="">10 </font>的Object数组,用还是不用,数组就在那里,爱用不用(占了内存)<br>* JDK8之后,无参构造方法实际创建长度为 <b><font color="#c41230">0 </font></b>的Object数组,首次add元素时,才执行数组扩容操作,然后真正向数组中插入数据(Lazy懒),用的时候创建或加载,有效降低无用内存的占用。
方法:参考jdk1.8-API文档
<b><font color="#f15a23">Vector</font></b>类(<b><font color="#00a650">数组、线程同步</font></b>)
特点:<br>1. 数组结构实现,<font color="#c41230">查询快、增删慢</font>;<br> 2. JDK1.0版本,<font color="#0076b3">运行效率慢、线程安全</font>。<br>
方法:参考jdk1.8-API文档
<b><font color="#f15a23">LinkedList</font></b>类(<b><font color="#00a650">链表</font></b>)
特点:<br> 1. 链表结构实现,<font color="#c41230">增删快,查询慢</font>;<br>
对比
ArrayList:必须开辟连续空间,查询快,增删慢。运行快,线程不安全。<br>Vector:必须开辟连续空间,查询快,增删慢。运行慢,线程安全。<br>LinkedList:无需开辟连续空间,查询慢,增删快。
Set接口与实现类
继承:父接口<b><font color="#c41230">Collection</font></b>
特点
1)<font color="#c41230">无序、无下标、元素不可重复</font>(当插入新元素时,如果新元素与已有元素进行equals比较,结果为true时,则<b><font color="#c41230">拒绝新元素插入</font></b>)<br>2)set接口并没有提供自己独有的方法,<font color="#5c5c5c">均是继承</font><b style=""><font color="#c41230">Collection</font></b><font color="#5c5c5c">的方法</font>
去重逻辑
<b><font color="#f15a23">hashCode( )</font></b>比较
不同:对象一定不同(<b><font color="#00a650">add成功</font></b>)
<b style=""><font color="#c41230">相同</font></b><font color="#5c5c5c">:对象不一定不同</font>
<font color="#f15a23" style=""><b>this==o</b></font>地址比较
true:对象一定相同(add失败)
<b><font color="#c41230">false</font></b>:<b><font color="#f15a23">equals( )</font></b>内容比较
true:内容相同(add失败)
<b><font color="#c41230">false:内容不同</font></b>(<b><font color="#00a650">add成功</font></b>)
实现类
<font color="#f15a23">HashSet</font>类(<font color="#00a650">HashCode-无序不重复</font>)【重点】
特点:<br>* <font color="#c41230">基于HashCode实现元素不重复</font> - <b><font color="#c41230">无序</font></b><br>* 当存入元素的哈希码相同时,会调用equals确认,结果为true,则拒绝后者加入<br>* 无参构建初始容量为16(负载因子0.75,即+75%容量扩容)<br>* 底层使用的HashMap类,即将所有需要存储的值,通过HashMap去重存入<br>* <font color="#c41230">先判断hashCode是否相同,再==比较地址是否相同,再equals内容是否相同</font><br>
<font color="#f15a23">LinkedHashSet</font>类(<font color="#00a650">记录插入顺序</font>)
特点:<br>* 继承自HashSet,又基于LinkedHashMap来实现的<br>* 底层使用LinkedHashMap(链表结构)存储,节点形式独立存储数据,<br> 并可以指向下一个节点,通过顺序访问节点,<font color="#c41230">可保留元素的插入顺序</font> - <b><font color="#c41230">插入顺序</font></b><br>* 所有方法与HashSet相同,用法也一模一样<br>
<font color="#f15a23">TreeSet</font>类(<font color="#00a650">二叉树-自动排序</font>)
特点:<br>* 基于<font color="#c41230">排列顺序实现元素不重复</font> - <b><font color="#c41230">自动排序</font></b><br>* 实现了SortedSet接口,对所有插入集合的元素自动排序<br>* 元素对象的类型必须实现Comparable接口,指定排序规则(Integer/String类默认实现),<br> 通过<font color="#c41230">重写CompareTo方法才能使用</font>,以确定是否为重复元素
排序
方式一:遍历加入到List中使用Collections.sort(list)排序;
方式二:使用TreeSet的构造创建一个TreeSet对象实现自动排序;
Map接口与实现类
特点
* 用于存储任意键值对(<b><font color="#f15a23">Key</font><font color="#000000">:</font><font color="#f15a23">Value</font></b>)<br>* 键:无序、无下标、不允许重复(唯一)<br>* 值:无序、无下标、允许重复
接口方法
* V put(K key, V value) // 将对象存入集合中,关联键值,<font color="#c41230">key重复则覆盖value</font><br>* Object get(Object key) // 根据键获取对应的值<br>* Set<K> // 返回所有key<br>* Collection<V> values() // 返回包含所有值的Collection集合<br>* Set<Map.Entry<K,V>> // 键值匹配的Set集合
子接口
<font color="#f15a23">SortedMap</font>接口
实现类
<font color="#f15a23">HashMap</font>类(<font color="#00a650">效率快+允许null</font>)重点
特点:<br>* JDK1.2版本,线程不安全,运行效率快;允许用null作为key或是value<br>* 无参构建初始容量为16(负载因子0.75,即+75%容量扩容)<br>* HashMap算法:拿到任何一个对象后,通过hash(key)做运算,key>>>16(除16),只可能得到0-15之间的一个数组,作为插入数组的下标。
<font color="#f15a23">LinkedHashMap</font>类(<font color="#00a650">记录插入顺序</font>)
特点:<font color="#c41230">HashMap的一个子类</font>,保存了记录的插入顺序,也可在构造时带参数,按照访问次序排序。
<font color="#f15a23">Hashtable</font>类(<font color="#00a650">线程安全</font>)
特点:JDK1.0版本,线程安全,运行效率慢;不允许null作为key或是value
<font color="#f15a23">Properties</font>类(<font color="#00a650">配置文件读取</font>)
特点:<font color="#c41230">Hashtable的子类</font>,要求key和value都是String,通常用于配置文件的读取。
Demo
<font color="#f15a23">TreeMap</font>类(<font color="#00a650">自动排序</font>)
特点:实现了SortedMap接口(Map的子接口),可以对key自动排序。
foreach循环
<font color="#f15a23" style="font-weight: bold;">for (数据类型 变量名 : 容器名称) {<br> </font><font color="#5c5c5c" style="">//可遍历集合或数组(常用在无序集合上)</font><br><font color="#f15a23" style="font-weight: bold;">}</font>
异常处理
异常的概念
概念:程序在运行过程中出现的特殊情况<br>必要性:任何程序都可能存在大量的位置问题、错误;如果不对这些问题进行正确处理,则可能导致程序的中断,造成不必要的损失。
异常的分类
位置:<font color="#f15a23">java.lang.<b>Throwable</b></font>;
Throwable类
Error类(<font color="#c41230">不可处理</font>)
Exception类
RuntimeException类
CheckedException类
<font color="#c41230">除了RuntimeException类与其子类,以及错误Error类,<b>其他的都是检查异常</b>。</font>
异常的产生
自动
当程序运行时遇到不符合规范的代码或结果时,会产生异常;
手动
<font color="#f15a23"><b>throw new 异常类型("实际参数");</b></font>
1.创建异常对象
2.结合throw关键字,抛出异常
用在<font color="#c41230">【<b>方法内</b>】</font>
异常的传递
概念:按照方法的调用链反向传递,如始终没有处理异常,最终会由JVM进行默认异常处理(打印堆栈跟踪信息)
* <b><font color="#c41230">受查异常</font></b>:<b><font color="#f15a23">throws</font></b> 声明对应的方法可能存在异常,声明<font color="#c41230">修饰在方法参数列表后端【<b>方法上</b>】,可以用"<b>,"</b>分隔指定声明多个异常</font><br>* <b><font color="#c41230">运行时异常</font></b>:因可处理可不处理,无需声明异常
异常的处理
<b><font color="#f15a23">try </font><font color="#000000">{</font></b><br> // 可能出现异常的代码<br><b>} <font color="#f15a23">catch</font> (Exception e) {</b><br> // 异常处理的相关代码(三种方案)<br> // <b>方案1</b>:自定义处理, 如println();<br> // <b>方案2</b>:打印堆栈跟踪信息, e.<font color="#f15a23">printStackTrace()</font>;<br> // <b>方案3</b>:获取异常的原因信息, println(e.<font color="#f15a23">getMessage()</font>);<br>[... <font color="#f15a23">多重 catch</font> () ...] // 遵循从子到父的顺序,<font color="#c41230">父类异常在最后</font>。<br><b>} <font color="#f15a23">finally</font> {</b><br> // 无论是否出现异常都会执行的代码结构(<font color="#c41230">不受return影响</font>),常用于释放资源<br><b>}</b>
try-catch<br>try-catch-catch<br>try-catch-finally<br>try-catch-catch-...-finally<br>try-finally(不常见)
自定义异常<br>
定义
必须<b><font color="#c41230">继承</font></b>自Exception或Exception的子类,常用RuntimeException
必须提供<b><font color="#c41230">无参构造</font></b>方法;
必须提供String message的<b><font color="#c41230">1参构造</font></b>方法,super(message);
抛出
Exception受查异常
声明:①需要<font color="#c41230" style="">声明</font>该异常,传递出去; ②声明的异常类型与抛出的<font color="#c41230" style="">异常类型一致</font>
抛出:throw new 自定义异常类名(异常提示字符串);
RuntimeException运行时异常
声明:可声明/可不声明
抛出:throw new 自定义异常类名(异常提示字符串);<br>
打印突出显示的错误信息(serr)
System.<i><b><font color="#0076b3">err</font></b></i>.println(e.getMessage());
异常方法覆盖
* 0. 方法名、参数列表、返回值类型必须和父类相同(<font color="#c41230">覆盖的基本要求</font>)<br>* 1. 父类中方法<font color="#c41230">没有声明异常</font>,则子类中也<font color="#c41230">不可以声明异常</font><br>* 2. 父类中方法<font color="#c41230">声明了异常</font>,子类重写后<font color="#c41230">可声明也可不声明,如果声明则必须是与其相同或其异常子类</font><br>* 3. 子类可以声明比父类<font color="#c41230">更多</font>的异常,但必须<font color="#c41230">小于</font>父类的异常类(即异常子类) - 即<font color="#c41230"><b>子类不能抛出比父类更多、更宽的异常</b></font>
多线程
线程概念
<b>进程</b>:程序静止的,真正运行时的程序,才被称为进程。(<font color="#c41230"><b>宏观并行,微观串行</b></font>)<br><b>线程</b>:轻量级进程(Light Weight Process),<font color="#c41230">程序中的一个顺序控制流程</font>,同时也是<font color="#c41230">CPU的基本调度单位</font>,<br>进程由1个或多个线程组成,彼此间完成不同的工作,交替执行,称为多线程。
eg
迅雷,是一个进程,当中的多个不同的下载任务即多个线程。<br>JVM,<font color="#c41230">Java虚拟机是一个进程(<b>单进程</b>)</font>,当中默认包含主线程(main),可通过代码创建多个独立线程,与main并发执行。
扩展
获取win电脑当前CPU核心数命令:<br>① win+R ② <b><font color="#f15a23">wmic </font></b> ③ <b><font color="#f15a23">cpu get NumberOfCores</font></b>
线程组成
① CPU时间片
操作系统会为每个线程分配执行时间
② 运行数据
* <b>堆</b>空间:存储线程需使用的对象,多个线程可以<font color="#c41230">共享堆中的对象</font>;<br>* <b>栈</b>空间:存储线程需使用的局部变量,<font color="#c41230">每个线程都拥有独立的栈</font>;
③ 线程逻辑代码
线程创建
继承父类
步骤
<font color="#c41230">① 继承</font><b style=""><font color="#f15a23">Thread</font></b><font color="#c41230">类</font><br><font color="#c41230">② 覆盖run()方法</font><br><font color="#c41230">③ 创建子类对象</font><br><font color="#c41230">④ 调用start()方法 - 启动线程</font>
示例
MyThread t1 = new MyThread();<br>t1.start();
实现接口【推荐】
步骤
<font color="#c41230">① 实现</font><b style=""><font color="#f15a23">Runnable</font></b><font color="#c41230">接口</font><br><font color="#c41230">② 覆盖run()方法</font><br><font color="#c41230">③ 创建实现类对象</font><br><font color="#c41230">④ 创建线程对象(Thread父类有参构造)</font><br><font color="#c41230">⑤ 调用start()方法 - 启动线程</font>
示例
Thread t2 = new Thread(new MyRunnable());<br>t1.start();
特点
* 只是将当前类变成线程任务类,<font color="#c41230">本身不是个线程</font><br>* run任务是可以多线程对象共享(<font color="#c41230">任务复用</font>)<br>* <b><font color="#c41230">更灵活</font></b>(<font color="#c41230">还可以继承其他的类 + 实现其他的接口能力</font>)
<b>并发计算</b>
<b><font color="#f15a23">Callable</font>接口</b>
public <b>interface</b> Callable<b><<font color="#f15a23">V</font>></b> {<br> public <b><font color="#f15a23">V</font></b> <b><font color="#f15a23">call</font></b>() <b><font color="#f15a23">throws Exception</font></b>;<br>}<br>
* JDK5加入,与Runnable接口类似,实现之后代表一个线程任务;<br>* Callable<b><font color="#c41230">具有泛型返回值</font></b>,<b><font color="#c41230">可以声明异常</font></b>。
<b><font color="#f15a23">Future</font>接口</b>
public <b>interface</b> Future<b><V></b><br>
* 异步接收ExecutorService.submit()所返回的状态结果,当中包含了call()的返回值;<br>* 成员方法:<br> <font color="#f15a23"><b>V</b> <b>get</b>()</font>以阻塞形式等待Future中的异步处理结果(<font color="#c41230">call()的返回值</font>), 该方法会抛出<b><font color="#662c90">InterruptedException</font></b>, <b><font color="#662c90">ExecutionException</font></b>异常<br>
线程状态(6)
<b>初始New → 运行RUNNABLE → 等待WAITING(限期/无限期) → 阻塞BLOCKED → 终止TERMINATED</b>
* JDK5之后,READY+RUNNING = RUNNABLE(运行态)
<b>所有线程状态图示</b>
线程方法
基本
Thread.currentThread().getId() // 返回当前线程标识符(线程ID)
Thread.currentThread().getName() // 返回当前线程对象名(线程名)
休眠
public <b>static</b> void <b><font color="#f15a23">sleep</font></b>(long millis)<br>// 当前线程主动休眠millis毫秒<br>
特点
* <b>静态方法</b>,直接类名调用Thread.sleep(1000);<br>* 使当前线程进入阻塞状态,在指定时间内不会执行,不推荐使用;<br>* sleep()被调用时该线程<font color="#c41230">不会释放它所拥有的锁</font>;<br>* 该方法会抛出<b style=""><font color="#662c90">InterruptedException</font></b>中断异常;
放弃
public <b>static</b> void <b><font color="#f15a23">yield</font></b>( )<br>// 当前线程主动放弃时间片,回到就绪状态,竞争下一次时间片
特点
* <b>静态方法</b>,直接类名调用Thread.yield();<br>* yield只是使当前线程重新回到就绪状态,所以执行yield的线程有可能在进入到就绪状态后马上又被执行。<br> <font color="#c41230">yield只能使同优先级或更高优先级的线程有执行的机会</font>。<br>* 可能对调试或测试有用,可能有助于根据竞态条件重现错误。 <br> 在设计并发控制结构(例如java.util.concurrent.locks包中的并行控制结构)时也可能有用。
结合
public <b>final</b> void <b><font color="#f15a23">join</font></b>( )<br>// 允许其他的线程加入到当前线程中来(<font color="#c41230">插队</font>),等待join的线程终止
特点
* 成员方法/最终方法,不能被覆盖;<br>* 如果某个线程在另一个线程t上调用t.join(),<font color="#c41230">此线程将被挂起,直到目标线程t结束才恢复</font>;<br>* <font color="#c41230">能够释放当前线程锁</font>,其他线程可以调用次线程中的同步方法;<br>* 该方法会抛出<b style=""><font color="#662c90">InterruptedException</font></b>中断异常;
线程同步
线程为什么不安全?
当多线程并发访问临界资源时,如果破坏原子操作,可能会造成数据不一致;<br>* 临界资源:共享资源(同一对象),一次仅允许一个线程使用,才可以保证正确性;<br>* 原子操作:不可分割的多步操作,被视作一个整体,其顺序和步骤不可打乱或缺省;
同步方式
方式:同步代码块
<b><font color="#f15a23">synchronized</font></b> <font color="#f15a23">(临界资源对象) {</font> // <font color="#c41230"><b>对临界资源加锁</b></font><br> //代码(原子操作)<br><font color="#f15a23">}</font>
注意
* <font color="#c41230">每个对象都有一个互斥锁标记</font>,用来分配给线程的;<br>* 只有拥有对象互斥锁标记的线程,才能进入对该对象加锁的同步代码块;<br>* 线程退出同步代码块时,会释放相应的互斥锁标记;
方式:同步方法
<font color="#f15a23"><b>synchronized</b> 返回值类型 方法名称(形参列表) { </font>// <b><font color="#c41230">对当前对象(this)加锁</font></b><br> // 代码(原子操作)<br><font color="#f15a23">}</font><br>
注意
* 只有拥有对象互斥锁标记(eg:Object lock;)的线程,才能进入该对象加锁的同步方法中;<br>* 线程退出同步方法时,会释放相应的互斥锁标记。
同步规则
只有在调用包含同步代码块的方法,或者同步方法时,才需要对象的锁标记
如果在调用不包含同步代码块的方法,或普通方法时,则不需要锁标记,可直接调用
已知线程安全的类
① StringBuilder<br>② Vector<br>③ Hashtable
公开成员方法均为synchronized修饰的同步方法。
线程通信
阻塞/等待
Object类的成员方法:<br>public final void <b><font color="#f15a23">wait</font></b>()<br>public final void <b><font color="#f15a23">wait</font></b>(long timeout)
说明:必须在对共享临界资源(obj)加锁的<font color="#c41230">同步代码块/同步方法</font><font color="#5c5c5c">中</font>。<br>在一个线程中调用obj.wait()时,此线程会<font color="#c41230">释放其拥有的所有锁标记</font>,同时此线程<font color="#c41230">阻塞</font>在obj的等待队列中。<br>即当前线程释放锁,进入等待队列(<b><font color="#c41230">无限期等待 - 除非收到通知</font></b>)。
通知/唤醒
Object类的成员方法:<br>public final void <b><font color="#f15a23">notify</font></b>()<br>public final void <b><font color="#f15a23">notifyAll</font></b>()
说明:必须在对共享临界资源(obj)加锁的<font color="#c41230">同步代码块/同步方法</font>中。<br>从obj的waiting中释放一个或全部线程,对自身没有任何影响。
经典问题
死锁
* 当第一个线程拥有A对象锁标记,并等待B对象锁标记,同时第二个线程拥有B对象锁标记,并等待A对象锁标记,产生死锁。<br>* 一个线程可以同时拥有多个对象的锁标记,当线程阻塞时,不会释放已经拥有的锁标记,由此可能造成死锁。
生产者与消费者
若干个生产者在生产产品,这些产品将提供给若干个消费者去消费。<br>为了使生产者和消费者能并发执行,在两者之间设置一个能存储多个产品的缓冲区:<br><font color="#c41230">生产者将生产的产品放入缓冲区,消费者从缓冲区中取走产品进行消费</font>。<br>显然生产者和消费者之间必须保持同步,<br>即<font color="#c41230">不允许消费者到一个空的缓冲区中取产品,也不允许生产者向一个满的缓冲区中放入产品</font>。
线程池
概念
问题:<br>* 线程是宝贵的内存资源、单个线程约占1MB的空间,过多分配易造成内存溢出;<br>* 频繁的创建及销毁会增加虚拟机回收频率、资源开销,造成程序性能下降。
线程池:<br>* 线程容器,可<font color="#c41230">设定线程分配的数量上限</font>;<br>* 将预先创建的线程对象存入池中,并<font color="#c41230">重用线程池中的线程对象</font>;<br>* <font color="#c41230">避免频繁的创建和销毁</font>。
原理
将任务提交给线程池,由线程池分配线程、运行任务,并在当前任务结束后复用线程。
<b>线程池</b>(接口/类)
位置:<font color="#f15a23">java.util.<b>concurrent</b></font>;
<b><font color="#f15a23">Executor</font><font color="#5c5c5c">接口</font></b>
接口,线程池的<font color="#c41230">顶级接口</font>
<b><font color="#f15a23">ExecutorService</font><font color="#5c5c5c">接口</font></b>
Executor的子接口,线程池接口
public <b>interface</b> ExecutorService<br> <b>extends</b> Executor
<font color="#f15a23">Future<?> <b>submit</b>(Runnable task)</font><br>// 该成员方法用于提交任务代码进而自动由线程池创建线程并运行
<b><font color="#f15a23">Executors</font><font color="#5c5c5c">类</font></b>
工厂/工具类,<b><font color="#c41230">通过此类可以获得一个线程池</font></b>
① 通过 <font color="#f15a23">Executors.<b>newFixedThreadPool</b>(int nThreads)</font> 获取<font color="#c41230">固定数量</font>的线程池<br> @return ExecutorService 接口类型引用<br>
② 通过 <font color="#f15a23">Executors.<b>newCachedThreadPool</b>()</font>获得动态数量的线程池,如不够则创建新的,<font color="#c41230">没有上限</font><br> @return ExecutorService 接口类型引用<br>
<b>互斥锁</b>(接口/类)
位置:<font color="#f15a23">java.util.<b>concurrent.locks</b></font>;
<b><font color="#f15a23">Lock</font>接口</b>
public interface <b><font color="#f15a23">Lock</font></b> {}
特点:<br>* 提供更多实用性方法,功能更强大、性能更优越。<br>
方法:<br>① void <font color="#f15a23">lock</font>() // 获取锁,如锁被占用,则等待<br>② boolean <font color="#f15a23">trylock</font>() // 尝试获取锁(成功true,失败false,不阻塞)<br>③ void <font color="#f15a23">unlock</font>() // 释放锁 <br>
<b><font color="#f15a23">ReentrantLock</font>类(<font color="#00a650">重入锁/递归锁</font>)</b>
public class <b><font color="#f15a23">ReentrantLock</font></b> extends <b>Object</b> implements <b>Lock, Serializable</b>
特点:<br>* Lock接口的实现类,与synchronized一样具有互斥锁功能。<br>注意:<br>1)使用Lock,需要<font color="#c41230">显式的获取锁和释放锁</font>;<br>2)为了避免拿到锁的线程在运行期间出现异常,导致程序终止没有释放锁!应用<font color="#c41230">try-finally来保证无论是否出现异常,最终必须释放锁</font>;<br>3)ReentrantLock为重入锁,<font color="#c41230">避免递归,如果必须递归,必须正确控制退出条件</font>。<br>(此锁支持同一线程的2147483647个递归锁的最大值。试图在Error超过这个限制的结果将从锁定的方法。)<br>
使用:①创建重入锁对象;②显式开启锁;③显式释放锁;④释放锁必须放在finally代码块中
<b><font color="#f15a23">ReentrantReadWriteLock</font>类(<font color="#00a650">读写锁</font>)</b>
public class <b><font color="#f15a23">ReentrantReadWriteLock</font></b> extends <b>Object</b> implements <b><font color="#c41230">ReadWriteLock</font>, Serializable</b>
特点:<br>* 一种支持<font color="#c41230">一写多读的同步锁</font>,读写分离,可分别分配读锁、写锁;<br>* 支持多次分配读锁,使<font color="#c41230">多个读操作可以并发执行</font>(<font color="#c41230">写锁同步,读锁异步</font>)。<br>
互斥规则:<br>① 写-写:互斥,阻塞;-- 独占<br>② 读-写:互斥,读阻塞写、写阻塞读;<br>③ 读-读:不互斥、不阻塞;<br>* 在读操作远远高于写操作的环境下,可在保证线程安全的情况下,极大提高运行效率。
<b>线程安全</b>(方法/类)
方法
位置:<font color="#f15a23">java.util.<b>Collections</b></font>;
public static <T> Collection<T> <font color="#f15a23">synchronizedCollection</font>(Collection<T> c)<br>public static <T> List<T> <font color="#f15a23">synchronizedList</font>(List<T> list)<br>public static <T> Set<T> <font color="#f15a23">synchronizedSet</font>(Set<T> s)<br>public static <K,V> Map<K,V> <font color="#f15a23">synchronizedMap</font>(Map<K,V> m)<br>public static <T> SortedSet<T> <font color="#f15a23">synchronizedSortSet</font>(SortedSet<T> s)<br>public static <K,V> SortedMap<K,V> <font color="#f15a23">synchronizedSortedMap</font>(SortedMap<K,V> m)
特点:<br>* 都是<font color="#c41230">返回对应泛型集合</font>类型的方法;<br>* 都是<font color="#c41230">静态方法</font>,通过Collections直接调用;<br>* 都是在静态方法中new了一个synchronized<font color="#c41230">同步的静态内部类</font>;<br>* 实际使用时的成员方法与原集合没有区别;<br>* JDK1.2提供,接口统一、维护性高,但性能没有提升,均以synchonized实现。
类
位置:<font color="#f15a23">java.util.<b>concurrent</b></font>;
<b><font color="#f15a23">CopyOnWriteArrayList</font>类(<font color="#00a650">线程安全的List</font>)</b>
public class <b><font color="#f15a23">CopyOnWriteArrayList</font></b><E><br>extends <b>Object</b><br>implements <b>List<E>, RandomAccess, Cloneable, Serializable</b>
特点:<br>* 符合List特点:有序、有下标、元素可重复<br>* <font color="#5c5c5c">线程安全的ArrayList,</font><font color="#c41230">加强版读写分离</font>;<br>* <font color="#c41230">写有锁,读无锁</font>,读写之间不阻塞,优于读写锁;<br>* <font color="#c41230">写入时,先copy一个容器副本、再添加新元素,最后替换引用</font>;<br>* 使用方式与ArrayList无异。<br>
List<String> alist = new CopyOnWriteArrayList<String>();
<b><font color="#f15a23">CopyOnWriteArraySet</font>类(<font color="#00a650">线程安全的Set</font>)</b>
public class <b><font color="#f15a23">CopyOnWriteArraySet</font></b><E><br>extends <b>AbstractSet<E></b><br>implements <b>Serializable</b>
说明:<br>* 符合Set特点:无序、无下标、元素不重复<br>* 线程安全的Set,底层使用CopyOnWriteArrayList实现;<br>* 唯一不同在于:<font color="#c41230">使用addIfAbsent()添加元素(查重),会遍历数组</font>;<br>* 如存在元素,则不添加(扔掉副本)。
Set<String> aset = new CopyOnWriteArraySet<String>();
<b><font color="#f15a23">ConcurrentHashMap</font>类(<font color="#00a650">线程安全的Map</font>)</b>
public class <b><font color="#f15a23">ConcurrentHashMap<K,V></font></b><br>extends <b>AbstractMap<K,V></b><br>implements <b>ConcurrentMap<K,V>, Serializable</b>
特点:<br>* 初识容量默认为16段(Segment),使用<font color="#c41230">分段锁设计</font>;<br>* 不对整个Map加锁,而是<font color="#c41230">为每个Segment加锁(16把锁)</font>;<br>* 当多个对象存入同一个Segment时,才需要互斥;<br>* 最理想状态位16个对象分别存入16个Segment,并行线程数量16个;<br>* 使用方式与HashMap无异。<br>// <font color="#c41230">JDK<b>1.7</b>: 分段锁设计 Segment</font><br>// <font color="#c41230">JDK<b>1.8</b>: CAS交换算法(CAS比较和交换) + 同步锁(锁的是表头)</font>
Map<String, Integer> chmap = new ConcurrentHashMap<String, Integer>();
<b>队列</b>(FIFO)
位置:<font color="#f15a23">java.util.<b>Queue</b></font>;
<b><font color="#f15a23">Queue</font>接口</b>
public interface <font color="#f15a23">Queue</font><E> extends <b>Collection</b><E>
* Collection的子接口,表示队列<font color="#c41230"><b>FIFO</b></font>(First In First Out)
常用方法:<br>(1)抛出异常<br>boolean add(E e) // 顺序添加1个元素(到达上限后,再添加则会抛出异常)<br>E remove() // 获得第1个元素并移除(如果队列没有元素时,则抛异常)<br>E element() // 获得第1个元素但不移除(如果队列没有元素时,则抛异常)<br>(2)返回特殊值【<b><font color="#c41230">推荐使用</font></b>】<br>boolean <font color="#f15a23">offer</font>(E e) // 顺序添加1个元素(到达上限后,再添加则会返回false)<br>E <font color="#f15a23">poll</font>() // 获得第1个元素并移除(如果队列没有元素时,则返回null)<br>E <font color="#f15a23">keep</font>() // 获得第一个元素但不移除(如果队列没有元素时,则返回null)
<b><font color="#f15a23">ConcurrentLinkedQueue</font>(<font color="#00a650">线程安全的队列Queue</font>)</b>
public class <b><font color="#f15a23">ConcurrentLinkedQueue</font></b><E> extends <b>AbstractQueue</b><E> implements <b>Queue<E>, Serializable</b>
说明:<br>* <font color="#c41230">线程安全</font>、可高效读写的队列,<font color="#c41230">高并发下性能最好的队列</font>;<br>* <font color="#c41230">无锁</font>、<font color="#c41230">CAS比较交换算法</font>,修改的方法包含3个核心参数(V,E,N);<br>* V:要更新的变量、E:预期值、N:新值<br>* 只有当V==E时,V=N;否则表示已被更新过,则取消当前操作。
<b><font color="#f15a23">BlockingQueue</font>接口(<font color="#00a650">阻塞队列</font>)</b>
public interface <b><font color="#f15a23">BlockingQueue</font></b><E> extends <b>Queue</b><E><br>
常用方法:<br>void <font color="#f15a23">put</font>(E e) // 将指定元素插入此队列中,如果没有可用空间,则死等<br>E <font color="#f15a23">take</font>() // 获取并移除此队列头部元素,如果没有可用元素,则死等<br>说明:<br>* Queue的子接口,<font color="#c41230">阻塞的队列</font>,增加了两个线程状态为<font color="#c41230">无限期等待</font>的方法<br>* <font color="#c41230">可用于解决生产者、消费者问题</font>
<b><font color="#f15a23">ArrayBlockingQueue</font>类(<font color="#00a650">有界阻塞队列</font>)</b>
* 数组结构实现,有界队列。手工固定上限
BlockingQueue<String> abq = new ArrayBlockingQueue<String>(3);
<b><font color="#f15a23">LinkedBlockingQueue</font>类(<font color="#00a650">无界阻塞队列</font>)</b>
* 链表结构实现,无界队列。默认上限Integer.MAX_VALUE
BlockingQueue<String> lbq = new LinkedBlockingQueue<String>();
CAS比较交换算法
比较与交换(compare and swap),是一种无锁算法,即不使用锁的情况下实现多线程之间的变量同步。<br>也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫<font color="#c41230">非阻塞同步</font>(Non-blocking Synchronization)。<br><br>CAS算法涉及到三个操作数:<br>需要读写的内存变量<b>V</b>、<br>进行比较的值(预期值)<b>E</b>、<br>拟写入的新值<b>N</b>。<br><font color="#c41230">当且仅当V的值等于E时,CAS通过原子方式用新值N来更新V值,否则不会执行任何操作</font>(比较和替换是一个原子操作)。<br>一般情况下是一个自旋转操作,即不断的重试。<br>
IO框架
<b>字节流&字符流汇总图</b>
流的概念
内存与存储设备之间传输数据的通道。
流的分类
按<b>方向</b>:【重点】相对于程序操作的内存,<font color="#c41230"><b>进入内存为输入,从内存出去为输出。</b></font><br>① 输入流:将[存储设备]中的内容输入到[内存]中;<br>② 输出流:将[内存]中的内容输出到[存储设备]中。
按<b>单位</b>:<br>① 字节流:以字节为单位,可以读写所有数据;<br>② 字符流:以字符为单位,只能读写文本数据。
按<b>功能</b>:<br>① 节点流:具有实际传输数据的读写功能;<br>② 过滤流:在节点流的基础之上增强功能。
字<font color="#c41230">节</font>流
抽象父类
<b><font color="#f15a23">InputStream</font></b> 字节输入流
<b><font color="#f15a23">OutputStream</font></b> 字节输出流
<b><font color="#f15a23">InputStream</font></b> 字节输入流
子类:字节节点流<br>
<b><font color="#f15a23">FileInputStream</font></b> 类
<b><font color="#f15a23">FileOutputStream</font></b> 类
子类:字节过滤流(缓冲流)
<b><font color="#f15a23">BufferedInputStream</font></b> 类
<b><font color="#f15a23">BufferedOutputStream</font></b> 类
子类:字节过滤流(对象流)
<b><font color="#f15a23">ObjectInputStream</font></b> 类
<b><font color="#f15a23">ObjectOutputStream</font></b> 类
* 增强了缓冲区功能<br>* 增强了读写8种基本数据类型和字符串功能<br>* 增强了读写对象的功能:<br> 1) Object <font color="#f15a23">readObject</font>() // 从流中读取一个对象<br> 2) void <font color="#f15a23">writeObject</font>(Object obj) // 向流中写入一个对象
<b>对象序列化</b>:<br>使用流传输对象的过程称为序列化、反序列化。<br>1)必须实现 <b><font color="#000000">Serializable</font><font color="#c41230"> </font></b>接口;<br>2)对象自身和类中属性都<font color="#c41230">必须序列化</font><br> (即实现Serializable这个空接口即可,基本数据类型数组可不序列化,引用数据类型必须序列化);<br>3)<b><font color="#f15a23">transient</font></b> 关键字修饰为临时属性,不参与序列化;<br>4)对象的默认序列化机制写入对象的类、类签名和所有非瞬态和非静态字段的值,<br> 因此<font color="#c41230">属性不能使用static修饰</font>,否则取的都是最后一次的值(static属于类本身,会影响序列化)。<br>5)序列化对象流读取到文件尾,会抛出 <b><font color="#662c90">EOFException</font></b> 异常 - <font color="#c41230">捕获后停止读取文件</font>。
字<font color="#c41230">符</font>流
抽象父类
<b><font color="#f15a23">Reader</font></b> 字符输入类
<b><font color="#f15a23">Writer</font></b> 字符输出类
子类:字符过滤流
<b><font color="#f15a23">BufferedReader</font></b> 字符输入过滤流
BufferedWriter 字符输出过滤流
<b><font color="#f15a23">PrintWriter </font></b>字符输出过滤流(写入后换行)【常用】
子类:桥转换流
<b><font color="#f15a23">InputStreamReader</font></b> 桥转换输入流
<b><font color="#f15a23">OutputStreamWriter</font></b> 桥转换输出流
* 可将字节流转换为字符流;(为的就是可以设置字符编码方式)<br>* 可<b><font color="#c41230">指定字符的编码方式</font></b>;
步骤
字节流转换字符流步骤:<br>①创建字节流 Output/InputStream<br>②创建过滤流,设置字符编码集(按需) OutputStreamWriter/InputStreamReader<br>③封装过滤流 PrintWriter/BufferedReader<br>④读写数据 write/read<br>⑤关闭流 close
<b><font color="#c41230">一行套娃</font></b>:<br>PrintWriter pw1 = <b>new</b> PrintWriter(<b>new</b> OutputStreamWriter(<b>new</b> FileOutputStream("files\\convert.txt"), "UTF-8"));<br>BufferedReader br1 = <b>new</b> BufferedReader(<b>new</b> InputStreamReader(<b>new</b> FileInputStream("files\\convert.txt"), "UTF-8"));<br>
子类:字符节点输入输出流
<b><font color="#f15a23">FileReader</font></b> 字符节点输入流
<b><font color="#f15a23">FileWriter</font></b> 字符节点输出流
文件操作
<font color="#f15a23">File </font>类
* 文件和目录路径名的抽象表示形式。<br>* 没有无参构造。<br>* 具体方法都很常用,查询jdk1.8 API文档。
<b><font color="#f15a23">FileFilter</font> 接口</b>
* 当调用File类中的listFiles()方法时,支持传入FileFilter接口的实现类对象,<br> 对获取文件进行过滤,只有满足条件的文件才可出现在listFiles()的返回值中。——接口回调
<font color="#c41230">简单FTP下载功能核心IO逻辑</font>
Server Demo
Client Demo
网络编程
TCP/IP四层模型<br>
应用层
应用层
表示层
会话层
传输层
传输层
网络层
网络层
网络接口层
数据链路层
物理层
IP协议
回环地址 127.0.0.1,指本机,一般用于测试。
查看IP命令:ipconfig
测试IP命令:ping D.D.D.D
Port
程序的唯一标识。
端口分类
公认端口 0-1023
注册端口 1024-49151
动态或私有端口 49152-65535
常用端口
MySql:3306
Oracle:1521
Tomcat:8080
SMTP:25
Web服务器:80
FTP服务器:21
类
<b>InetAddress</b>
标识花联网协议(IP)地址对象,封装了与该IP地址对象相关的所有信息,并提供常用方法
无法直接创建对象,<font color="#c41230">构造方法私有化</font>,需要通过getxxx方法获得
<b>Inet4Address</b>
<b>Inet6Address</b>
<b>Socket</b>
创建客户端的类
<b>ServerSocket</b>
创建服务器的类
开发步骤
① 建立通信连接(会话)<br>* 创建ServerSocket,指定端口号;<br>* 调用accept等待客户端接入;<br>② 客户端请求服务器<br>* 创建Socket,指定服务器IP + 端口号;<br>* 使用字节输出流,发送请求数据给服务器;<br>* 使用字节输入流,接收响应数据到客户端(等待);<br>③ 服务器响应客户端<br>* 使用字节输入流,接收请求数据到服务器(等待);<br>* 使用字节输出流,发送响应数据到客户端。
反射-设计模式
概念:程序运行时动态获取信息以及动态调用对象方法的功能为Java语言的反射机制。
类
<b><font color="#f15a23">Class</font>类</b>
String <font color="#f15a23">getName</font>() 返回由 类对象表示的实体(类,接口,数组类,原始类型或空白)的名称,作为 String 。<br>static Class<?> <font color="#f15a23">forName</font>(String className) 获取类对象名<br>Package <font color="#f15a23">getPackage</font>() 获取类对象的包名<br>Class<? super T> <font color="#f15a23">getSuperclass</font>() 获取父类的类对象名<br>Class<?>[] <font color="#f15a23">getInterfaces</font>() 获取接口的类对象名<br>Constructor<?>[] <font color="#f15a23">getConstructors</font>() 获取构造方法<br>Class<?>[] <font color="#f15a23">getParameterTypes</font>() 获取方法(构造/成员)的参数类型列表<br>Field[] <font color="#f15a23">getFields</font>() 获取属性(自身+父类的所有public公开属性)<br>Field[] <font color="#f15a23">getDeclaredFields</font>() 获取属性(自身所有的属性)<br>Method[] <font color="#f15a23">getMethods</font>() 获取方法(自身+父类单继承叠加的所有public公开方法)<br>Method[] <font color="#f15a23">getDeclaredMethods</font>() 获取方法(自身所有的方法)<br><b>T <font color="#f15a23">newInstance</font>()</b> 创建由此类对象表示的类的新实例(此类对象必须有无参构造)
Field类
Method类
public Method <font color="#f15a23">getDeclaredMethod</font>(String name, Class<?>... parameterTypes)<br>返回单个指定方法名称和参数类型列表的方法(私有方法也可获取)<br>Object <font color="#f15a23">invoke</font>(Object obj, Object... args)<br>调用底层的方法,这方法需要类的对象、实参列表。
Constructor类
获取 Class 对象并创建实例对象
类全名:<font color="#f15a23">Class.<i>forName</i></font>("全限定名");
编译期:<font color="#f15a23">类名.class</font>;
运行时:<font color="#f15a23">对象名.getClass( )</font>;
创建类的实例对象:T <font color="#f15a23">newInstance</font>( );
操作 <b>构造方法</b> 对象
Class<?> clazz = Class.forName("com.demo.reflect.User");<br>// 获取无参构造,创建对象<br>Constructor<?> c1 = clazz.<font color="#f15a23">getConstructor</font>();<br>User u1 = (User) c1.newInstance();<br>// 获取有参构造,创建对象<br> Constructor<?> c2 = clazz.<font color="#f15a23">getConstructor</font>(<b>Integer.class</b>, <b>String.class</b>);<br>User u2 = (User) c2.newInstance(1, "小叮当");<br>// 获取私有构造,创建对象<br>Constructor<?> c3 = clazz.<font color="#f15a23">getDeclaredConstructor</font>(String.class);<br>c3.<font color="#c41230"><b>setAccessible</b></font>(true); // 忽略访问修饰检查(突破封装)<br>User u3 = (User) c3.newInstance("小白");<br>
操作 <b>成员变量</b> 对象
Class<?> clazz = Class.forName("com.demo.reflect.User");<br>User user = (User) clazz.newInstance();<br>// 获取私有属性,设置属性的值<br> Field idField = clazz.<font color="#f15a23">getDeclaredField</font>("id");<br>idField.<b><font color="#c41230">setAccessible</font></b>(true); // 忽略访问修饰检查(突破封装)<br>idField.<font color="#f15a23">set</font>(user, 10); // 给user对象的值设置为10<br>int id = idField.<font color="#f15a23">get</font>(user); // 从user对象中获取id的值<br>
操作 <b>成员方法</b> 对象
Class<?> clazz = Class.forName("com.demo.reflect.User");<br>User user = (User) clazz.newInstance();<br>// 获取私有方法,调用执行该方法<br>Method setName = clazz.<font color="#f15a23">getMethod</font>("setName", String.class);<br>setName.<b><font color="#c41230">setAccessible</font></b>(true); // 忽略访问修饰检查(突破封装)<br>setName.<font color="#f15a23">invoke</font>(user, "小黑");<br>
通用编程
反射执行任意实体类对象的 set 方法:Demo
反射执行任意实体类对象的 get 方法:Demo
反射执行任意实体类对象的任意方法:Demo
读取配置文件反射创建任意实体对象:Demo
<b>设计模式</b>
工厂模式
<ul><li><span style="font-size: inherit;">结合多态:扩展性更强</span></li><li><span style="font-size: inherit;">工厂模式:降低耦合度</span></li><li><span style="font-size: inherit;">反射机制:去代码冗余</span></li></ul>
// @param className 类的全限定名<br>public static <font color="#f15a23">Object</font> <b>createInstance</b>(String className) throws Exception {<br> return <font color="#f15a23"><b>Class</b></font>.<font color="#f15a23">forName</font>(className).<font color="#f15a23">newInstance</font>( );<br>}
Demo
单例模式
单例(singleton):只允许创建一个该类的对象。
饿汉式
天生线程安全(无锁)、类加载时创建(不用也创建,占用资源)
Demo
懒汉式
天生线程不安全(需同步锁、效率低)、使用时创建
Demo
懒汉式(<font color="#c41230">线程安全版</font>)
<font color="#c41230">天生线程安全(无锁)、使用时创建(静态内部类)</font>
Demo
代理模式
提供代理对象,增强方法功能。
静态代理设计模式
步骤:<br>① 自定义一个代理类(增强类)实现和被代理类(被增强类)相同的接口<br>② 在代理类中声明被代理类的<font color="#c41230">对象</font><br>③ 在代理类的方法中使用被代理类调用方法<br>
优点:<font color="#c41230">增强</font>被代理类的功能,可以<font color="#c41230">控制</font>被代理类的对象<br>缺点:必须要重写被代理类接口的所有的方法(破坏单一职能原则,<font color="#c41230">耦合性高</font>)
装饰者设计模式
步骤:<br>① 自定义一个装饰类(增强类)实现和被装饰类(被增强类)相同的接口<br>② 在装饰类中声明被装饰类的<font color="#c41230">引用</font><br>③ 在装饰类的方法中使用被装饰类调用方法<br>
优点:<font color="#c41230">增强</font>被代理类的功能,<font color="#c41230">无法控制</font>被代理类的对象<br>缺点:必须要重写被装饰类接口的所有的方法(破坏单一职能原则,<font color="#c41230">耦合性高</font>)
<b>动态代理设计模式</b>
动态代理本质就是通过反射来生成的一个代理。<br>在Java中 java.lang.reflect 包下提供了一个 Proxy 类和 InvocationHandler 接口,通过使用这个类和接口就可以生成动态代理对象。<br>JDK提供的代理只能针对接口做代理,有更强大的代理cglib,Proxy类中的方法创建动态代理对象。
步骤:——<font color="#c41230">基于接口的方法增强</font><br>① 编写一个代理类的接口<br>② 实现一个真正的代理类,实现该接口<br>③ 创建一个动态的代理类,实现 <font color="#f15a23"><b>InvocationHandler</b></font> 接口,并重写该 <font color="#f15a23">invoke</font>() 方法<br>④ 在测试类中调用 <b>Proxy</b>.<font color="#f15a23">newProxyInstance</font>() 方法生成动态代理对象<br>优化:③④可合并为匿名内部类实现。
优点:<font color="#c41230">不需要重写接口中的所有方法,耦合度更低</font>。
核心代码片段
/**<br>* 在代理实例上处理方法调用,并返回结果<br>* @param proxy 代理类的实例<br>* @param method 被代理类的原方法<br>* @param args 被代理类的原方法的实际参数<br>* @return Object对象<br>*/<br>@Override<br>public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {<br> System.out.println("权限校验");<br> Object result = method.<font color="#f15a23">invoke</font>(<font color="#662c90"><b>userDao</b></font>, args);<br> System.out.println("日志记录");<br> return result;<br>}
// ClassLoader loader: 被代理类对应的类加载器<br>// Class<?>[] interfaces: 被代理类所实现的所有接口<br>// InvocationHandler h: 一个用以增强代理类的处理器<br>接口名 p = (接口强转) <b>Proxy.</b><font color="#f15a23">newProxyInstance</font>(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h);
// 匿名内部类对象 - 指定需要增强的方法<br>UserDao np = (UserDao) <b>Proxy</b>.<b><font color="#f15a23">newProxyInstance</font></b>(<br> userDao.getClass().<font color="#f15a23">getClassLoader</font>(),<br> userDao.getClass().<font color="#f15a23">getInterfaces</font>(),<br> <font color="#f15a23">(proxy, method, argss) -> {</font><br> String methodName = method.getName();<br> Object result;<br> // 只增强指定的需要增强的方法<br> if ("<b>delete</b>".equals(methodName)) {<br> System.out.println("权限校验");<br> result = method.invoke(userDao, argss);<br> System.out.println("日志记录");<br> } else {<br> result = method.invoke(userDao, argss);<br> }<br> return result;<br><font color="#f15a23">}</font>);<br>np.<b>delete</b>();
① Demo
② Demo
③ Demo
④ Demo
<b>配置文件 + 工厂模式 + 反射 + 注解 + xml解析</b>
Java8新特性
接口中的实现方法
① 使用 <b><font color="#f15a23">default</font></b> 关键字就可以给接口增加一个非抽象的方法实现;
② 接口还可以存在 <b><font color="#f15a23">static</font></b> 静态方法实现,使用 <font color="#f15a23">接口名.静态方法名</font> 的形式直接调用;
* 包括声明 <font color="#16884a">@FunctionalInterface</font> 限制接口只有1个抽象方法时,也可以增加①或②。
* <font color="#c41230">一般不建议写实现</font>。
Demo
<font color="#c41230">Lambda</font> 表达式
概念:允许把函数作为一个方法的参数,代码简洁紧凑(<font color="#c41230">函数作为参数传递到方法中</font>)
语法
<b><font color="#c41230">函数式接口</font></b> 变量名 = <font color="#f15a23">(参数1,参数2...)->{<br> //方法体<br>};</font>
新的操作符:-> (箭头操作符)<br>* 箭头操作符左侧 (参数1,参数2,...)-> 表示参数列表<br>* 箭头操作符 ->右侧{...} 表示方法体
特点
* 形参列表的数据类型会自动推断<br>* 如果形参列表为空,只需保留()<br>* 如果形参列表只有1个参数,可以省略(),只要参数名字即可<br>* 如果执行语句只有1句,且无返回值,{}可以省略<br>* 若有返回值,仍想省略{},return也省略,必须保证执行语句为1句<br>* Lambda表达式不会生成单独的内部类文件<br>* Lambda表达式访问局部变量时,变量要修饰为final,如果没加会隐式自动添加<br>* Lambda表达式只能用在函数式接口的使用场景中
Demo
函数式接口
概念:如果一个接口只有 <b><font color="#c41230">1</font></b> 个公开抽象方法,则该接口为函数式接口。
* 为了确保接口达到只有1个方法的要求,接口名上添加注解 <font color="#16884a">@FunctionalInterface</font>
4 个核心函数式接口
位置:<b><font color="#f15a23">java.util.function</font></b>
① <b><font color="#f15a23">Predicate</font></b><T>接口(断言、返回真假)
② <b><font color="#f15a23">Consumer</font></b><T>接口(消费、有去无回)
③ <b><font color="#f15a23">Supplier</font></b><T>接口(创造、无中生有)
④ <b><font color="#f15a23">Function</font></b><T,R>接口(传递、返回数据)
Demo
https://simple.blog.csdn.net/article/details/105000639
方法引用 ::
Lambda表达式的一种简写形式。
如果Lambda表达式方法体中只是调用一个特定的已存在的方法,则可以使用方法引用。
4 种使用形式
① 对象::实例方法<br>② 类::静态方法<br>③ 类::实例方法<br>④ 类::new
注意:调用的方法的参数列表与返回值类型,都与函数式接口中的方法参数列表与返回值类型一致。
<b><font color="#c41230">Stream</font></b> 接口
支持顺序和并行聚合操作的一系列元素,是Java8中处理数组、集合的抽象概念。<br>可以执行非常复杂的查找、过滤、映射等操作。<br>
流(与I/O不同)
位置:<b><font color="#f15a23">java.util.stream</font></b>
流程
<font color="#f15a23">创建.中间操作....最终操作</font>
* 中间操作可.多个
主要的API方法
创建
Stream<T> stream = 集合或数组.stream();
中间操作
Stream<T> <font color="#f15a23">filter</font>(Predicate<? super T> predicate)<br>返回由与此给定谓词匹配的此流的元素组成的流。<br>Stream<T><font color="#f15a23"> limit</font>(long maxSize)<br>返回由此流的元素组成的流,截短长度不能超过 maxSize 。<br>Stream<T> <font color="#f15a23">distinct</font>()<br>返回由该流的不同元素(根据 Object.equals(Object) )组成的流。<br><R> Stream<R> <font color="#f15a23">map</font>(Function<? super T,? extends R> mapper)<br>返回由给定函数应用于此流的元素的结果组成的流。<br>Stream<T> <font color="#f15a23">sorted</font>()<br>返回由此流的元素组成的流,根据自然顺序排序。<br>Stream<T> <font color="#f15a23">sorted</font>(Comparator<? super T> comparator)<br>返回由该流的元素组成的流,根据提供的 Comparator进行排序。
最终操作
long <font color="#f15a23">count</font>()<br>返回流中的元素个数。<br>void <font color="#f15a23">forEach</font>(Consumer<? super T> action)<br>对此流的每个元素执行遍历操作。<br>boolean <font color="#f15a23">anyMatch</font>(Predicate<? super T> predicate)<br>或,流中是否有包含指定规则的元素<br>boolean <font color="#f15a23">allMatch</font>(Predicate<? super T> predicate)<br>且,流中是否全部包含指定规则的元素<br>boolean <font color="#f15a23">noneMatch</font>(Predicate<? super T> predicate)<br>非,流中是否都不包含指定规则的元素<br>Optional<T> <font color="#f15a23">findFirst</font>()<br>返回流的第一个元素的Optional,如果流为空,则返回一个空的Optional 。<br>Optional<T> <font color="#f15a23">findAny</font>()<br>返回流的任意一个随机元素的Optional,如果流为空,则返回一个空的Optional 。<br>Optional<T> <font color="#f15a23">max</font>(Comparator<? super T> comparator)<br>根据提供的 Comparator 返回此流的最大元素。<br>Optional<T> <font color="#f15a23">min</font>(Comparator<? super T> comparator)<br>根据提供的 Comparator 返回此流的最小元素。
串行流
.<font color="#f15a23">stream</font>()
并行流
.<font color="#f15a23">parallelStream</font>()
比串行流的<font color="#c41230">效率更高</font>
<font color="#ffff99">集合</font>体系
<b><font color="#000000">Colleciton</font></b>
<b><font color="#000000">List</font></b>
<b><font color="#f15a23">ArrayList</font></b>
<b><font color="#f15a23">Vector</font></b>
<b><font color="#f15a23">LinkedList</font></b>
<b><font color="#f15a23">CopyOnWriteArrayList</font></b>
<b><font color="#000000">Set</font></b>
<b><font color="#f15a23">HashSet</font></b>
<b><font color="#f15a23">LinkedHashSet</font></b>
<b><font color="#000000">SortedSet</font></b>
<b><font color="#f15a23">TreeSet</font></b>
<b><font color="#662c90">AbstractSet</font></b>
<b><font color="#f15a23">CopyOnWriteArraySet</font></b>
<b><font color="#000000">Queue</font></b>
<b><font color="#f15a23">ConcurrentLinkedQueue</font></b>
<font color="#662c90" style="font-weight: bold;">AbstractQueue<br></font><font color="#0076b3">抽象类</font><br><b style="color: rgb(0, 0, 0);">BlockingQueue</b>
<b><font color="#f15a23">ArrayBlockingQueue</font></b>
<b><font color="#f15a23">LinkedBlockingQueue</font></b>
<b><font color="#000000">Map</font></b>
<font color="#f15a23" style=""><b>HashMap</b></font>
<b><font color="#f15a23">LinkedHashMap</font></b>
<b><font color="#f15a23">Hashtable</font></b>
<b><font color="#f15a23">Properties</font></b>
<b><font color="#662c90">AbstractMap</font></b>
<b><font color="#f15a23">TreeMap</font></b>
<b><font color="#f15a23">ConcurrentHashMap</font></b>
<b><font color="#000000">Collections</font></b>
排序
public static <T extends Comparable<? super T>> void <font color="#f15a23">sort</font>(List<T> list)<br>public static void <font color="#f15a23">reverse</font>(List<?> list)<br>public static void <font color="#f15a23">shuffle</font>(List<?> list)<br>
同步
public static <T> Collection<T> <font color="#f15a23">synchronizedCollection</font>(Collection<T> c)<br>public static <T> List<T> <font color="#f15a23">synchronizedList</font>(List<T> list)<br>public static <T> Set<T> <font color="#f15a23">synchronizedSet</font>(Set<T> s)<br>public static <K,V> Map<K,V> <font color="#f15a23">synchronizedMap</font>(Map<K,V> m)<br>public static <T> SortedSet<T> <font color="#f15a23">synchronizedSortSet</font>(SortedSet<T> s)<br>public static <K,V> SortedMap<K,V> <font color="#f15a23">synchronizedSortedMap</font>(SortedMap<K,V> m)
其他诸如检查、判空、最大小值、交换等... API文档。
<font color="#ffff99">字节</font>流体系
<b>OutputStream</b>
<b>FileOutputStream (fn)</b>
FilterOutputStream
<b>BufferedOutputStream (fos)</b>
<b>ObjectOutputStream (fos)</b>
<b>InputStream</b>
<b>FileInputStream (fn)</b>
FilterInputStream
<b>BufferedInputStream (fis)</b>
<b>ObjectInputStream (fis)</b>
<font color="#ffff99">字符</font>流体系
<b>Writer</b><br>
<b>OutputStreamWriter (fos)</b><br>
<b>FileWriter (fn)</b><br>
<strike style=""><font color="#5c5c5c">BufferedWriter</font></strike><br>
<b>PrintWriter (osw)</b><br>
<b>Reader</b><br>
<b>InputStreamReader (fis)</b><br>
<b>FileReader (fn)</b><br>
<b>BufferedReader (isr)</b><br>
<b>JavaWeb</b>
<b><font color="#000000">MySQL</font></b>
概念
<b><font color="#c41230">关系结构数据库</font></b>:Oracle、DB2、MySQL、SQL Server。<br>以表格(Table)存储,多表间建立关联关系,通过分类、合并、连接、选取等运算实现访问。
DBMS,数据库管理系统。<br>MySQL:免费、适合中小型企业(被Oracle收购)。<br>在 WEB 应用方面,MySQL是最好的 RDBMS(关系数据库管理系统)应用软件之一。<br>
获取
官方网站:https://www.mysql.com/<br>下载地址:<font color="#c41230">https://dev.mysql.com/downloads/mysql/</font><br>安装包名:<font color="#f15a23"><b>mysql-installer-community-5.7.28.0.msi</b></font><br>* <b><font color="#f15a23">MySQL57</font></b>,即5.7版本应用较为广泛。
安装
详细安装步骤
https://simple.blog.csdn.net/article/details/105099985
配置
环境变量
Win
1. 创建<b>MYSQL_HOME</b> : <font color="#0076b3">C:\Program Files\MySQL\MySQL Server 5.7</font><br>2. 追加<b>Path</b>:<font color="#0076b3">%MYSQL_HOME%\bin;</font>
Mac
* 终端中输入cd ~ 进入目录,并检查.bash_profile是否存在,有则追加,无则创建<br>* 创建文件 touch .bash_profile<br>* 打开文件 open .bash_profile<br>* 输入export PATH=${PATH}:/usr/local/mysql/bin 保存并退出终端
配置参数
C:\ProgramData\MySQL\MySQL Server 5.7\<font color="#0076b3">my.ini</font>
default-character-set
客户端默认字符集,默认被注释,即遵循环境的字符集
character-set-server
服务器端默认字符集,默认被注释,即遵循环境的字符集
port
客户端和服务器端的端口号,默认 port=<b><font color="#f15a23">3306</font></b>
default-storage-engine
MySQL默认存储引擎 INNODB<br>
解决插入中文数据乱码或问号的问题
[mysql] # 第一处 line67<br>default-character-set=utf8
[mysqld] # 第二处 line102<br>character-set-server=utf8<br>collation-server=utf8_general_ci
重启MySQL服务:<br>win> <font color="#f15a23">net stop mysql57 && net start mysql57</font><br>Linux$ <font color="#f15a23">service mysql restart</font>
启动
win> <font color="#f15a23"><b>net start mysql57</b></font>
修改root密码
旧版(mysql57可用):root可替换为其他用户名<br><b><font color="#f15a23">SET PASSWROD FOR</font></b> root@localhost = <font color="#f15a23">PASSWORD</font>('123456');<br>新版:<br><b><font color="#f15a23">ALTER USER</font></b> 'root'@'localhost' <b><font color="#f15a23">IDENTIFIED BY</font></b> '123456';<br>
客户端工具
Navicate
快速、可靠并价格相宜的数据库管理工具,专为简化数据库的管理及降低系统管理成本而设。<br>* 使用 Navicate 需要会pj
<b><font color="#0076b3">SQLyog </font></b>
广泛的预定义工具和查询、友好的视觉界面、类似 Excel 的查询结果编辑界面。
<font color="#0076b3">DataGrip </font>
<font color="#c41230">IDEA开发工具集成</font>。<br>DataGrip是捷克公司的产品,需要付费。如果买了IDEA,DataGrip通用。<br>
SQL语言分类
1. 数据`<b>查询</b>`语言 `<b><font color="#f15a23">DQL</font></b>`(Data Query Language):select、where、order by、group by、having<br>2. 数据`<b>定义</b>`语言 `<b><font color="#f15a23">DDL</font></b>`(Data Definition Language):create、alter、drop<br>3. 数据`<b>操作</b>`语言 `<b><font color="#f15a23">DML</font></b>`(Data Manipulation Language):insert、update、delete<br>4. 事务`<b>处理</b>`语言 `<b><font color="#f15a23">TPL</font></b>`(Transaction Process Language):commit、rollback<br>5. 数据`<b>控制</b>`语言 `<b><font color="#f15a23">DCL</font></b>`(Data Control Language):grant、revoke
<font color="#0076b3">命令</font>
查询
基本查询
<font color="#f15a23" style=""><b>SELECT 列名 FROM 表名;</b></font>
运算 + - * / 没有 %(它现在是占位符)
列 <b><font color="#f15a23">AS</font></b> '列别名'
<b><font color="#f15a23">DISTINCT</font></b> 列名
排序查询
<b><font color="#5c5c5c">SELECT 列名 FROM 表名 </font><font color="#f15a23">ORDER BY 排序列1 [排序规则], 排序列2 [排序规则]</font></b>
排序规则
ASC 升序
DESC 降序
条件查询
<b><font color="#5c5c5c">SELECT 列名 FROM 表名 </font><font color="#f15a23">WHERE 条件</font></b>
等值判断 =
不等值判断 >、<、>=、<=、!=、<>(也是不等)
逻辑判断 <b><font color="#f15a23">AND, OR, NOT</font></b>
区间判断 <b><font color="#f15a23">BETWEEN ... AND ...</font></b>
包含两端边界两个值
小到大顺序不能颠倒
NULL值判断 <b><font color="#f15a23">IS NULL, IS NOT NULL</font></b>
枚举查询 <b><font color="#f15a23">IN</font></b>(值1, 值2, 值3..)
模糊查询
列名 <b><font color="#f15a23">LIKE</font></b> 'S_'
_ 单个任意字符,模糊内容、精确长度
列名 <b><font color="#f15a23">LIKE</font></b> 'S%'
% 0或多个任意字符0-n个
分支结构查询
<font color="#f15a23"><b>CASE<br> WHEN 条件1 THEN 结果1<br> WHEN 条件2 THEN 结果2<br> WHEN 条件3 THEN 结果3<br> ELSE 结果x<br>END </b>AS '列别名'</font>
对紧跟列名的操作,注意列名后的 逗号
时间查询
<b><font color="#5c5c5c">SELECT</font><font color="#f15a23"> 时间函数([参数列表]);</font></b>
SYSDATE() / NOW() 年-月-日 时:分:秒<br>CURDATE() 年-月-日<br>CURTIME() 时:分:秒<br>WEEK(DATE) 获取指定日期为一年中的第几周<br>YEAR(DATE) / MONTH(DATE) / DAY(DATE) 年、月、日<br>HOUR(TIME) / MINUTE(TIME) / SECOND(TIME) 时、分、秒<br>DATEDIFF(DATE1, DATE2) 两个日期的相隔天数<br>ADDDATE(DATE, N) 计算DATE加上N天后的日期(自然日)
聚合函数
<b>SELECT <font color="#f15a23">聚合函数(列名)</font> FROM 表名;</b>
COUNT(列) 总行数,忽略null值<br>SUM(列) 所有行中单列结果的综合<br>AVG(列) 平均值<br>MAX(列) 最大值<br>MIN(列) 最小值
分组查询
<b>SELECT 列名 FROM 表名 WHERE 条件 <font color="#f15a23">GROUP BY 分组依据列</font>;</b><br>
WHERE 条件 也可省略。
分组过滤查询
<b>SELECT 列名 FROM 表名 WHERE 条件 GROUP BY 分组列 <font color="#f15a23">HAVING 过滤规则</font>;</b>
过滤规则:定义对分组后的数据进行过滤,相当于一个新的条件。
字符串查询
<b><font color="#5c5c5c">SELECT</font><font color="#f15a23"> 字符串函数([参数列表]);</font></b>
CONCAT(str1, str2, str...) 连接多个字符串<br>INSERT(str, pos, len, newstr) 将str中指定pos位置开始的len长度的内容替换为newstr<br>LOWER(str) 转小写<br>UPPER(str) 转大写<br>SUBSTRING(str, pos) / (str FROM pos) / (str, pos, len) / (str FROM pos FOR len)<br>将str字符串中指定pos位置开始截取到末尾或者len长度的内容
* 注意:<font color="#c41230"><b>MySQL 中字符串下标是从 1 开始</b></font>。
限定查询
<b>SELECT 列名 FROM 表名 <font color="#f15a23">LIMIT 起始行,查询行数</font>;</b>
* 注意:<b><font color="#c41230">LIMIT 的起始行是从 0 开始为第1 行</font></b>。
【公式】第 i 页: <font color="#f15a23">SELECT * FROM LIMIT 页长*(i-1), 页长</font>
【查询总结】
<b>SELECT 列名 <font color="#c41230">FROM 表名<br>WHERE 条件 GROUP BY 分组 HAVING 过滤条件<br></font>ORDER BY 排序列 LIMIT 起始行,总条数;</b>
执行顺序:<br>⑤ SELECT 列名<br><b style="font-size: inherit;"><font color="#f15a23">①</font></b><span style="font-size: inherit;"> FROM 表名</span><br><b><font color="#f15a23">②</font></b> WHERE 条件<br><b><font color="#f15a23"> ③</font></b> GROUP BY 分组<br><b><font color="#f15a23"> ④</font></b> HAVING 过滤条件<br>⑥ORDER BY 排序列(asc|desc)<br>⑦LIMIT 起始行,总条数
子查询
子查询结果作为条件判断
<b>SELECT 列名 FROM 表名 <font color="#f15a23">WHERE 条件 > (子查询结果值)</font><font color="#5c5c5c">;</font></b>
子查询结果:<font color="#c41230">一行一列</font>(1个值)
子查询结果作为枚举查询条件
<b>SELECT 列名 FROM 表名 <font color="#f15a23">WHERE 列名 IN(子查询结果列)</font>;</b>
子查询结果:<font color="#c41230">多行单列</font>(1列值) - IN可替换为 <b><font color="#f15a23">ANY</font></b> 或 <font color="#f15a23"><b>ALL</b></font> 关键字
子查询结果作为一张表
<b>SELECT 列名 FROM <font color="#f15a23">(子查询结果表) AS 表别名</font>;</b>
子查询结果:<font color="#c41230">多行多列</font>(1张表)
合并查询
去重合并
<b>SELECT * FROM 表名 1 <font color="#f15a23">UNION</font> SELECT * FROM 表名 2</b>
全部合并
<b>SELECT * FROM 表名1 <font color="#f15a23">UNION ALL</font> SELECT * FROM 表名2</b>
列数必须相同,行内容向下追加。
表连接查询
<b>SELECT 列名 FROM 表1 <font color="#f15a23">连接方式</font> 表2 <font color="#f15a23">ON 连接条件</font><font color="#5c5c5c">;</font></b>
四种连接方式
内连接方式: <b><font color="#f15a23">INNER JOIN ... ON ...</font></b>
内连接多表: <b><font color="#f15a23">INNER JOIN ... INNER JOIN ... ON ...</font></b>
外连接左表: <b><font color="#f15a23">LEFT JOIN ... ON ...</font></b>
外连接右表: <b><font color="#f15a23">RIGHT JOIN ... ON ...</font></b>
库表
库操作
库中的数据类型
数值类型:<font color="#f15a23">INT</font> / DOUBLE / <font color="#f15a23">DOUBLE(M,D)</font> / <font color="#f15a23">DECIMAL(M,D)</font>
日期类型:<font color="#f15a23">DATE</font> / TIME / YEAR / <font color="#f15a23">DATETIME</font> / TIMESTAMP<br>
字符串类型:<font color="#f15a23">CHAR</font> / <font color="#f15a23">VARCHAR</font> / BOLB / TEXT<br>
查看所有数据库
<b><font color="#f15a23">SHOW</font></b> DATABASES; #显示当前MySQL中包含的所有数据库
创建自定<b><font color="#c41230">数据库</font></b>
<font color="#5c5c5c">CREATE DATABASE</font> mydb1; #创建mydb数据库<br><b><font color="#f15a23">CREATE DATABASE</font></b> mydb2 <b><font color="#f15a23">CHARACTER</font></b> <b><font color="#f15a23">SET</font></b> gbk; #创建数据库并设置编码格式gbk【常用】<br>CREATE DATABASE mydb3 CHARACTER SET gbk COLLATE gbk_chinese_ci; #支持简体中文和繁体中文<br>CREATE DATABASE IF NOT EXISTS mydb4; #如果mydb4数据库不存在,则创建;如果存在,则不创建。
查看库创建信息
<b><font color="#f15a23">SHOW CREATE</font></b> DATABASE mydb2; #查看创建数据库时的基本信息
修改数据库信息
<b><font color="#f15a23">ALTER</font></b> DATABASE mydb2 CHARACTER SET utf8; # 修改mydb1 的字符集为 utf-8<br>
删除指定数据库
<b><font color="#f15a23">DROP</font></b> <font color="#f15a23">DATABASE</font> mydb1; #删除数据库mydb1
查看使用数据库
<b><font color="#f15a23">SELECT</font></b> DATABASE<b><font color="#f15a23">( )</font></b>; #查看当前使用的数据库
切换使用数据库
<b><font color="#f15a23">USE</font></b> mydb1; #使用mydb1数据库
表操作
创建自定<font color="#c41230"><b>数据表</b></font>
<b><font color="#f15a23">CREATE TABLE</font></b> 表名<b><font color="#f15a23">(</font></b><br> 列名1 数据类型 [约束],<br> 列名1 数据类型 [约束],<br> ...<br> 列名n 数据类型 [约束] # 最后一行不加逗号<br><b><font color="#f15a23">)</font></b>[<b><font color="#f15a23">CHARSET</font></b> = utf8]<b><font color="#f15a23">; </font></b> # 可根据需要指定表的字符编码集<br>
<b>【DML】</b>
DML:增、删、改
创建
<b><font color="#f15a23">INSERT INTO</font> 表名(列 1,列 2,列 3....) <font color="#f15a23">VALUES</font>(值 1,值 2,值 3......);</b>
* 表名后的列名和 VALUES 里的`<font color="#c41230">值要一一对应</font>`(个数、顺序、类型)
查看表创建信息
<b><font color="#f15a23">SHOW CREATE</font></b> TABLE student; #查看创建数据表时的信息:列名和类型
修改
<b><font color="#f15a23">UPDATE</font> 表名 <font color="#f15a23">SET </font>列1 = 新值1, 列2 = 新值2, ... <font color="#f15a23">WHERE 条件</font>;</b>
* 注意:SET 后多个列名=值,绝大多数情况下都要`<font color="#c41230">加 WHERE 条件</font>`,指定修改,`<font color="#c41230">否则为整表更新</font>`。
列的增删改
# 【增】最右侧添加:如果想在一个已经建好的表中添加一列,可以用<br><font color="#f15a23"><b>ALTER</b> TABLE</font> mydb1 <font color="#f15a23">ADD COLUMN</font> NEW_COLUMN_NAME VARCHAR(45) <font color="#f15a23">NOT</font> NULL;<br># 【增】指定位置添加:这条语句向已有的表中加入新的一列,这一列在表的最后一列位置,希望添加在指定的一列<br><font color="#f15a23"><b>ALTER</b> TABLE</font> mydb1 <font color="#f15a23">ADD COLUMN</font> NEW_COLUMN_NAME VARCHAR(45) <font color="#f15a23">NOT NULL</font> <font color="#f15a23">AFTER</font> COLUMN_NAME;<br># 【增】添加到第一列:上面这个命令的意思是说添加新列到某一列后面。如果想添加到第一列<br><font color="#f15a23"><b>ALTER</b> TABLE</font> mydb1 <font color="#f15a23">ADD</font> <font color="#f15a23">COLUMN</font> NEW_COLUMN_NAME VARCHAR(45) <font color="#f15a23">NOT NULL FIRST</font>;<br># 【改】将表 mydb1 中,列名 def 改为unit<br><font color="#f15a23"><b>ALTER</b> TABLE</font> mydb1 <font color="#f15a23">CHANGE</font> def unit CHAR;<br># 【删】将表 mydb1 中,列名 unit 的列删除<br><font color="#f15a23"><b>ALTER</b> TABLE</font> mydb1 <font color="#f15a23">DROP COLUMN</font> unit;
删除
<b><font color="#f15a23">DELETE FROM</font> 表名 <font color="#f15a23">WHERE 条件</font>;</b>
* 注意:删除时,`<font color="#c41230">必须加 WHERE 条件</font>`,如若不加 WHERE条件,删除的是整张表的数据<br>* 注意:仅仅删除数据,<font color="#c41230">不会影响数据表的结构</font>
清空
<b><font color="#f15a23">TRUNCATE TABLE</font> 表名;</b>
* 注意:TRUNCATE 是`<font color="#c41230">把表销毁</font>`,再按照原表的格式`<font color="#c41230">创建一张新表</font>`
约束
实体完整性约束
* <b><font color="#c41230">标识每一列数据不重复、实体唯一</font></b>。
主键约束
<b><font color="#f15a23">PRIMARY KEY</font></b>
列值:不可重复,不能为 NULL
唯一约束
<b><font color="#f15a23">UNIQUE</font></b>
列值:不可重复,可以为 NULL
自动增长列
<b><font color="#f15a23">AUTO_INCREMENT</font></b>
列值:从 1 开始,每次加 1;不能单独使用,和主键配合
域完整性约束
* <b><font color="#c41230">限制列的单元格的数据正确性</font></b>。
非空约束
<b><font color="#f15a23">NOT NULL</font></b>
列值:必须有值,不能为 NULL
默认值约束
<b><font color="#f15a23">DEFAULT</font></b>
列值:为列赋予默认值;书写DEFAULT,以指定的默认值进行填充
引用完整性约束
<b><font color="#f15a23">CONSTRAINT 引用名 FOREIGN KEY(列名) REFERENCES 被引用表名(列名)</font></b>
列值:FOREIGN KEY 引用外部表的某个列的值,新增数据时,约束此列的值必须是引用表中存在的值
事务
概念
<font color="#c41230">事务,是一个原子操作,是一个最小执行单元,可以由一个或多个SQL语句组成</font>。<br>在同一个事务当中,所有的SQL语句都成功执行时,整个事务成功,有一个SQL语句执行失败,整个事务都执行失败。
边界
<b>开始</b>:<br>上一个事务结束后的第一条增删改的语句,即事务的开始。<br># 1.开启事务 方式一: <br><b><font color="#f15a23">START TRANSACTION;</font></b> <br># 1.开启事务 方式二:<br><b><font color="#f15a23">SET autoCommit = 0</font></b>; # autoCommit = 0 关闭自动提交,1 开启自动提交<br>
<b>结束</b>:<br> 1). 提交:<br> a. 显示提交:<b><font color="#f15a23">COMMIT</font></b>;<br> b. 隐式提交:一条创建/删除的语句,正常退出(客户端退出连接);<br> 2). 回滚:<br> a. 显示回滚:<b><font color="#f15a23">ROLLBACK</font></b>;<br> b. 隐式回滚:非正常退出(断电/宕机)执行了创建/删除语句,但是失败了,会为这个无效的语句执行回滚。<br>
原理
数据库会为每一个客户端都维护一个`<font color="#c41230">空间独立的缓存区</font>`(回滚段)。<br>一个事务中所有的增删改语句的`<font color="#c41230">执行结果都会缓存在回滚段</font>`中,<br>只有当事务中所有 SQL 语句均`<font color="#c41230"><b>正常结束</b></font>`(commit),<br>才会将回滚段中的数据同步到数据库。否则无论因为哪种原因失败,整个事务将<b><font color="#c41230">回滚</font></b>(rollback)。
<b>特性(<font color="#c41230">ACID</font>)</b>
<b><font color="#f15a23">Atomicity(原子性)</font></b><br>表示<font color="#c41230">一个事务内的所有操作是一个整体</font>,要么全部成功,要么全部失败。
<b><font color="#f15a23">Consistency(一致性)</font></b><br>表示一个事务内有<font color="#c41230">一个操作失败时</font>,所有的更改过的数据都必须<font color="#c41230">回滚到修改前状态</font>。
<b><font color="#f15a23">Isolation(隔离性)</font></b><br>事务查看数据操作时数据所处的状态,要么是另一并发事务<font color="#c41230">修改它之前的状态</font>,<br>要么是另一事务<font color="#c41230">修改它之后的状态</font>,事务<font color="#c41230">不会查看中间状态的数据</font>。
<b><font color="#f15a23">Durability(持久性)</font></b><br>持久性事务完成之后,它<font color="#c41230">对于系统的影响是永久性的</font>。
<b>应用&实例</b>
应用环境:<br>基于增删改语句的操作结果(均返回操作后受影响的行数),<br>可通过程序逻辑手动控制事务提交或回滚。
模拟转账 Demo
权限
创建用户
<b><font color="#f15a23">CREATE USER</font> 用户名 <font color="#f15a23">IDENTIFIED BY</font> 密码;</b>
授权用户
<b><font color="#f15a23">GRANT ALL ON</font> 数据库.表 <font color="#f15a23">TO</font> 用户名;</b>
撤销授权
<b><font color="#f15a23">REVOKE ALL ON</font> 数据库.表名 <font color="#f15a23">FROM</font> 用户名;</b>
删除用户
<b><font color="#f15a23">DROP USER</font> 用户名;</b>
视图
概念
视图,`<b><font color="#c41230">虚拟表</font></b>`,从一个表或多个表中查询出来的表,作用和真实表一样,`包含一系列带有行和列的数据`。<br>视图中,用户<b><font color="#c41230">可以使用 SELECT 语句查询数据</font></b>,也<font color="#c41230">可以使用 INSERT、UPDATE、DELETE 修改记录(影响原表)</font>,<br>视图可以使用户操作方便,并保障数据库系统安全。
特点
优点
- <b>简单化</b>,数据所见即所得。<br>- <b>安全性</b>,用户只能查询或修改他们所能见到得到的数据。<br>- <b>逻辑独立性</b>,可以屏蔽真实表结构变化带来的影响。
缺点
- <b>性能相对较差</b>,简单的查询也会变得稍显复杂。<br>- <b>修改不方便</b>,特变是复杂的聚合视图基本无法修改。
创建
<b><font color="#f15a23">CREATE VIEW</font> 视图名 <font color="#f15a23">AS</font> 查询数据源表语句;</b>
使用
<b><font color="#f15a23">SELECT *</font></b> 与正常的 TABLE 使用方式相同
修改
方式① <b><font color="#f15a23">CREATE OR REPLACE VIEW</font> 视图名 <font color="#f15a23">AS</font> 查询语句;</b><br>方式② <b><font color="#f15a23">ALTER VIEW</font> 视图名 <font color="#f15a23">AS</font> 查询语句;</b>
删除
<b><font color="#f15a23">DROP VIEW</font> 视图名;</b>
<b><font color="#000000">JDBC</font></b>
概念
<b><font color="#f15a23">JDBC</font></b>(<font color="#f15a23">Java DataBase Connectivity</font>) Java连接数据库,可以<font color="#c41230">使用Java语言连接数据库完成 CRUD 操作</font>。<br><b><font color="#f15a23">CRUD</font></b>:增加(<font color="#f15a23">Create</font>)、读取(<font color="#f15a23">Retrieve</font>)、更新(<font color="#f15a23">Update</font>)和删除(<font color="#f15a23">Delete</font>)
核心思想
Java中定义了访问数据库的接口,可以为多种关系型数据库提供<b><font color="#c41230">统一的访问方式</font></b>。<br>由数据库厂商提供驱动实现类(<b>Driver数据库驱动</b>)
Driver: <font color="#0076b3">mysql-connector-java-5.1.X 适用于5.X版本</font><br>Driver: mysql-connector-java-8.0.X 适用于8.X版本
API
环境搭建
1. 在项目下新建 lib 文件夹,用于存放 jar 文件<br>2. 复制MySQL驱动文件 <font color="#31a8e0"><b>mysql-connector-java-5.1.25-bin.jar</b></font> 到项目的 lib 文件夹中<br>3. 选中 lib 文件夹,右键选择 <font color="#f15a23">add as library</font>,点击OK
5.x 链接:https://pan.baidu.com/s/1pB0xoNHDt2NxCX0fgA4ezg <br>提取码:48t6<br>8.x 链接:https://pan.baidu.com/s/1FWzpLm1XUqCFKkVt9KDINA <br>提取码:d5b3<br>
开发步骤
1. <b><font color="#c41230">加载</font></b>驱动
<font color="#5c5c5c" style="">// 反射:触发类加载,Driver 执行了 static 代码块</font><br><b style="color: rgb(241, 90, 35);">Class.</b><i><b><font color="#00a650">forName</font></b></i>("<font color="#31a8e0">com.mysql.jdbc.Driver</font>");
2. <b><font color="#c41230">连接</font></b>数据库
// 数据库连接地址,兼容中文正确显示的参数:?useUnicode=true&characterEncoding=utf8<br>String url = "<b><font color="#31a8e0">jdbc</font>:<font color="#31a8e0">mysql</font>://localhost:3306/<font color="#0076b3">companydb</font></b><font color="#f15a23">?</font><font color="#c41230">useUnicode</font><font color="#f15a23">=true&</font><font color="#c41230">characterEncoding</font><font color="#f15a23">=utf8</font>";<br> String user = "root"; // 用户名<br> String password = "admin123"; // 密码<br> Connection connection = <b><font color="#f15a23">DriverManager.</font><i><font color="#00a650">getConnection</font></i></b>(url, user, password);
3. <b><font color="#c41230">获取</font></b>发送 SQL 语句的对象
// 普通对象<br><strike>Statement statement = connection.createStatement();</strike>
//【使用】预编译SQL语句;安全地避免SQL注入;动态填充数据执行多个同构的SQL语句<br>PreparedStatement preparedStatement = <b><i><font color="#00a650">connection</font></i>.</b><font color="#f15a23">prepareStatement</font>(sql);<br><font color="#f15a23">preparedStatement.<b>set类型</b>(下标,值)</font>; // String sql = "...?...?...?"; 下标: 对应问号占位符 1 2 3<br>
4. <b><font color="#c41230">编写</font></b>并<b><font color="#c41230">执行</font></b> SQL 语句
// <font color="#c41230">DML(增删改)操作</font><br>int result = <b><i><font color="#00a650">preparedStatement.</font></i></b><font color="#f15a23">executeUpdate</font>();
// DQL(查询)操作<br>ResultSet resultSet = <b><i><font color="#00a650">preparedStatement.</font></i></b><font color="#f15a23">executeQuery</font>();
5. <font color="#c41230"><b>处理</b></font>结果
if (<b><font color="#f15a23">result > 0</font></b>) { /* 执行成功 */ } else { /* 执行失败 */ }
if (<b><font color="#f15a23">resultSet.next()</font></b>) { <br> 类型 变量 = <font color="#f15a23">resultSet.<b>get类型</b>(int columnIndex)</font>; // 列的编号从1开始<br> 类型 变量 = <font color="#f15a23">resultSet.<b>get类型</b>(String columnLable)</font>; // 列名<br>} else { <br> /* 查询失败 */ <br>}
6. <b><font color="#c41230">关闭</font></b>资源
// 原则:<b><font color="#c41230">先开后闭</font></b><br>非空 resultSet.close();<br>非空 preparedStatement.close();<br>非空 connection.close();
封装连接
重用性方案
封装了获取连接、释放资源两个方法:<br>public static Connection <font color="#f68b1f">getConnection</font>( )<br>public static void <font color="#f68b1f">closeAll</font>(Connection c, Statement s, ResultSet r)
DBUtils.java - Demo
跨平台方案
定义 private static final Properties <b><font color="#662c90">properties</font></b> = new Properties(); // 配置文件集合<br>定义 static{<br> // 首次使用工具类,触发类加载<br> InputStream is = <b style=""><font color="#f15a23">DBUtils.</font><font color="#c41230">class</font><font color="#f15a23">.getResourceAsStream</font></b>("文件路径"); // 复用本类自带流,读取配置文件<br> properties.<font color="#f15a23">load</font>(is); // 将is流中的配置文件信息,加载到集合中<br> Class.forName(properties.<font color="#f15a23">getProperty</font>("driver"));<br>}<br>在 getConnection 方法中应用 properties.<font color="#f15a23">getProperty</font>("url"); // 以及 username 和 password
DBUtils.java - Demo
src/db.properties - Demo
优化封装事务
DBUtils.java - Demo
封装数据
ORM 思想:零散数据的载体
概念:Object Relational Mapping,<font color="#f15a23">对象关系映射</font>。<br>将数据库查询到的结果集遍历映射为对象集合。<br>entity规则:<font color="#c41230"><b>表名=类名</b></font>;<b><font color="#c41230">列名=属性名</font></b>;提供<font color="#c41230" style="font-weight: bold;">各个属性的get/set</font><font color="#5c5c5c" style="">方法;提供无参构造和[若需有参构造]</font>
Demo
DAO 层:数据访问对象
概念:Data Access Object,<font color="#f15a23">数据访问对象</font>。<br>1. 将所有对同一张表的操作都封装在一个 XXXDaoImpl对象中;<br>2. 根据增删改查的不同功能,实现具体的方法(insert, update, delete, select, selectAll);<br>经验:<font color="#c41230">应将对于一张表的所有操作统一封装在一个数据访问对象中。——<b>重用</b>!</font>
Demo
日期转换
分类
<font color="#f15a23">String</font> 类型,用户输入类型
<font color="#f15a23">java.util.Date</font> 类型,java应用层的日期类型
<font color="#f15a23">java.sql.Date</font> 类型,java的MySQL中特殊日期类型
<b>String</b> → java.<b>util</b>.Date
日期格式化类: <b><font color="#f15a23">SimpleDateFormat</font></b>
//按照指定格式转换成util.Date类型<br>String dateStr = "1999-09-09";<br>SimpleDateFormat sdf = new <font color="#f15a23"><b>SimpleDateFormat</b></font>("yyyy-MM-dd");<br><font color="#31a8e0">java.util.Date</font> date = sdf.<font color="#f15a23">parse</font>(dateStr);
java.<b>util</b>.Date → java.<b>sql</b>.Date
// java.sql.Date(long mesc) 参数为毫秒值的有参构造<br>public static java.<font color="#31a8e0">sql</font>.Date utilToSql(java.<font color="#31a8e0">util</font>.Date date) {<br> return new java.<font color="#31a8e0">sql</font>.Date(date.<font color="#f15a23">getTime</font>());<br>}
java.<b>sql</b>.Date → java.<b>util</b>.Date
// 无需转换:父类引用指向子类对象<br>java.<font color="#31a8e0">util</font>.Date utilDate = <font color="#f15a23">new</font> java.<font color="#31a8e0">sql</font>.Date(<font color="#c41230">long msec</font>); // mesc: 毫秒值<br>// eg:<br>java.util.Date user_borndate = resultSet.getDate("user_borndate");<br>
数据库<b><font color="#c41230">连接池</font></b>
自定义连接池普通版
步骤:<br>1.连接池初始化时,创建一些连接,并存储到 LinkedList中<br>2.获取连接,LinkedList.remove(0)<br>3.归还连接,addBack(connection)
Demo
自定义连接池优化版
步骤:<br>1.连接池初始化时,创建一些连接,并存储到 LinkedList中<br>2.加入装饰者设计模式,将普通连接对象Connection中的close方法改变成归还连接<br> > 破坏单一职责原则,使用了中间类<br>3.获取连接,使用装饰者设计模式,返回增强的连接对象<br>4.归还连接,就无序addBack(connection)方法
自定义连接池终极版
步骤:<br>1.连接池初始化时,创建一些连接,并存储到 LinkedList中<br>2.加入动态代理,将普通连接对象Connection中的close方法改变成归还连接<br>3.获取连接,使用动态dialing,返回增强的连接对象<br>
Demo
<b><font color="#f15a23">Druid</font></b> 德鲁伊环境配置
特点
Druid 是目前比较流行高性能的,分布式列存储<br>一、亚秒级查询<br>二、实时数据注入<br>三、可扩展的PB级存储<br>四、多环境部署<br>五、丰富的社区
导入jar包:<font color="#31a8e0"><b>druid-1.1.5.jar</b></font>
链接:https://pan.baidu.com/s/1f0pl7CnEJ5vNkWGFS3kdrg<br>提取码:05wc<br>
配置文件:<b>database.properties</b>
<b>DBPoolUtils.java</b>
<font color="#f15a23">Service</font>业务(Biz/Business)
概念:用户要完成的一个业务功能,是由一个或多个的DAO调用组成。<br>软件、程序提供的一个功能都叫业务
UserInfoServiceImpl.java Demo
<b><font color="#f15a23">ThreadLocal</font></b> 类解决转账事务
简介
ThreadLocal 可以绑定<font color="#c41230">当前线程</font>与<font color="#c41230">1个泛型</font>对象的键值对的对象。<br>常用方法:<br>1. public void <font color="#f15a23">set</font>(T value); // 设置当前线程绑定的对象<br>2. public T <font color="#f15a23">get</font>(); // 返回当前线程绑定的对象<br>3. public void <font color="#f15a23">remove</font>(); // 移除当前线程的绑定对象
转账基本流程
1. 验证 fromAccount 是否存在<br>2. 验证 fromAccount 是否密码正确<br>3. 验证当前账户余额是否充足<br>4. 验证 toAccount 是否存在<br>5. 减少 fromAccount 的余额<br>6. 增加 toAccount 的余额<br>
线程<font color="#c41230"><b>绑定</b></font>连接
// 创建对象:<b><font color="#c41230">当前线程绑定1个 Connection 类型对象</font></b><br> private static final ThreadLocal<<font color="#0076b3">Connection</font>> <b><i><font color="#662c90">THREAD_LOCAL</font></i></b> = <b><font color="#f15a23">new</font></b> <font color="#f15a23">ThreadLocal</font><>();
// 当前线程从 ThreadLocal 里取,DBUtils.getConnection()<br>Connection connection = <b><i><font color="#662c90">THREAD_LOCAL</font></i></b>.<font color="#f15a23">get</font>(); // 默认 get 到的是 null<br>if (connection == null) { // 如果为空<br> connection = DriverManager.getConnection(...); // properties获取三参<br> <b><i><font color="#662c90">THREAD_LOCAL</font></i></b>.<font color="#f15a23">set</font>(connection);<br>}<br>
// 关闭连接资源,同时移除 ThreadLocal 对象,DBUtils.closeAll(c, s, r)<br>if (connection != null) {<br> connection.close();<br> <b><i><font color="#662c90">THREAD_LOCAL</font></i></b>.<font color="#f15a23">remove</font>(); // 最后关闭 connection 的时候移除线程对象<br>}<br><br>// 调用时机:事务完成后的 <b><font color="#c41230">finally</font></b> 中(<font color="#c41230">DAO层不关闭 connection</font>)<br>DBUtils.closeAll(connection, null, null);<br>
转账<b><font color="#c41230">事务</font></b>核心
Connection connection = null;
// ① 建立了一个数据库连接(线程已绑定)<br>connection = DBUtils.<i><font color="#662c90">getConnection</font></i>();
// ② 开启事务:关闭自动提交<br>connection.<b><font color="#f15a23">setAutoCommit</font></b>(<font color="#c41230">false</font>);
/* ... 业务中的原子操作,如转账中的余额扣除、余额增加 ... */
// ③ 提交事务:执行到这里无异常<br>connection.<b><font color="#f15a23">commit</font></b>();
} catch (...) {<br> // ④ 回滚事务:如果出现了异常<br> if (connection != null) {<br> connection.<b><font color="#f15a23">rollback</font></b>();<br> }<br>} finally {<br> DBUtils.closeAll(<font color="#c41230">connection</font>, null, null);<br>}
普适性泛型工具类
封装DML方法:public int commonsUpdate(String sql, Object... args)
封装DQL方法:public List<T> commonsSelect(String sql, RowMapper<T> rowMapper, Object... args)
三层架构设计
表示层
<font color="#31a8e0">view/</font>
c: TestXxxxView
命名:xxxVIew<br>职责:收集用户的数据和需求、展示数据
业务层
<font color="#31a8e0">service/</font>
<font color="#c41230">i: XxxxService</font>
<font color="#31a8e0">impl/</font>
c: XxxxServiceImpl
命名:XXXServiceImpl<br>职责:数据的加工处理、调用Dao组合完成业务实现、控制事务
DAO层
<font color="#31a8e0">dao/</font>
<font color="#c41230">i: XxxxDao</font><br>
<font color="#31a8e0">impl/</font>
c: XxxxDaoImpl
命名:xxxDaoImpl<br>职责:向业务层提供数据,将业务层加工处理后的数据同步到数据库
实体类
<font color="#31a8e0">entity/</font>
c: Xxxx
工具类
<font color="#31a8e0">utils/</font>
c: DBUtils
c: DateUtils
Apache的DBUtils
介绍
Commons DbUtils 是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,<br>使用它能勾简化JDBC应用程序的开发!同时,不会影响程序的性能。
DbUtils是Java编程中数据库操作实用小工具,小巧、简单、实用。<br>对于数据表的查询操作,可以吧结果转换为List、Array、Set等集合。<br>便于操作对于数据表的DML操作,也变得很简单(只需要写SQL语句)。
接口/类
<b><font color="#f15a23">ResultSetHandler </font></b>接口:转换类型接口<br> <b><font color="#f15a23">BeanHandler </font></b>类:实现类,把一条记录转换成对象<br> <b><font color="#f15a23">BeanListHandler </font></b>类:实现类,把多条记录转换成List集合。<br> <b><font color="#f15a23">ScalarHandler </font></b>类:实现类,适合获取一行一列的数据。
<b><font color="#f15a23">QueryRunner</font></b>:执行sql语句的类<br> 增、删、改:<font color="#f15a23">update</font>();<br> 查询:<font color="#f15a23">query</font>();
使用步骤
<b>①</b> jar包:<b>mysql-connector-java-5.1.25-bin.jar</b><br><b>②</b> jar包:<b>druid-1.1.5.jar</b><br><b>③</b> jar包:<b>commons-dbutils-1.6.jar</b><br><b>④</b> database.properties配置文件<br>
开发步骤
// DBUtils中静态属性:null<br>private static <b><font color="#c41230">DruidDataSource</font></b> <b style=""><font color="#662c90">dataSource</font></b> = null;
// DBUtils中静态代码块:创建<font color="#c41230"><b>Druid</b></font>德鲁伊 dataSource 连接池对象<br>static {<br> // ... database.properties<br> <b style=""><font color="#662c90">dataSource</font></b> = (<font color="#c41230"><b>DruidDataSource</b></font>) <b><font color="#f15a23">DruidDataSourceFactory</font></b>.<font color="#f15a23">createDataSource</font>(properties);<br>}
// DBUtils中静态方法:返回一个数据源<br> public static DataSource getDataSource() {<br> return <b style=""><font color="#662c90">dataSource</font></b>;<br>}
// DAO实现类中调用方式<br>// 1.创建 QueryRunner 对象,并传递一个数据源对象<br>private <b><font color="#f15a23">QueryRunner</font></b> <font color="#c41230">queryRunner</font> = new <b><font color="#f15a23">QueryRunner</font></b>(<b>DBUtils</b>.<i><font color="#662c90"><b>getDataSource</b></font></i>());<br>// 2.使用 queryRunner 对象,DML-增删改使用 .update(); DQL-查询使用 .query();<br>Object[] <font color="#0076b3">params</font> = {xxx.getXx()...}; // 对应占位符获取值<br>return queryRunner.<font color="#f15a23">update</font>("insert into xxx(yyy...) values(?,?,?...)", <font color="#0076b3">params</font>);<br>return queryRunner.<font color="#f15a23">query</font>("select * from xxx where id = ?", <b>new <font color="#f15a23">BeanHandler</font><[Xxx]>(Xxx.<font color="#c41230">class</font>)</b>, <font color="#0076b3">id</font>);<br>return queryRunner.<font color="#f15a23">query</font>("select * from user", <b>new <font color="#f15a23">Bean</font><font color="#c41230">List</font><font color="#f15a23">Handler</font><[Xxx]>(Xxx.<font color="#c41230">class</font>)</b>);<br>
Demo
DBUtils.java
<b><font color="#c41230">ThreadLocal 线程绑定当前使用的线程池中 connection 对象,<br>即可正确对事务进行开启、提交、回滚时操作的是同一个数据库连接!</font></b>
XxxxDaoImpl<br>
database.properties
# 数据库配置<br><b>driver</b>=com.mysql.jdbc.Driver<br><b>url</b>=jdbc:mysql://localhost:3306/<b style=""><font color="#c41230">account</font></b>?useUnicode=true&characterEncoding=utf8<br><b>username</b>=<font color="#c41230"><b>root</b></font><br><b>password</b>=<font color="#c41230"><b>123456</b></font><br># 初始化连接数<br><b>initialSize</b>=10<br># 最大连接数<br><b>maxActive</b>=30<br># 最小空闲连接数<br><b>minIdle</b>=5<br># 超时等待时间,单位:毫秒ms<br><b>maxWait</b>=5000
druid配置文件
database.properties
# 数据库配置<br><b>driver</b>=com.mysql.jdbc.Driver<br><b>url</b>=jdbc:mysql://localhost:3306/<b style=""><font color="#c41230">db</font></b>?useUnicode=true&characterEncoding=utf8<br><b>username</b>=<font color="#c41230"><b>root</b></font><br><b>password</b>=<font color="#c41230"><b>123456</b></font><br># 初始化连接数<br><b>initialSize</b>=10<br># 最大连接数<br><b>maxActive</b>=30<br># 最小空闲连接数<br><b>minIdle</b>=5<br># 超时等待时间,单位:毫秒ms<br><b>maxWait</b>=5000
c3p0配置文件
c3p0.properties
# 数据库配置<br><b>c3p0.driverClass</b>=com.mysql.jdbc.Driver<br><b>c3p0.jdbcUrl</b>=jdbc:mysql://localhost:3306/<b><font color="#c41230">db</font></b><br><b>c3p0.user</b>=<font color="#c41230"><b>root</b></font><br><b>c3p0.password</b>=<b><font color="#c41230">123456</font></b><br>
<font color="#000000">HTML</font>
简介
概述:HTML,Hyper Text Markup Language(超文本标记语言)<br>浏览器解析HTML标记的内容
特点:简易性、可扩展性、平台无关性、通用性
发展:HTML2.0 >> 3.2 >> 4.0 >> 4.01 >> 5
基本结构
<!DOCTYPE html> <!-- 文档声明,告诉浏览器使用html解析 --><br><html> <!-- 页面标记 --><br> <head> <!-- 网页头部 --><br> <meta charset="utf-8" /> <!-- 字符集编码 --><br> <title>我的页面</title> <!-- 页面标签标题 --><br> </head><br> <body> <!-- 网页主体,显示的部分 --><br> 第一个页面!<br> </body><br></html>
1. HTML页面包含头部 head 和主体 body<br>2. HTML标签通常成对出现,有开始标签、结束标签称为 对标签;没有结束标签的为 空标签<br>3. HTML标签都有属性,格式:属性名="属性值" (多个属性名用空格间隔)<br>4. HTML不区分大小写,建议小写<br>5. HTML文件后缀名为 .html / .htm
基本标签
结构标签
根
<html> </html>
头
<head> </head>
标题
<b><title> </title></b> <font color="#5c5c5c">在头标签中</font><br>
元信息
<b style="color: rgb(241, 90, 35);"><meta </b><font color="#5c5c5c">charset="utf8"</font><b style="color: rgb(241, 90, 35);">></b> 在头标签中
主体
<body> </body>
属性
<b>color</b>="颜色"<br><b>bgcolor</b>="背景色"<br><b>background</b>="背景图路径"<br>颜色表示方式:① 颜色名称 red green ② RGB模式 #000000 #FFFFFF
排版标签
注释
<!-- 注释文本 -->
换行
<br />
段落<br>
<b><p> </p></b> <font color="#5c5c5c">自带换行,有行间距</font>
属性
<b>align</b>="文本对齐方式 left 默认、center、right"
水平线
<hr />
属性
<b>width="</b>宽度" 像素px / 百分比%<br><b>size</b>="高度" 水平线的粗细,避免过粗,一般个位数,eg:6px<br><b>color=</b>"水平线颜色"<br><b>align</b>="对齐方式 left、center默认、right"<br>
标题标签
<b><h1></b><font color="#5c5c5c">一级标题</font><b></h1></b> <font color="#5c5c5c">数字越小</font><br><b><h2></b><font color="#5c5c5c">二级标题</font><b></h2></b> <font color="#5c5c5c">字号越大</font><br><b><h3></b><font color="#5c5c5c">三级标题</font><b></h3></b> <font color="#5c5c5c">默认加粗</font><br><b><h4></b><font color="#5c5c5c">四级标题</font><b></h4></b> <font color="#5c5c5c">默认字号</font><br><b><h5></b><font color="#5c5c5c">五级标题</font><b></h5></b> <font color="#5c5c5c">默认占据一行</font><br><b><h6></b><font color="#5c5c5c">六级标题</font><b></h6></b> <font color="#5c5c5c">默认有行间距</font>
容器标签
块标签
<b><font color="#f15a23"><div> </div></font></b> 独占一行,自带换行<br>默认宽度为浏览器部分宽度,高度会跟随元素内的文本内容而改变<br>应用:<font color="#c41230">结合css做页面分块,布局</font>
行级标签
<b><font color="#f15a23"><span> </span></font></b> 所有内容都在同一行<br>默认宽度和高度都会随着内容改变<br>应用:<font color="#c41230">友好提示信息的显示</font>
列表标签
无序列表
<font color="#f15a23"><b><ul></b><br> <li> </li><br> <li> </li><br> <li> </li><br><b></ul></b></font>
<b>type</b>="?"<br>实心圆:disc (默认)<br>空心圆:circle<br>黑色方块:square
有序列表
<font color="#f15a23"><b><ol></b><br> <li> </li><br> <li> </li><br> <li> </li><br><b></ol></b></font>
<b>type</b>="?"<br>数字:1<br>大小写字母:A / a<br>罗马数字:I / i
定义列表
<b style="color: rgb(241, 90, 35);"><dl> </b><font color="#5c5c5c">列表</font><br><b style="color: rgb(241, 90, 35);"> <dt></b><font color="#5c5c5c">Coffee</font><b style="color: rgb(241, 90, 35);"></dt> </b><font color="#5c5c5c">标题</font><br><b style="color: rgb(241, 90, 35);"> <dd></b><font color="#5c5c5c">Black hot drink</font><b style="color: rgb(241, 90, 35);"></dd> </b><font color="#5c5c5c">内容</font><br><b style="color: rgb(241, 90, 35);"> <dt></b><font color="#5c5c5c">Milk</font><b style="color: rgb(241, 90, 35);"></dt></b><br><b style="color: rgb(241, 90, 35);"> <dd></b><font color="#5c5c5c">White cold drink</font><b style="color: rgb(241, 90, 35);"></dd></b><br><b style="color: rgb(241, 90, 35);"></dl></b>
列表嵌套
可以相互任意嵌套
图片标签
<b><img /></b>
属性
<b>src</b>="图片地址"<br><b>height</b>="高度"<br><b>width</b>="宽度"<br><b>border</b>="边框"<br><b>alt</b>="图片未被加载时的提示文字"<br><b>title</b>="图片被鼠标悬停时的提示文字"
链接标签
<b style="color: rgb(241, 90, 35);"><a> </b><font color="#5c5c5c">文本或图片</font><b style="color: rgb(241, 90, 35);"> </a></b>
属性
<b>href</b>="跳转的地址" // 跳转外网需要添加协议http/https<br><b>target</b>="_self"(当前页) "_blank"(一直新页面) "_search"(仅1个新页面复用)
<b><font color="#f15a23">充当锚点</font></b>(跳转顶部/跳转底部)<br>提供率 name 属性,为其赋值<br>点击跳转的标签 href 属性给 #name<br><a <b>name</b>="tops"></a><br><a <b>href</b>="<font color="#f15a23">#</font>tops">跳到顶部</a>
表格标签
<b style="color: rgb(241, 90, 35);"><table </b><font style="" color="#5c5c5c">border="1"</font><b style="color: rgb(241, 90, 35);">> </b><font color="#5c5c5c">表格</font><br><b style="color: rgb(241, 90, 35);"> <tr></b><br><b style="color: rgb(241, 90, 35);"> <th></b><font color="#5c5c5c"><b>header</b></font><b style="color: rgb(241, 90, 35);"></th></b><br><b style="color: rgb(241, 90, 35);"> <th></b><font color="#5c5c5c"><b>header</b></font><b style="color: rgb(241, 90, 35);"></th></b><br><b style="color: rgb(241, 90, 35);"> </tr></b><br><b style="color: rgb(241, 90, 35);"> <tr></b><br><b style="color: rgb(241, 90, 35);"> <td></b><font color="#5c5c5c">row 2, cell 1</font><b style="color: rgb(241, 90, 35);"></td></b><br><b style="color: rgb(241, 90, 35);"> <td></b><font color="#5c5c5c">row 2, cell 2</font><b style="color: rgb(241, 90, 35);"></td></b><br><b style="color: rgb(241, 90, 35);"> </tr></b><br><b style="color: rgb(241, 90, 35);"></table></b><br>
属性
table
<b>width</b>="表格宽度"<br><b>height</b>="表格高度"<br><b>border</b>="边框宽度"<br><b>bordercolor</b>="边框颜色"<br><b>cellspacing</b>="单元格之间的间距"<br><b>cellpadding</b>="单元格与内容的间距"<br><b>align</b>="对齐方式 left center right" 表格相对于页面
th
表头,默认加粗、居中
td
<b>align</b>="对齐方式 left center right" 内容相对于单元格<br><b>valign</b>="对齐方式 top middle bottom" 内容相对于单元格
列合并
<b>colspan</b>="横跨的列数"
行合并
<b>rowspan</b>="纵跨的行数"
文本标签
<font color="#5c5c5c">普通的文字是这样</font><b style="color: rgb(241, 90, 35);"><br><b></b><b style=""><font color="#5c5c5c">b 粗体文字</font></b><b style="color: rgb(241, 90, 35);"></b><br><strong></b><b style=""><font color="#5c5c5c">strong 加重文字</font></b><b style="color: rgb(241, 90, 35);"></strong><br><big></b><font color="#5c5c5c">big 大号文字</font><b style="color: rgb(241, 90, 35);"></big><br><small></b><font color="#5c5c5c">small 小号文字</font><b style="color: rgb(241, 90, 35);"></small></b><br><b style="color: rgb(241, 90, 35);"><em></b><i style=""><font color="#5c5c5c">em 着重文字</font></i><b style="color: rgb(241, 90, 35);"></em></b><br><b style="color: rgb(241, 90, 35);"><i></b><font color="#5c5c5c"><i style="">i</i><i style=""> 斜体文字</i></font><b style="color: rgb(241, 90, 35);"></i></b><br><font color="#5c5c5c">sub 下标文字:CO</font><b style="color: rgb(241, 90, 35);"><sub></b><font color="#5c5c5c">2</font><b style="color: rgb(241, 90, 35);"></sub></b><br><font color="#5c5c5c">sup 上标文字:注解</font><b style="color: rgb(241, 90, 35);"><sup></b><font color="#5c5c5c">[1]</font><b style="color: rgb(241, 90, 35);"></sup></b><br><b style="color: rgb(241, 90, 35);"><ins></b><u style=""><font color="#5c5c5c">ins 插入文字</font></u><b style="color: rgb(241, 90, 35);"></ins></b><br><b style="color: rgb(241, 90, 35);"><del></b><strike style=""><font color="#5c5c5c">del 删除文字</font></strike><b style="color: rgb(241, 90, 35);"></del></b>
表单标签
定义标签
<b><font color="#f15a23"><form> </form></font></b>
HTML表单用于搜集不同类型的用户输入信息。
输入标签
<b><font color="#f15a23"><input /></font></b>
表单元素:<br><span style="font-size: inherit;">type 不同的输入方式</span><br><span style="font-size: inherit;">name 用于<font color="#c41230"><b>拼接到链接地址提交到服务器</b></font>,格式:</span>name1=value1<b><font color="#f15a23">&</font></b>name2=value2<br><span style="font-size: inherit;">value 默认值</span><br><span style="font-size: inherit;">checked 单选选中</span><br><span style="font-size: inherit;">selected 多选选中</span><br>
登陆界面
<ul><li>账户:<input type="<b>text</b>" <b>name</b>="username" <b>placeholder</b>="请输入账户" /><br></li><li>密码:<input type="password" name="password" placeholder="请输入密码" /><br></li><li><span style="font-size: inherit;">性别:</span></li></ul><span style="font-size: inherit;"> <input type="radio" name="sex" value="male" checked="checked" />男</span><br style="font-size: inherit;"><span style="font-size: inherit;"> <input type="radio" name="sex" value="female" />女</span><br style="font-size: inherit;"><ul><li><span style="font-size: inherit;">照片:type="file"</span></li><li><span style="font-size: inherit;">地址:<select name="city"></span></li></ul><span style="font-size: inherit;"> <option value="zz">郑州</option></span><br style="font-size: inherit;"><span style="font-size: inherit;"> <option value="zz" selected="selected">南阳</option></span><br style="font-size: inherit;"><span style="font-size: inherit;"> </select></span><br style="font-size: inherit;"><ul><li><span style="font-size: inherit;">爱好:</span></li></ul><span style="font-size: inherit;"> <input type="checkbox" name="hobbys" value="basketball" checked="checked" />篮球</span><br style="font-size: inherit;"><span style="font-size: inherit;"> <input type="checkbox" name="hobbys" value="football" checked="checked" />足球</span><br style="font-size: inherit;"><span style="font-size: inherit;"> <input type="checkbox" name="hobbys" value="volleyball" checked="checked" />排球</span><br style="font-size: inherit;"><ul><li><span style="font-size: inherit;">介绍:<textarea name="introduce"></textarea></span></li><li><span style="font-size: inherit;">提交:<br><input type="submit" name="submit" value="注册" /><br><button type="submit">注册</button></span></li><li><span style="font-size: inherit;">清空:<br><input type="reset" name="reset" id="" value="清空" /><br><button type="reset">清空</button></span></li></ul><br>
框架标签
<b><font color="#f15a23"><frameset> </frameset></font></b> // 代替body标签<br><b><font color="#f15a23"><frame> </frame></font></b> // 分割页面的内容,在frameset中
属性
frameset属性:<br><ul><li><b>row</b>="20%,*" 横向20%+80%</li><li><b>cols</b>="50%,*" 纵向50%+50%</li></ul><br>
frame属性:<br><ul><li><b>src</b>="填充的内容"</li><li><b> noresize</b>="noresize" 不能改变大小</li><li><b> scrolling</b>="no" 不显示滚动条</li><li>定位到具体位置使用 name 属性</li></ul>
Demo
其他标签
标签
<!-- 网页的编码 --><br><<b><font color="#f15a23">meta</font></b> <b>charset</b>="utf-8"><br><!-- 网页的编码:html 4.01 --><br><meta <b>http-equiv</b>="<font color="#f15a23">content-type</font>" <b>content</b>="text/html; charset=utf-8"/><br><!-- 网页的关键字 seo --><br><meta name="<font color="#f15a23" style="">keywords</font>" <b>content</b>="关键词1,关键词2,关键词3"/><br><!-- 网页的描述 seo --><br><meta name="<font color="#f15a23" style="">description</font>" <b>content</b>="this is my page"/><br><!-- 页面自动跳转,2秒后跳转百度 --><br><meta <b>http-equiv</b>="<font color="#f15a23">refresh</font>" <b>content</b>="2;url=https://www.baidu.com"/><br><!-- href: 引入css文件地址 --><br><<b><font color="#f15a23">link</font></b> <b>rel</b>="stylesheet" <b>type</b>="text/css" <b>href</b>="css/01CSS.css"/><br><!-- src: js文件地址 --><br><<b><font color="#f15a23">script</font></b> <b>src</b>="js文件地址" <b>type</b>="text/javascript"></script>
符号
<ul><li>&lt; 小于号 <</li><li>&gt; 大于号 ></li><li>&amp; 与字符 &</li><li>&quot; 引号 "</li><li>&reg; 已注册 ®</li><li>&copy; 版权©</li><li>&trade; 商标™</li><li>&nbsp; 空格<br>&yen; 人民币 ¥</li></ul>
<font color="#000000">CSS</font>
标签/属性
<style><br> <font color="#f15a23">选择器</font>{<br> 属性名:属性值;<br> }<br></style>
<xxx <b>style</b>="aaa:AAA; bbb:BBB;">
CSS使用方式
内联方式
<font style="color: red;">这是一行字</font>
标签内,单独对特定标签元素生效,简单,但不能复用。<br>
内部方式
<style type="text/css"><br> font{<br> font-size: 50px;<br> color: darkblue;<br> }<br> a{ text-decoration:none }<br></style><br><b></head></b>
<ol><li>在 head 标签中,使用 style 标签</li><li>使用选择器选中元素</li><li>编写 css 代码</li></ol>
外部方式
<link rel="stylesheet" type="text/css" href="<font color="#0076b3"><b>./css/01CSS.css</b></font>"/>
<ol><li>新建一个 css 样式文件</li><li>编写 css 代码</li><li>在 html 文件中引入 css 外部文件,使用 link 标签引入</li></ol>
CSS选择器
标签选择器
<font color="#f15a23">标签名</font>{<br> 属性名:属性值;<br>}<br>
body全局样式:标签名使用body
id选择器
<b>id</b>="aaa"
<font color="#f15a23">#id选择器</font>{<br> 属性名:属性值;<br>}<br>
类选择器
<b>class</b>="aaa"
<font color="#f15a23">.类选择器</font>{<br> 属性名:属性值;<br>}<br>
属性选择器
<font color="#f15a23">标签名[属性名]</font>{<br> 属性名:属性值;<br>}<br>
<font color="#f15a23">标签名[属性名="值"]</font>{<br> 属性名:属性值;<br>}<br>
eg:<br>a[href<b><font color="#f15a23">^</font></b>="http"] { 样式 } 以http开头的<br>a[href<b><font color="#f15a23">$</font></b>="cn"] { 样式 } 以cn结尾的<br>a[href<b><font color="#f15a23">*</font></b>="u"] { 样式 } 包含了字符u的<br>
层级选择器
<font color="#f15a23" style="font-weight: bold;">父选择器 子选择器</font><b>{</b><br><b> 属性名:属性值;</b><br><b>}</b><br>//【后代】会跨子标签层级
<b><font color="#f15a23">父选择器>子选择器</font>{<br> 属性名:属性值;<br>}<br></b>// 【子代】亲儿子不跨标签层级
<b><font color="#f15a23">A选择器+B选择器</font>{<br> 属性名:属性值;<br>}<br></b>// 【相邻兄弟】自身之后的1个兄弟标签
<b><font color="#f15a23">A选择器~B选择器</font>{<br> 属性名:属性值;<br>}<br></b>// 【通用兄弟】自身之后的所有兄弟标签
在结构中有标签包裹父子/相邻层级关系时使用。
分组选择器
<font color="#f15a23">#id选择器, .类选择器, 标签名</font>{<br> 属性名:属性值;<br>}<br>
逗号分隔不同的选择器,将这些划分为一组,使用共同的样式
不同的选择器不同的样式做修改,样式会叠加。<br>不同的选择器相同的样式做修改,遵循优先级:<br>优先级(范围越小优先级越高):<b><font color="#f15a23">内联样式</font></b> > <b><font color="#f1753f">id</font></b> > <b><font color="#f68b1f">class</font></b> > <b><font color="#fdb813">标签</font></b>
CSS伪类
用于向某些选择器添加特殊的效果。
锚伪类
<ul><li>* 主要用于 a 标签上<br>a<b><font color="#f15a23">:link</font></b> {color: #FF0000} /* 未访问的链接样式 */</li><li>a<b><font color="#f15a23">:visited</font></b> {color: #00FF00} /* 已访问的链接样式 */</li><li>a<b><font color="#f15a23">:hover</font></b> {color: #FF00FF} /* 鼠标移动到标签内容上 */</li><li>a<b><font color="#f15a23">:active</font></b> {color: #0000FF} /* 选定时标签内容样式 */</li></ul>
注意:在 CSS 定义中,<font color="#c41230">a:hover 必须被置于 a:link 和 a:visited 之后</font>,才是有效的。<br>注意:在 CSS 定义中,<font color="#c41230">a:active 必须被置于 a:hover 之后</font>,才是有效的。<br>注意:伪类名称对大小写不敏感。
CSS属性
字体
定义文本的字体系列、大小、加粗、风格(如斜体)和变形(如小型大写字母)
属性
<ul><li><b style=""><font color="#000000">font</font></b> 简写属性。作用是把所有针对字体的属性设置在一个声明中。eg:<b>font</b>:oblique 700 30px "黑体"; /* 样式 加粗 大小 风格 */</li><li><b>font-family</b> 设置字体系列。</li><li><b>font-size</b> 设置字体的尺寸。</li><li><b>font-style</b> 设置字体风格。(斜体)</li><li><b style="font-size: inherit;">font-weight</b><span style="font-size: inherit;"> 设置字体的粗细。</span><br></li></ul>
文本
改变文本的颜色、字符间距,对齐文本,装饰文本,对文本进行缩进,等等
属性
<ul><li><b><font color="#000000">color</font></b> 设置文本颜色</li><li><b>direction</b> 设置文本方向。</li><li><b>line-height</b> 设置行高。</li><li><b>text-align</b> 对齐元素中的文本。(左对齐、居中、右对齐)</li><li><b>text-decoration</b> 向文本添加修饰。(上划线、下划线、删除线、无线条)</li><li><b>text-indent</b> 缩进元素中文本的首行(2em : 2个字符;20% : 20%的宽度)</li><li><b>text-transform</b> 控制元素中的字母。(全大写、全小写、所有单词首字母大写)</li><li><b>unicode-bidi</b> 设置文本方向。</li><li><b style="font-size: inherit;">white-space</b><span style="font-size: inherit;"> 设置元素中空白的处理方式。(="nowrap" 禁止文本分行,即都在1行内)</span></li><li><span style="font-size: inherit;"><b>letter-spacing</b> 设置字符间距。</span></li><li><b>word-spacing</b> 设置单词间距。</li></ul>
背景
<ul><li><b>background-color</b>:设置背景颜色,默认透明</li><li><b>background-image:url("图片路径");</b>设置背景图片<br><b>background-size</b>: 设置背景图片的尺寸属性</li><li><b>background-repeat</b>:</li></ul> repeat-y:只在垂直方向都平铺<br> repeat-x:只在水平方向都平铺<br> repeat:在水平垂直方向都平铺<br> no-repeat:任何方向都不平铺<br><ul><li><b>background-position</b>: 改变图像在背景中的位置。top、bottom、left、right 和 center(1个位置值或多个组合位置值)</li></ul>/*简写 没有顺序*/<br><b><font color="#f15a23">background</font></b>: red center no-repeat url(img/003.jpg); <br>
列表
<ul><li><b>list-style-type</b>:decimal;改变列表的标志类型</li><li><b>list-style-image</b>: url("images/dog.gif");用图像表示标志</li><li><b>list-style-position</b>: inside;确定标志出现在列表项内容之外还是内容内部 </li></ul>简写<br>list-style: decimal url(img/001.png) inside;<br>去掉样式:<br>list-style:none;<br>list-style-type:none;
显示
<ul><li><span style="font-size: inherit;"><b>display</b>: </span></li></ul><span style="font-size: inherit;"> none 不显示</span><br> <b><font color="#f15a23">block</font></b> 块级元素<br> <b><font color="#f15a23">inline</font></b> 行内元素<br> <b><font color="#f15a23">inline-block</font></b> 行内块级元素<br><br><ul><li><font style=""><b>display:</b></font><font color="#f15a23" style="font-weight: bold;">flex</font> 伸缩布局:</li></ul><b><font color="#f15a23"> flex-direction</font></b>:row/column 主轴方向<br> <b><font color="#f15a23">align-items</font></b>: center; 垂直居中<br> <b><font color="#f15a23"> justify-content</font></b>: center; 水平居中
轮廓
轮廓(outline)<br>绘制于元素周围的一条线,位于边框边缘的外围,可起到突出元素的作用。常用属性:<br><ul><li><b>outline-style</b>:</li></ul> solid(实线) dotted(虚线) dashed(虚线的每段较长) double(框为空心); 设置轮廓的样式<br><ul><li><b>outline-color</b>:red; 设置轮廓的颜色</li><li><b>outline-width</b>:10px 设置轮廓的宽度</li></ul>
浮动
<ul><li><b>float</b>="?"</li></ul>left 左浮动 right 右浮动 none 不浮动 inherit 继承父元素<br>* 浮动起来的元素会遮盖没有浮动属性的元素
<ul><li><b>clear</b>="?"</li></ul>left 左侧不允许浮动元素<br>right 右侧不允许浮动元素<br>both 左右两侧均不允许浮动元素<br>none 默认,允许浮动元素出现在两侧<br>inherit 继承父元素<br>
定位
<ul><li><b>position</b>: </li></ul> static(默认)<br> <b><font color="#f15a23">relative</font></b>(相对定位) <b><font color="#c41230">相对自身原来的位置偏移某个距离,原本所占的空间仍然保留。</font></b><br> <b><font color="#f15a23">absolute</font></b>(绝对定位) <b><font color="#c41230">相对于已定位的父元素进行偏移某个距离</font></b>,<b><font color="#c41230">不保留原空间</font></b>。(如无已定位的父元素则相对于浏览器)<br> fixed(固定定位) 固定加载位置,不会因为滚动而变化位置<br><b>left</b> - 相对浏览器左边<br><b>right</b> - 相对浏览器右边<br><b>top</b> - 相对浏览器顶端<br><b>bottom</b> - 相对浏览器底端
注意:body有默认的margin(<font color="#c41230">8</font>px)
CSS盒子
尺寸
<ul><li><b>width</b>:设置元素的宽度</li><li><span style="font-size: inherit;"><b>height</b>:设置元素的高度</span></li><li><span style="font-size: inherit;"><b>line-height</b>:设置元素的行高</span></li></ul>
边框<br>
<font style="font-size: inherit;"><b style=""><font color="#f15a23">border</font></b><br><ul style="color: rgb(92, 92, 92);"><li><font color="#5c5c5c" style="font-size: inherit;">border-style</font><span style="font-size: inherit;">:边框样式,值有以下情况:</span></li></ul></font> solid:实线<br> double:空心线<br> dashed:虚线组成的边框<br> dotted:圆点组成的边框<br><ul><li><b>border-color</b>:边框颜色</li><li><b>border-width</b>:边框宽度</li></ul>简写<br>border: 1px solid red;<br>
外边距
<ul><li><b><font color="#f15a23">margin</font></b>:外间距,<font color="#c41230">边框和边框外层元素的距离</font></li></ul> 四个方向的距离(top right bottom left)<br> margin-top:像素值px;<br> margin-bottom:像素值px;<br> margin-left:像素值px;<br> margin-right:像素值px;
内边距
<ul><li><b><font color="#f15a23">padding</font></b>:内间距,元素内容和边框之间的距离((top right bottom left)) </li></ul> padding-left:像素值px;<br> padding-right:像素值px;<br> padding-top:像素值px;<br> padding-bottom:像素值px;
实际
盒子模型的实际的宽度:width+2*(padding+border+margin)<br>盒子模型的实际的高度:height+2*(padding+border+margin)
CSS3扩展属性
圆角
<b>border-radius</b>:50%; //圆角半径<br><font color="#c41230">可以将正方形图片切为圆形</font>。<br>
阴影
相对于自身原来的位置偏移x,y像素值 模糊半径值 颜色值<br><b>box-shadow</b>:10px 10px 5px #888888; //方框阴影属性<br><b>text-shadow</b>:5px 5px 5px #ffff00; //文本阴影属性<br>
背景图片尺寸
<body style="text-align: center;<br> <b>background</b>:url(img/1.png);<br> <b>background-size</b>: 200px 300px;<br> <b>background-repeat</b>: no-repeat;"><br><span style="font-size: inherit;"></body> //背景图片尺寸,不平铺</span><br>
多个背景图片
<b>background-image</b>:url(bg_flower.gif),url(bg_flower_2.gif);
<b>Tomcat</b>
基本概念
C/S模式:Client/Server模式(客户端/服务器)【优】客户端分担了负载【劣】新功能必须需要重新下载<br>B/S模式:<b>Browser/Server</b>模式(<font color="#c41230">浏览器/服务器</font>) 【优】使用简单只需要浏览器【劣】负载都交给了服务器
Tomcat,是Apache-Jarkarta开源项目中的一个子项目,<font color="#c41230">小型、轻量级的支持JSP和Servlet技术的web服务器</font>。<br>最新的Servlet和JSP规范因为有 Sun 公司的参与和支持总能得到体现,<font color="#c41230">技术先进、性能稳定、免费</font>!
web动态项目比web静态项目区别:<br><b><font color="#c41230">动态资源</font></b>中可以有静态资源,可以有动态资源,<font color="#c41230">必须有 </font><font color="#0076b3">WEB_INF 目录 </font><font color="#c41230">和 </font><font color="#0076b3">WEB_INF/web.xml </font><font color="#c41230">文件</font>。
<b>Tomcat配置</b>
<b>Tomcat服务器搭建</b>
安装
1.官网下载 <font color="#0076b3"><b>tomcat.apache.org</b></font> Tomcat8.0|8.5版本<br>2.解压到一个没有特殊符号的路径<br>3.进入到解压的目录下,bin\startup.bat启动<br>* 不要放入层次多的文件夹中、不建议放中文路径、依赖JAVA_HOME环境变量。
目录
<ul><li><b>bin</b> 二进制可执行文件和启动脚本文件</li><li><b>conf</b> 配置目录:</li></ul> <font color="#f15a23">server.xml</font> 配置整个服务器的信息<br> <font color="#f15a23">tomcatusers.xml</font> 存储tomcat用户信息<br> <font color="#f15a23">web.xml</font> 部署描述符文件,注册了很多MIME即文档类型<br> <font color="#f15a23">context.xml</font> 对所有应用的统一配置,通常不配置它<br><ul><li><b>lib</b> 服务器启动以来的核心类库,jar包文件</li><li><b>logs</b> 日志文件,启动、关闭、错误、异常等信息</li><li><b>temp</b> 存放临时文件,可以在tomcat关闭后删除</li><li><b>webapps</b> 存放web项目的核心目录,其中每个文件夹都是一个项目,ROOT是未给出项目目录时的特殊项目</li><li><b>work</b> 运行时生成的文件,最终运行的文件都在这里,通过webapps中的项目生成的</li></ul>
启动
<b>bin/<font color="#f15a23">startup.bat</font></b> 启动服务器<br><b>bin/<font color="#f15a23">shutdown.bat</font></b> 关闭服务器<br>
* 中文乱码解决:logging.properties >> <font color="#c41230">注释掉line47</font> #java.util.logging.ConsoleHandler.encoding = <font color="#5c5c5c">UTF-8</font>
访问
<b>http://ip:port/<font color="#c41230">project</font>/资源</b> (静态[html/css/javascript]、动态[servlet/jsp])
浏览器访问 http://<font color="#f15a23">localhost:8080 </font><font color="#5c5c5c">或</font><font color="#f15a23"> </font><font color="#5c5c5c">http://</font><font color="#f15a23">127.0.0.1:8080<br></font>
默认访问 index.xml 或 index.jsp
原因:Tomcat目录 conf 目录下 web.xml 规定了默认欢迎页面
<<font color="#f15a23">welcome-file-list</font>><br> <<font color="#f15a23">welcome-file</font>><b>index.html</b></welcome-file><br> <welcome-file><b>index.htm</b></welcome-file><br> <welcome-file><b>index.jsp</b></welcome-file><br></welcome-file-list>
自定义的 web 项目也部署到 tomcat 中,也会遵守该规定。
常见错误
404:无法找到文件<br>500:内部服务器错误
配置
配置默认访问页
直接修改 tomcat 的 web.xml 中的 <welcome-file-list> 会影响到所有项目的欢迎页面。
在项目目录中 <b><font color="#0076b3">WEB_INF/web.xml</font></b> 中修改 <b><font color="#f15a23"><welcome-file-list></font></b> 仅针对当前项目有效。
配置端口号:<b><font color="#0076b3">conf/server.xml</font></b>
<Connector port="<font color="#f15a23">8080</font>" protocol="HTTP/1.1"<br> connectionTimeout="20000"<br> redirectPort="8443" /> //默认8080
<Connector port="<font color="#f15a23">80</font>" protocol="HTTP/1.1"<br> connectionTimeout="20000"<br> redirectPort="8443" /> //遵循浏览器默认端口可以直接用 http://localhost 访问
配置项目为默认启动项目:<b><font color="#0076b3">conf/server.xml</font></b>
重命名 ROOT 项目或删除该目录
</Host>前 新增如下内容:<br><b><Context <font color="#f15a23">docBase</font>="<font color="#c41230">磁盘绝对路径</font>" path="" debug="0" reloadable="true"/></b><br>
B/S数据流程图
<b>Tomcat项目部署</b>
直接将项目放到webapps目录<br>
直接拷贝
配置虚拟项目目录
conf/server.xml<br>
<Host><br> ...<br> <b><Context <font color="#f15a23">docBase</font>="<font color="#c41230">磁盘路径</font>" <font color="#f15a23">path</font>="<font color="#c41230">/访问名称</font>" /></b><br></Host>
访问 http://localhost:8080/<b><font color="#c41230">访问名称</font></b>/资源文件
配置虚拟项目目录优化版
<b><font color="#0076b3">conf/Catalina/localhost</font></b>
新建 <b><font color="#c41230">projname</font></b><font color="#f15a23">.xml</font>
编辑<br><?xml version="1.0" encoding="UTF-8"?><br><b><Context <font color="#f15a23">docBase</font>="<font color="#c41230">磁盘路径</font>" /></b>
访问 http://localhost:8080/<b><font color="#c41230">projname</font></b>/资源文件
<b>Tomcat在开发工具支持</b>
Eclipse中集成Tomcat
Window >> Preferences >> Server
点击add >> 选择对应的版本 >> Finish
<font color="#c41230"><b>Intellij IDEA中集成Tomcat</b></font>
<b><font color="#000000">File</font></b> >> <b><font color="#000000">Settings</font></b> >> <b><font color="#000000">build-execution-deployment</font></b> >> 选择<b><font color="#000000">Application Servers</font></b> >> 添加<b><font color="#000000">Tomcat</font></b> >> 选择<b><font color="#000000">Tomcat安装根目录</font></b><br>如:D:\tomcat\apache-tomcat-8.5.53
* 解决源码编译运行后打印中文乱码问题:Tomcat-8.5.53 >> Edit Configuration >> <b><font color="#000000">VM option</font></b>:<b><font color="#c41230">-Dfile.encoding=utf-8</font></b>
自定义Tomcat服务器
@注解<br>
注解Annotation用于描述元数据的修饰符,包括类、成员变量、构造方法、成员方法、方法参数和声明。<br>JDK5.0之后引入的特性。<br>
注解分类
类型
标记注解:注解中没有属性可以设置,如 @Override、@Deprecated<br>单值注解:注解中只有一个属性("value="可省略),如 @SuppressWarings{ String[] value; }<br>完整注解:注解中有多个属性<br>
来源
Java内置注解
<font color="#c41230"><b>@Override<br></b></font>方法覆盖注解<br>
判断子类中的方法是否是一个父类方法的重写方法
<font color="#c41230"><b>@Deprecated<br></b></font>过时标记注解<br>
标记一个类/方法/变量是否是过时的,调用时会有删除线
<font color="#c41230"><b>@SupressWarning("all")<br></b></font>压制所有警告注解<br>
可以消除编译器/开发工具对警告的提示
<b><font color="#c41230">@FunctionaInterface<br></font></b>函数式接口注解<br>
标记只能有1个公开抽象方法,用于Lambda简写
<b><font color="#c41230">@SafeVarargs<br></font></b>安全的可变参数注解
帮助检查可变参数与泛型结合时的使用情况
第三方注解
<b>Junit</b>
<b style="color: rgb(196, 18, 48);">@Test</b><br><font color="#5c5c5c">单元测试注解</font>
import <b>org.junit.Test</b>;<br>* 该注解的方法被<b><font color="#c41230">强制public</font></b>且<b><font color="#c41230">无参</font></b><br>* <font color="#c41230">可以直接运行@Test注解的方法</font>,底层还是 main 方法运行,通过(反射+@Test注解)生效。
其他待补充
<b>Servlet</b>
<b><font color="#c41230">@WebServlet</font></b><br>web资源配置注解
Servlet3.0+版本支持,可以替代web.xml配置。
(框架注解)待补充
自定义注解
@Retention(RetentionPolicy.RUNTIME)<br>public <font color="#f15a23">@interface</font> 自定义注解名 {<br> 数据类型 属性名1() default 默认值1;<br> 数据类型 属性名2() default 默认值2;<br> 数据类型 属性名3()[] default {元素值1, 元素值2, ...};<br>}
Demo
元注解
<b><font color="#c41230">定义在自定义注解上</font></b>,规定自定义的作用区域、存活策略。
<font color="#c41230"><b>@Target</b></font><br>规定自定义注解的作用区域
public @interface Target {<br> <font color="#c41230">ElementType</font>[] value();<br>}
<span style="font-size: inherit;">当前定义的注解可以应用的范围:</span><br><ul><li><span style="font-size: inherit;"><b>TYPE</b>, 类、接口、枚举的类型定义上</span></li><li><span style="font-size: inherit;"><b>FIELD</b>, 成员变量上</span></li><li><span style="font-size: inherit;"><b>METHOD</b>, 成员方法上</span></li><li><span style="font-size: inherit;"><b>PARAMETER</b>, 方法参数上</span></li><li><span style="font-size: inherit;">CONSTRUCTOR, 构造方法上</span></li><li><span style="font-size: inherit;"><b>LOCAL_VARIABLE</b>, 局部变量上</span></li><li><span style="font-size: inherit;">ANNOTATION_TYPE, 注解类型上</span></li><li><span style="font-size: inherit;">PACKAGE, 包定义语句上</span></li><li><span style="font-size: inherit;">TYPE_PARAMETER, 类型参数声明</span></li><li><span style="font-size: inherit;">TYPE_USE, 使用一个类型</span></li></ul>
<font color="#c41230"><b>@Retention</b></font><br>规定自定义注解的存活策略
public @interface Retention {<br> <font color="#c41230">RetentionPolicy</font> value();<br>}
当前定义的注解可以存活的方式:<br><ul><li>SOURCE, 仅仅停留在源码中,编译时即除去</li><li>CLASS, 保留到编译后的字节码中,运行时无法获取注解信息</li><li><b>RUNTIME</b>, <font color="#c41230">保留到运行时,通过反射机制可以获取注解信息</font></li></ul>
<b><font color="#c41230">@Documented</font></b><br>文档标记注解(无参数)<br>
将注解中的内容包含到Javadoc中。
<b><font color="#c41230">@Inherited</font></b><br>可随修饰类被继承的标记注解(无参数)<br>
例如B继承了A,A添加了注解,那么B也会继承同样的注解。
<b>获取注解信息</b>
<b>核心步骤</b>
反射机制<br>① 注解在类/方法上,获取对应的 <b><font color="#c41230">Class 对象</font></b> / <b><font color="#c41230">Method 对象</font></b><br>② 判断类/方法上的注解是否存在 <font color="#f15a23">.isAnnotationPresent</font>(注解名.class)<br>③ 获取注解信息 <font color="#f15a23">.getAnnotation</font>(注解名.class)
自定义注解@MyTest
步骤:<br>1.自定义注解<br>2.在测试类上使用该自定义注解<br>3.让自定义注解生效<br> ● 获取测试类的Class对象<br> ● 获取测试类的成员方法<br> ● 判断方法上是否有自定义注解<br> ● 执行添加了注解的方法
Demo
自定义注解@JDBCInfo
步骤:<br>1.自定义注解@JDBCInfo<br>2.在DBUtils工具类上使用@JDBCInfo<br>3.在DBUtils工具类的静态代码中获取注解中的属性(反射读取注解信息)<br>
Class<DBUtils> dbClass = DBUtils<font color="#f15a23">.class</font>;<br>boolean present = dbClass<font color="#f15a23">.isAnnotationPresent</font>(JDBCInfo.class);<br>if (present) {<br> JDBCInfo jdbcInfo = dbClass<font color="#f15a23">.getAnnotation</font>(JDBCInfo.class);<br> DRIVERCLASS = jdbcInfo<b><font color="#f15a23">.</font></b>driverClass();<br> ...<br>}
@JDBCInfo
DBUtils
TestJDBCInfo
<b>注解+反射+设计模式【日志记录】</b>
装饰者模式
装饰类中调用所有方法,并定义printLog()方法增加日志信息:<br> 1.获取UserDao实现子类的 Class 对象<br> 2.获取UserDao接口的 Class 对象<br> 3.获取到接口中对应的方法<br> 4.判断方法上是否有注解信息<br> 5.有注解,则获取注解信息<br> 6.拼接日志需要的时间和必要信息<br>
<b>动态代理模式</b>
动态代理的匿名内部类参数中定义增强日志信息的逻辑:<br> 1.检查方法上是否有对应注解<br> 2.<font color="#c41230">有注解</font>:执行原有功能,打印日志<br> 3.拼接日志需要的时间和必要信息<br> 4.<font color="#c41230">没注解</font>:执行原有功能<br>
@SysLog
UserDao接口
UserDaoImpl实现类
装饰者设计模式:UserDaoWrapper装饰类
测试类验证
动态代理设计模式:测试类 Proxy.newProxyInstance(...) 验证
xml与注解-对比
xml
优点:<br>1、降低耦合,使容易扩展<br>2、对象之间的关系一目了然<br>3、xml配置文件比注解功能齐全<br>缺点:<br>1、配置文件配置工作量相对注解要大
注解
优点:<br>1、在class文件中,可以降低维护成本<br>2、提高开发效率<br>缺点:<br>1、如果对注解文件(Annotation)进行修改,需要重新编译整个工程<br>2、业务类之间的关系不如xml配置那样一目了然<br>3、程序中过多的注解,对于代码的简洁度有一定影响<br>4、注解功能没有xml配置文件齐全
* 大多数情况下使用配置文件,Spring Boot流行起来,就流行注解配置(注解开发)。
Servlet
<b>Servlet基础</b>
概念
Servlet 一个可以执行在服务器中的Java程序。
核心作用
1. 接收客户端浏览器请求,完成操作任务<br>2. 动态生成网页(页面数据可变)<br>3. 将包含操作结果的动态网页响应给客户端浏览器
目录结构
|--webapps(存放所有网站)<br> |--MyServlet(网站)<br> |--WEB_INF(核心内容)<br> |--classes/*.class(.class文件)<br> |--lib/*.jar(网站需要的jar包)<br> |--web.xml(配置文件)<br> |--css/*.css(样式文件)<br> |--img/*.jpg/png/bmg/gif(图片资源)<br> |--js/*.js(脚本文件)<br> |--*.html(静态页面)<br>|--XXXServlet
配置库包
External Library中没有Tomcat包( <font color="#0076b3">jsp-api.jar</font> & <font color="#0076b3">servlet-api.jar</font>)时:<br>Alt+1 切到项目窗口 >> F4 打开Module Setting >> 选择Dependencies >> 增加Tomcat的库
开发步骤
创建目录结构
方式一:实现 <font color="#f15a23" style="">javax.servlet.<b>Servlet</b></font> 接口,重写 5 个主要方法,处理请求的方法是 service( )——缺点:5个方法中只有1个方法有用<br>方式二:继承 <font color="#f15a23">javax.servlet.<b>GenericServlet</b></font> 抽象类,重写需要的方法,处理请求的方法是 service( )——缺点:与协议无关,无法满足http协议的web项目<br><b><font color="#c41230">方式三</font></b>:继承 <font color="#f15a23">javax.servlet.http.<b>HttpServlet</b></font> 抽象类,<font color="#c41230">默认重写了 service( ) 方法</font>,且针对http协议优化,需自行重写 doGet( ) 和 doPost( ) 方法处理请求
在文件 <b><font color="#0076b3">WEB_INF/web.xml</font></b> 中新增如下内容<br>
<<font color="#f15a23">servlet</font>><br> <<font color="#f15a23">servlet-name</font>><b>Demo01</b></servlet-name><br> <<font color="#f15a23">servlet-class</font>><b>com.demo.t1.servlet.Demo01</b></servlet-class><br> <<font color="#f15a23">load-on-startup</font>>0</load-on-startup><br></servlet><br><<font color="#f15a23">servlet-mapping</font>><br> <<font color="#f15a23">servlet-name</font>><b>Demo01</b></servlet-name><br> <<font color="#f15a23">url-pattern</font>><b><font color="#c41230">/demo</font></b></url-pattern><br></servlet-mapping>
web项目中会有 /demo 的访问资源,访问方式: <font color="#c41230">http://localhost:8080/projname<b>/demo</b></font>
<b>Servlet配置</b>
web.xml配置(<font color="#c41230">Servlet所有版本支持</font>)
<font color="#c41230">为当前项目配置多个Servlet映射:</font><br><font color="#000000">配置方式:</font><b style="color: rgb(196, 18, 48);">可写多组</b> servlet 和 servlet-mapping 的标签,用来匹配映射不同的页面执行对应的不同的Servlet<br><font color="#c41230">为 Servlet 配置多个访问名称</font>:<br><font color="#000000">方式①:</font>增加多对<servlet-mapping>标签,修改其中的 <url-pattern> 标签;<br><font color="#000000">方式②:</font>在<servlet-mapping>标签中,增加多对 <url-pattern> 标签。
<url-pattern>匹配规则
精确匹配 <b><font color="#f15a23">/具体的名称</font></b> 只有url路径是具体的名称的时候才会触发Servlet<br>后缀匹配 <b><font color="#f15a23">*.xxx</font></b> 只要是xxx结尾的就匹配触发Servlet<br>目录匹配 <b><font color="#f15a23">/a/b/c*</font></b> 匹配对应目录资源下所有请求,包含服务器的所有资源<br>通配匹配 <b><font color="#f15a23">/</font></b> 匹配所有请求,包含服务器的所有资源,不包含.jsp——为<font color="#c41230">缺省Servlet</font>(Tomcat自带缺省)<br>
<load-on-startup>加载Servlet
<<font color="#f15a23">load-on-startup</font>>0<<font color="#f15a23">/load-on-startup</font>><br></servlet>
1) 标记容器是否在启动的时候就加载对应的 Servlet (实例化并调用其init()方法)<br>2) 它的值必须是一个整数,表示servlet应该被载入的顺序<br>3) 当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个 Servlet<br>4) 当值小于0或者没有指定时,则表示容器在该servlet被选择时才会去加载<br>5) 正数的值越小,该servlet的优先级越高,应用启动时就越先加载<br>6) 当值相同时,容器就会自己选择顺序来加载
服务器路径问题
分类:<br>① 带协议的绝对路径:<b><font color="#f15a23">http://localhost:8080/</font></b><font color="#5c5c5c">projname/img/pic.jpg</font><br>② 不带协议的绝对路径:<b><font color="#f15a23">/</font></b><font color="#5c5c5c">projname/img/pic.jpg</font><br>③ 相对路径:<br> 当前目录 <b><font color="#f15a23">./</font></b> 可省略<br> 上级目录 <b><font color="#f15a23">../</font></b> 不可省略
@WebServlet注解式配置(<font color="#c41230">Servlet3.0+支持</font>)
<font color="#c41230">@WebServlet</font>(<br> <b>name</b> = "TestWebServlet", // 设置 Servlet 的映射名字(通常与类名一致)<br> /*value = {"/demo", "/web"},*/<br> <b>urlPatterns</b> = {"/demo01", "/web01"}, // 设置 Servlet 访问资源名(value同urlPatterns)<br> <b>loadOnStartup</b> = 1, // 设置 Servlet 启动优先级<br> <b>initParams</b> = { // 设置 Servlet 启动参数<br> <font color="#c41230">@WebInitParam</font>(<b>name</b> = "username", <b>value</b> = "root"),<br> <font color="#c41230">@WebInitParam</font>(<b>name</b> = "password", <b>value</b> = "123456"),<br> }<br>)
name:任意起的当前Servlet的名字<br>value:<font color="#c41230">配置url路径</font>,该路径在<font color="#c41230">当前项目中必须唯一</font><br>urlPatterns:配置url路径,和value作用一样,不能同时使用<br>loadOnStartup:配置Servlet的创建时机
<b><font color="#5c5c5c">【</font><font color="#c41230">快捷创建</font></b><font color="#5c5c5c">】</font>包下 <font color="#f15a23">Alt+Insert</font> >> <b><font color="#f15a23">Create New Servlet</font></b> >> <br>输入类名即可同时创建注解和类, <font color="#000000">只需要写 </font><font color="#c41230">value</font><font color="#000000"> 配置 url 路径和</font><font color="#c41230">请求处理代码</font><font color="#000000">即可</font>
页面显示控制
① 默认只有 index.jsp 时会只显示其为首页
② 如果写了 index.html 页面则会以其<font color="#c41230">优先</font>为首页
③ 默认页面找不到时显示的页面
<<font color="#f15a23">welcome-file-list</font>><br> <<font color="#f15a23">welcome-file</font>><b><font color="#000000">page.html</font></b></welcome-file><br> <welcome-file><b><font color="#000000">page.htm</font></b></welcome-file><br> <welcome-file><b><font color="#000000">page.jsp</font></b></welcome-file><br></welcome-file-list>
<<font color="#f15a23">error-page</font>><br> <!--当页面未找到报404时显示 location 标签指定的页面--><br> <<font color="#f15a23">error-code</font>><b><font color="#000000">404</font></b></error-code><br> <<font color="#f15a23">location</font>><font color="#000000"><b>/error/404.html</b></font></location><br></error-page>
<b>ServletConfig与ServletContext</b>
<b><font color="#f15a23">ServletConfig</font> 接口</b>
是一个配置对象,通过 web.xml 或 注解方式配置 Servlet 参数后,可以通过 ServletConfig 对象获取初始化参数。
1. ServletConfig 对象是由服务器创建的,通过 Servlet 的 init 方法传递到 Servlet 中;<br>2. 作用:<br> 获取 Servlet 名称使用 <font color="#f15a23">getServletName</font>();<br> 获取 Servlet 初始化参数 <font color="#f15a23">getInitParameter</font>(); <font color="#f15a23">getInitParameterNames</font>();<br> 获取 ServletContext 对象<br>3. 获取 ServletContext 对象:继承 HttpServlet 后直接调用 Servlet 接口的 <font color="#f15a23">getServletContext</font>() 方法。
Demo
<b><font color="#f15a23">ServletContext</font> 接口</b>
是一个域对象(上下文对象),用来存储数据。<br>全局的储存信息的空间,服务器开始就存在,服务器关闭才释放。<br>
1. 当服务器启动时,会为服务器中的每一个web应用创建一个 ServletContext 对象;<br>2. 作用:<br> ① 实现多个 Servlet <b><font color="#c41230">数据共享</font></b><br> ② 获取<b><font color="#c41230">全局初始化参数</font></b><br> ③ 获取资源在服务器上的<b><font color="#c41230">真实磁盘路径</font></b><br> ④ 用 ServletContext 实现请求转发<br>
① 数据共享
public Object <font color="#f15a23">getAttribute</font>(String name) 获取域中指定参数名称的值<br>public void <font color="#f15a23">removeAttribute</font>(String name) 将指定的参数和值移除<br>public void <font color="#f15a23">setAttribute</font>(String name, Object object) 存储参数和值到到域中
Demo
② 获取全局初始化参数
<!--全局初始化参数:整个web应用,随着服务器的启动而初始化--><br><context-param><br> <param-name>username</param-name><br> <param-value>root</param-value><br></context-param><br><context-param><br> <param-name>password</param-name><br> <param-value>1234</param-value><br></context-param><br><!--或注解方式配置初始化参数-->
public String <font color="#f15a23">getInitParameter</font>(String name) 获取初始化参数<br>public java.util.Enumeration<E> <font color="#f15a23">getInitParameterNames</font>() 获取初始化参数集合
Demo
③ 获取资源在服务器上的真实磁盘路径
public String <font color="#f15a23">getRealPath</font>(String path) 获取资源的真实路径<br>根据项目的当前路径 / 拼接,注意参数给的时候也是相对于 / 当前路径。
Demo
案例:统计站点访问次数
Demo
Servlet集成JDBC三层架构
注意事项:<br>1. 路径配置,注解中的value路径、html中的路径;<br>2. QueryRunner注意传参时的实体类参数;<br>3. 确保数据库配置文件正确,能够正确被DruidUtils加载到;
Servlet生命周期
生命周期
// 监听 Servlet 的初始化——通过浏览器页面请求调用Servlet时<font color="#c41230">仅初始化 1 次</font>【<b><font color="#c41230">单例模式</font></b>】<br>void init(ServletConfig var1) throws ServletException;<br>// 处理 Servlet 的数据请求和响应<br>void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;<br>// 监听 Servlet 进行销毁——<font color="#c41230">服务器关闭</font>的时候会销毁 Servlet<br>void destroy();
线程安全
尽可能使用局部变量。
初始化参数
xml或注解。
<b>Servlet单示例多线程</b>
1. Servlet 在服务器中只会创建一个实例<br>2. 当多个请求同时请求一个 Servlet 时,就会根据 tomcat 中的 server.xml 文件中的 <Connector> 标签配置线程池,然后当项目启动时,根据项目中 web.xml 初始化线程池<br>3. 当请求到达时,Servlet 容器通过调度线程池中等待状态的线程给请求<br>4. 线程执行 Servlet 的 service 方法<br>5. 请求结束,放回线程池,等待被调用
优点:<br>* Servlet 单实例,减少了产生 Servlet 的开销<br>* 通过线程池来响应多个请求,提高了请求的响应时间<br>缺点:<br>* 在 Servlet 中尽量避免使用成员变量,因为成员变量属于对象实例,而 Servlet 是单实例,所以相当于这个成员变量是多线程共享,存在线程不安全的问题。
<b>HTTP</b>
HTTP协议
协议:两个设备进行数据交换的约定。<br>HTTP协议:超文本(字符/音频/视频/图片)传输协议,基于TCP协议。
HTTP请求报文(图)
<ul><li><b>请求行</b>:</li></ul><font color="#c41230"> Request URL</font>: 请求网址<br><font color="#c41230"> Request Method</font>:请求方式(<b><font color="#f15a23">GET</font>/<font color="#f15a23">POST</font></b>)<br><font color="#c41230"> Protocol</font>:http协议版本<br><ul><li><b>请求头</b>:</li></ul><font color="#c41230"> Cookie</font>: cookie<br><font color="#c41230"> Content-Type</font>:请求正文的数据类型<br><font color="#c41230"> User-Agent</font>:请求的浏览器类型<br><ul><li><b>请求数据</b>:</li></ul> 请求正文(POST+请求参数)的具体数据<br>
HTTP响应报文(图)
<ul><li><b>响应行</b>:</li></ul><font color="#c41230"> Status Code</font>:响应状态码(200/404...)<br><ul><li><b>响应头</b>:<br><font color="#c41230">Location</font>:与302状态码组合完成重定向功能</li></ul><font color="#c41230"> Content-Type</font>:响应正文的数据类型(Content-Type:<font color="#f15a23">text/html;charset=utf-8</font>)<br> <font color="#c41230">Refesh</font>:定时跳转<br> <font color="#c41230">Content-disposition</font>:文件下载<br><ul><li><b>响应数据</b>:</li></ul> 响应正文的具体数据
HTTP请求执行流程
<ul><li>发起请求</li><li>域名解析</li></ul> 本地域名解析(C:\Windows\System32\drivers\etc\hosts)<br> 互联网域名解析(DNS)<br><ul><li>执行请求</li><li>响应请求</li></ul>
<b>GET/POST请求区别</b>
● get只能传递<font color="#c41230">1kb以下</font>的数据;post可以传递<font color="#c41230">大数据</font><br>● get请求参数会直接拼接到<font color="#c41230">Request URL</font>上(&);post请求参数是在<font color="#c41230">请求正文</font>中,更安全<br>● get主要用于<font color="#c41230">获取/查询</font>数据;post主要用于<font color="#c41230">更新</font><font color="#5c5c5c">数据/</font><font color="#c41230">上传文件</font>
常用响应状态码
200:服务器响应成功<br>302:页面重定向<br>304:页面无变化,无需重新请求服务器<br>404:没有对应的服务器资源<br>500:服务器内部错误<br>
<b>请求&响应</b>
<b><font color="#f15a23">response </font><font color="#5c5c5c">对象</font></b>
操作响应行
<b>response.</b><font color="#f15a23">setStatus</font>() 操作响应状态码,如200,302<br><b>response.</b><font color="#f15a23">sendError</font>() 操作响应错误码,如404
操作响应头<br>
<b>response.</b><font color="#f15a23">setHeader</font>() 覆盖原有响应头的值<br><b>response.</b><font color="#f15a23">addHeader</font>() 在原有的响应头的基础上添加新值(Cookie)<br>
操作响应正文
<b>response.</b><font color="#f15a23">getWriter().println</font>("<b>响应正文内容</b>") 返回可将字符文本发送到客户端的 java.io.PrintWriter 对象<br>
操作响应中文乱码
// ● <b>终极方案</b>:同时设置服务器的编码,设置浏览器解码方式<br><b>response</b>.<font color="#f15a23">setContentType</font>("<b><font color="#00a650">text/html;charset=utf-8</font></b>");<br>// 其他方案:分别设置服务器编码、浏览器解码<br>response.setCharacterEncoding("utf-8") 设置服务器的编码方式<br>response.setHeader("Content-Type", "text/html;charset=utf-8") 设置浏览器的解码方式<br>
浏览器的解码方式不固定
<b>定时跳转</b>
/*定时跳转*/<br><b>response.</b><font color="#f15a23">setHeader</font>("<b><font color="#000000">refresh</font></b>", "<b><font color="#000000">5;url=</font></b>/demo/demo02"); // 5s后跳转demo02
重定向
// 方式一:设置 Status Code=302 和 Location=url<br><b>response.</b><font color="#f15a23">setStatus</font>(302);<br><b>response.</b><font color="#f15a23">setHeader</font>("location", "/projname/success.html");<br>// ● 方式二:本质还是 Status Code=302 和 Location=url<br><b>response</b>.<font color="#f15a23">sendRedirect</font>("<b style=""><font color="#000000">/</font><font color="#c41230">projname</font><font color="#000000">/success.html</font></b>");<br>response.sendRedirect(<b>request.getContextPath()</b> + <b>File.separator</b> + "<b>资源/页面</b>");<br>
原理:<br>浏览器<font color="#c41230"><b>发送http请求</b></font> >> web服务器回复响应状态码<b><font color="#c41230">302</font></b>+响应头<b><font color="#c41230">location</font></b>给浏览器 >> 浏览器收到302则<b><font color="#c41230">自动再发送1个http请求</font></b>(url+location) >> 服务器根据新请求的url寻找资源<b><font color="#c41230">响应</font></b>给浏览器
特点:<br>1. 重定向是<font color="#c41230">客户端</font>行为<br>2. 重定向是浏览器做了至少 <font color="#c41230"><b>2</b></font> 次的访问请求<br>3. 重定向浏览器<font color="#c41230">地址改变</font><br>4. 重定向两次跳转之间传输的<font color="#c41230">信息会丢失</font>(request生命周期为单次请求)<br>5. 重定向可以定向到<font color="#c41230">任何web资源</font>(当前站点/外部站点)<br>
<b><font color="#f15a23">request</font> 对象</b>
操作请求行
<b>request</b>.<font color="#f15a23">getMethod</font>() 获取请求方式<br><b>request</b>.<font color="#f15a23">getRequestURI</font>() 获取请求路径<br><b>request</b>.<font color="#f15a23">getQueryString</font>() 获取请求路径上的参数,仅限于GET<br>
操作请求头
<b>request</b>.<font color="#f15a23">getHeader</font>(String name) 根据请求头名称获取值,如 User-Agent
操作请求参数
<b>request</b>.<font color="#f15a23"><b>getParameter</b></font>() 获取指定参数名称的值<br><b>request</b>.<font color="#f15a23">getParameterValues</font>() 获取指定参数名称的一组值<br><b>request</b>.<font color="#f15a23">getParameterMap</font>() 返回此请求的参数的 java.util.Map<br><b>request</b>.<font color="#f15a23">getParameterNames</font>() 获取所有的参数名称<br>
Demo
操作请求数据
<font color="#c41230">@WebServlet</font>(name = "任意名字", urlPatterns = "<b><font color="#000000">/资源路径</font></b>")
<!--默认提交方式为 GET,同时可省略,POST不可省略--><br><b><form method="post" </b><font color="#f15a23" style="font-weight: bold;">action</font><b>="</b><font color="#000000" style="font-weight: bold;">/</font><font color="#c41230" style="font-weight: bold;">projname</font><font color="#000000" style="font-weight: bold;">/资源路径</font><b>">...</form></b><br>
操作请求中文乱码
/* POST请求正文乱码,两种方式都可以;GET是QueryString乱码,只能用方式二 */<br>// ● <b>终极方案</b>:设置请求正文<font color="#c41230">编码</font>,用于POST在<font color="#c41230">Tomcat8.5</font>环境。<br><b> request</b>.<font color="#f15a23">setCharacterEncoding</font>("<b><font color="#00a650">utf-8</font></b>");<br>// 其他方案:将请求中拿到的乱码字符串编码成iso8859-1字节,再将字节解码为utf-8字符串,通用Tomcat7.0&8.5环境。<br>String serverEncoding = request.<b>getCharacterEncoding</b>();<br>String tmp = request.<b>getParameter</b>("username");<br>String username = new String(tmp.<b>getBytes</b>(serverEncoding), "<font color="#00a650">utf-8</font>");<br>/* <font color="#c41230">Tomcat8.5</font><font color="#5c5c5c">比7.0中新增了URIEncoding="utf-8",</font><font color="#c41230">修复了GET请求QueryString乱码</font><font color="#5c5c5c">,POST请求还需设置请求正文编码</font> */
浏览器的编码方式固定为 utf-8
请求转发
// 转发,如提交成功自动进行一次配置路径的Servlet请求调用执行,此处为配置路径(无projname)<br><b>request</b>.<font color="#f15a23">getRequestDispatcher</font>("<b><font color="#000000">/资源路径</font></b>").<font color="#f15a23">forward</font>(request, response);
原理:<br>客户浏览器<b><font color="#c41230">发送http请求</font></b> >> web服务器<b><font color="#c41230">接收</font></b>此请求 >> 服务器<b><font color="#c41230">内部完成请求处理和转发动作</font></b> >> 将目标资源<b><font color="#c41230">响应</font></b>给客户
特点:<br>1. 转发是<font color="#c41230">服务器</font>行为<br>2. 转发是浏览器只做了 <b><font color="#c41230">1</font></b> 次访问请求<br>3. 转发浏览器<font color="#c41230">地址不变</font><br>4. 转发两次跳转之间的<font color="#c41230">信息不会丢失</font>(request生命周期内可传递数据)<br>5. 转发只能将请求转发给<font color="#c41230">同一个web项目内</font>的资源
request域对象
request域对象生命周期:在一次请求中,请求结束服务器响应时即销毁。
request域对象共享数据方法
<b>request.</b><font color="#f15a23">setAttribute</font>(name, msg); // 设置数据msg取名name<br><b> request.</b><font color="#f15a23">getAttribute</font>(name); // 获取数据与name对应<br><b> request.</b><font color="#f15a23">removeAttribute</font>(name); // 删除数据与name对应<br><b> request.</b><font color="#f15a23">getAttributeNames</font>(); // 获取所有的共享数据names<br>
● <font color="#c41230">重定向中不能使用 request域对象</font>,因为1次请求响应后该对象便销毁;<br>● <font color="#c41230">转发中可以使用 request域对象</font>,因为转发只有1次请求,在域对象生命周期内。<br>
重定向和转发的路径问题
1. 使用相对路径时,没有区别;<br>2. 使用绝对路径时,重定向使用<font color="#c41230">/project/资源</font>,转发使用<font color="#c41230">/资源</font>
<b>会话技术</b>
<b><font color="#f15a23">Cookie</font></b>
客户端状态管理技术,将状态信息保存在客户端。<br>网景公司发明,<font color="#c41230">浏览器会话技术</font>。<br>一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称name和设置值value。<br>浏览器一般只允许存放<b>300</b>个Cookie,每个站点最多存放<b>20</b>个Cookie,每个大小限制为<b><font color="#5c5c5c">4kb</font></b>。
工作原理
执行流程:<br>1.浏览器向服务器发送请求,服务器需要创建cookie,服务器会通过响应携带cookie,<br> 在产生响应时会产生Set-Cookie响应头,从而将cookie信息传递给了浏览器;<br>2.当浏览器再次向服务器发送请求时,会产生cookie请求头,将之前服务器的cookie信息再次发送给了服务器,<br> 然后服务器根据cookie信息跟踪客户端状态。
图示
创建添加
// 用响应创建Cookie,等价于 response.addHeader("set-cookie", "name=value");<br>Cookie cookie = <b><font color="#c41230">new</font></b> <b><font color="#f15a23">Cookie</font></b>(String <font color="#f15a23">name</font>, String <font color="#f15a23">value</font>); // Cookie: name=value<br>cookie.<font color="#f15a23">setMaxAge</font>(seconds); // 设置Cookie的生命周期<br>cookie.<font color="#f15a23">setPath</font>("/"); // 设置Cookie的共享范围<br><b>response</b>.<font color="#f15a23">addCookie</font>(cookie); // 添加1个Cookie<br>
获取修改
// 用请求获取Cookie<br>Cookie[] cookies = <b>request</b>.<font color="#f15a23">getCookies</font>(); // 获取Cookies返回数组<br>// 需<font color="#c41230">遍历</font><br>cookie.<font color="#f15a23">getName</font>();<br>cookie.<font color="#f15a23">getValue</font>();<br>// 修改Cookie<br>cookie.<font color="#f15a23">setValue</font>(String);
共享范围
// 设置Cookie的共享范围<br>cookie.<font color="#f15a23">setPath</font>("/");<br>
<b><font color="#c41230">/</font></b> 当前项目下所有资源均可共享访问该Cookie对象内容<br><b><font color="#c41230">/project/demo</font></b> 当前项目下只有资源demo均可共享访问该Cookie对象内容<br>
生命周期
// 设置Cookie生命周期,单位s<br>cookie.<font color="#f15a23">setMaxAge</font>(int); // 7天:7*24*60*60
<ul><li><0:浏览器会话结束/浏览器关闭,内存存储(<b><font color="#000000">默认</font></b>)</li><li>=0:失效</li><li>>0:生效时间,单位s</li></ul>* 在生命周期内Cookie会跟随任何请求,可通过<font color="#c41230">设置路径限制携带Cookie的请求资源范围</font>。
编码与解码
中文:Unicode,4个字节 英文:ASCII,2个字节
Cookie的中文乱码需要进行编码和解码处理:<br>编码:java.net.URLEncoder 的 <b>URLEncoder.<i><font color="#f15a23">encode</font></i></b>(String str, String encoding)<br>解码:java.net.URLDecoder 的 <b>URLDecoder.<i><font color="#f15a23">decode</font></i></b>(String str, String encoding)
Demo
chrome浏览器查看cookie信息
chrome://settings/content/cookies
chrome://settings/siteData
优劣
优点:<br>● <b>可配置三种到期规则</b>:1次请求就失效,1次浏览器会话(关闭)失效,配置永久生效<br>● <b>简单性</b>:基于文本的轻量结构,简单键值对<br>● <b>数据持久性</b>:虽然Cookie可被客户端浏览器的过期处理和干预,但Cookie通常也是客户端上持续时间最长的数据保留形式<br>
缺点:<br><b>● 大小受到限制</b>:大多数浏览器的Cookie只有4kb大小的限制<br><b>● 用户配置禁用</b>:客户浏览器设置了禁用接收Cookie的能力,限制了该功能<br><b>● 潜在安全风险</b>:用户可能会操纵篡改浏览器上的Cookie,会造成Cookie应用程序执行失败的问题
案例:记录用户上一次访问时间
LastVisitTimeServlet
案例:记录商品的浏览历史信息
HistoryServlet
ShowHistoryServlet
<b><font color="#f15a23">Session</font></b>
三大域对象
<font color="#c41230">request 1个用户可有多个</font>;<b><font color="#c41230">session 1个用户1个</font></b>;<font color="#000000"><b>servletContext 所有用户共用1个</b></font>。<br>为了节省空间,提高效率,ServletContext 中要放必须的、重要的、所有用户需要共享的线程安全的一些信息。<br>
服务器状态管理技术,将状态信息保存在服务器端。<br>是sun公司定义的一个接口。
工作原理
执行流程:<br>1. 第一次请求,请求头中没有jsessionid的cookie,当访问到对应的servlet资源时,执行到getSession()会创建HttpSession对象;进而响应时就将session的id作为cookie的value,响应到浏览器 Set-cookie:jsessionid=xxxx;<br>2. 再一次请求时,http请求中就有一个cookie:jsessionid=xxxx信息,那么该servlet就可以通过getSession()获取到jsessionid在服务器内查找对应的session对象,有就使用,无就创建。
图示
基本使用
// 获取session对象<br>HttpSession session = <b>request</b>.<font color="#f15a23">getSession</font>();<br>// 获取session对象的唯一标识:sessionID (JSESSIONID=E925DE1EF00F7944537C01A3BC0E2688)<br>String jsessionid = <b>session</b>.<font color="#f15a23">getId</font>();<br>// 销毁session对象中的jsessionid<br>session.<font color="#f15a23">invalidate</font>();
数据共享
// 往 session 中存储 msg<br>HttpSession session = request.getSession();<br><b>session</b>.<font color="#f15a23">setAttribute</font>("msg", "helloSession");<br>// 获取 msg<br>HttpSession session = request.getSession();<br>Object msg = <b>session</b>.<font color="#f15a23">getAttribute</font>("msg");<br>// 删除域对象中的数据<br><b>session</b>.<font color="#f15a23">removeAttribute</font>("msg");
生命周期
一般都是默认值 30 分钟,无需更改。
web.xml
<session-config><br> <session-timeout><b><font color="#000000">30</font></b></session-timeout><br></session-config>
浏览器关闭:销毁Cookie中的jsessionid=xxx,原session对象会保留默认30min后才销毁,30分钟后为新的session;<br>session销毁:调用 session.invalidate() 方法后,立即将session对象销毁,再次访问时会创建新的session。
<b>案例:使用验证码登陆和共享用户信息</b>
c3p0连接池
<font color="#0076b3"><b>c3p0-0.9.5.4.jar<br>commons-dbutils-1.7.jar<br>mchange-commons-java-0.2.16.jar<br>mysql-connector-java-5.1.48.jar</b></font><br>
DBUtils
DAOImpl
页面和Servlet
login.html
CreateCodeServlet
LoginServlet
ShowServlet
http请求中4大共享数据方式
ServletContext
生命周期为服务器开启和关闭,而且所有用户都会共享,范围过大,保密性不高。
request
生命周期太短,一次请求就丢失,无法再重定向后再次获取内容
cookie
存储在客户端浏览器,不安全!客户端浏览器可对cookie进行查看或修改,而且cookie无法定义特殊符号
session
存储在服务器,默认30分钟才销毁更新,或者服务器中主动销毁,适合用户登陆信息的共享
<b>Cookie工具类</b>
CookieUtils
<b>过滤器</b>
基本信息
对客户端向服务器发送的请求进行过滤,用于在请求之前处理资源的组件。<br>Filter和Listener都属于Servlet中的高级部分,Filter是最为实用的技术。
过滤器链
请求时,从客户端到服务端顺序处理;<br>响应时,从服务端到客户端顺序处理。<br>> 遵从原则:先过滤,后放行。
工作原理
执行流程:<br>1. 浏览器发起请求<br>2. 服务器会根据这个请求,创建 request 对象及 response 对象<br>3. 过滤器会持有 request 对象及 response 对象<br>4. 只有当过滤器放行之后,request 对象及 response 对象才会传给 Servlet
图示
生命周期
* 随着服务器的初始化而初始化<br>* 随着服务器的关闭而销毁
基本使用
开发步骤:<br>1. 自定义类<b><font color="#c41230">实现 Filter 接口</font><font color="#5c5c5c">(包:</font><font color="#0076b3">javax.servlet.Filter</font><font color="#5c5c5c">)</font></b><br>2. 重写 <font color="#f15a23"><b>init</b></font>() <font color="#f15a23"><b>doFilter</b></font>() <font color="#f15a23"><b>destroy</b></font>() 三个方法<br>3. 在 web.xml 中配置过滤器:①声明过滤器 ②配置过滤器的过滤路径
FilterDemo
public class Filter01 implements Filter {<br> @Override<br> public void <font color="#f15a23">init</font>(FilterConfig filterConfig) throws ServletException {<br> System.out.println("Filter01 过滤器的初始化");<br> }<br> @Override<br> public void <font color="#f15a23">doFilter</font>(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {<br> System.out.println("Filter01 放行之前");<br> // 通过过滤器链操作:放行<br> <font color="#924517"><b>filterChain</b></font>.<font color="#f15a23">doFilter</font>(<font color="#924517">servletRequest</font>, <font color="#924517">servletResponse</font>);<br> System.out.println("Filter01 放行之后");<br> }<br> @Override<br> public void <font color="#f15a23">destroy</font>() {<br> System.out.println("Filter01 过滤器的销毁");<br> }<br>}
web.xml
<!--声明Filter01过滤器--><br><filter><br> <filter-name>Filter01</filter-name><br> <filter-class>com.demo.filter.Filter01</filter-class><br></filter><br><!--配置Filter01的过滤路径--><br><filter-mapping><br> <filter-name>Filter01</filter-name><br> <!--/ 代表所有资源都过滤--><br> <url-pattern>/*</url-pattern><br></filter-mapping>
配置方式
web.xml
<!--无限接近SpringMVC中文乱码解决方案--><br> <filter><br> <filter-name><b><font color="#000000">EncodingFilter</font></b></filter-name><br> <filter-class><b><font color="#000000">com.demo.filter.EncodingFilter</font></b></filter-class><br> <init-param><br> <param-name><b><font color="#000000">encoding</font></b></param-name><br> <param-value><b style=""><font color="#c41230">utf-8</font></b></param-value><br> </init-param><br></filter><br><filter-mapping><br> <filter-name><b><font color="#000000">EncodingFilter</font></b></filter-name><br> <url-pattern><b><font color="#000000">/*</font></b></url-pattern><br> </filter-mapping>
步骤:声明过滤器,配置过滤路径。
匹配规则
<url-pattern>标签中的匹配规则:<br> * / 完全匹配<br> * /开头,*结尾 目录匹配<br> * *开头,后缀名结尾 后缀名匹配
注解配置
@WebFilter注解<br>WebInitParam[] initParams() default {}; //配置初始化参数<br>String filterName() default ""; //配置过滤器名称<br>String[] servletNames() default {}; //配置过滤的Servlet<br>String[] urlPatterns() default {}; //配置过滤路径
使用注解
Demo
中文乱码
方式一:过滤器处理
页面乱码处理 login.jsp 不会乱码
html 请求和响应乱码
web.xml
Demo
方式二:继承(通用Servlet)
<b>案例:实现自动登陆</b>
逻辑流程
1. 登陆账户后,根据是否勾选了自动登录选项框<br>2. 判断是否访问和登陆相关资源<br> * 如果是,直接放行<br> * 如果不是,判断是否已经在登陆状态<br> * 如果已登陆,直接放行<br> * 如果不是,需要从cookie中取出存储的用户信息,进行登陆操作<br> * 如果登陆成功,直接放行<br> * 如果登陆失败,就跳转到登陆页面
流程图示
代码逻辑
web.xml
login.jsp
AutoLoginServlet<br>
AutoLoginFilter
ShowIndexServlet
<b>案例:请求中的敏感词过滤</b>
核心逻辑
使用动态代理模式在过滤器中<font color="#c41230">增强 request.getParameter() 方法</font><br>使其在浏览器发起请求时拥有过滤敏感词功能。
SensitiveWordsFilter
<b>监听器</b>
基本信息
概念:监听器就是一个实现了特定接口的Java类
分类
一类监听器:监听域对象的创建、销毁
二类监听器:监听域对象中的属性变更(属性设置、属性替换、属性移除)
三类监听器:监听域对象中的java对象的绑定
Servlet监听器
事件源:request、session、servletContext三大域对象
监听器:Servlet对象(三种监听器)
绑定:web.xml配置 或 @WebListener注解
事件:域对象发生改变
工作原理
1. 实现了特定接口的类为监听器,用来监听另一个Java类的方法调用或者属性改变;<br>2. 当被监听的对象发生了方法调用或者属性改变后,监听器的对应方法就会立即执行。
基本使用
一类
<b><font color="#f15a23">ServletContextListener</font></b>
监听ServletContext域对象的创建、销毁
// 服务器启动,ServletContext域对象创建,该监听器方法则执行<br>public void contextInitialized(ServletContextEvent servletContextEvent)<br>// 服务器关闭,ServletContext域对象销毁,该监听器方法则执行<br>public void contextDestroyed(ServletContextEvent servletContextEvent)<br>
<b><font color="#f15a23">HttpSessionListener</font></b>
监听HttpSession域对象的创建、销毁
// 服务器第一次调用getSession方法时,该监听器方法被执行<br>public void sessionCreated(HttpSessionEvent httpSessionEvent)<br>// session过期/调用了invalidate方法销毁session时,该监听器方法被执行<br>public void sessionDestroyed(HttpSessionEvent httpSessionEvent)<br>
问题:<br>* 访问一个Servlet会不会创建session对象?会!<br>* 访问一个JSP页面会不会创建session对象?会!<br>* 访问一个HTML页面会不会创建session对象?不会!
<b><font color="#f15a23">ServletRequestListener</font></b>
监听ServletRequest域对象的创建、销毁
// 客户端向服务器发送了一个请求,服务器就会为该请求创建一个request对象,该监听器方法就被执行<br>public void requestInitialized(ServletRequestEvent servletRequestEvent)<br>// 当服务器为这次请求做出了响应后,将request对象销毁,该监听器方法就被执行<br>public void requestDestroyed(ServletRequestEvent servletRequestEvent)<br>
问题:<br>* 访问一个Servlet会不会创建request对象?会!<br>* 访问一个JSP页面会不会创建request对象?会!<br>* 访问一个HTML页面会不会创建request对象?不会!
二类
<b><font color="#f15a23">ServletContextAttributeListener</font></b>
<b><font color="#f15a23">HttpSessionAttributeListener</font></b>
<b><font color="#f15a23">ServletRequestAttributeListener</font></b>
三类
<b><font color="#f15a23">HttpSessionBindingListener</font></b>
监听session域对象中的java对象的状态(绑定和解绑)<br><ul><li>绑定:将java对象存储到session域对象</li><li><span style="font-size: inherit;">解绑:将java对象从session域对象移除</span></li></ul><span style="font-size: inherit;">* 该监听器不需要在web.xml中配置</span><br>
开发步骤:Java对象实现该接口,重写方法。
Demo
开发步骤
定义类实现监听器接口
重写方法
配置
配置 web.xml
<listener><br> <listener-class><b><font color="#000000">Listener的全限定名</font></b></listener-class><br></listener>
@注解
@WebListener
Demo
<b>案例:统计在线人数</b>
逻辑图示
代码实现
login.html<br>
User
LoginServlet
LogoutServlet
ShowIndexServlet
<b>综合案例:用户管理</b>
登陆
登陆成功,修改登陆状态,跳转首页<br>登陆失败,跳转到登陆页面
首页
不再登陆状态,提示用户登陆<br>在登陆状态,显示用户名<br>显示注销登陆按钮<br>显示用户列表
注销
session.removeAttribute / session.invalidate<br>注销成功,跳转到登陆页面<br>注销失败,跳转到首页,重新手动注销登陆
用户列表
不在登陆状态,不显示用户列表<br>在登陆状态:<br> · 操作数据库,获取所有用户<br> · 通过table标签将用户列表显示出来<br>
删除用户
在table的每一行中都添加一个删除按钮<br>在添加删除按钮时,会给出所在行的记录的id<br>在点击删除按钮时,请求删除用户的DeleteUserServlet<br>删除成功与否都跳转首页
批量删除
在table的每一行中都添加一个复选框<br>在每个删除标签中,需要给给每个复选框,设定name属性、value属性<br> · name="ids"<br> · value就是每一行记录的id<br>当点击批量删除按钮时,请求批量删除的Servlet<br>DeleteUsersServlet删除成功与否都跳转到首页
添加用户
首页新加一个添加用户按钮<br>点击添加用户按钮之后,跳转到添加用户页面<br>当点击提交按钮,开始添加用户<br>AddUserServlet 添加成功跳转首页,添加失败,跳转到添加用户页面
修改用户
在table的每一行中都添加一个修改按钮<br>点击修改用户按钮之后,跳转到修改用户页面ShowUpdateUserServlet:<br> · 获取要修改的用户信息<br> · 生成要修改用户的页面<br>点击提交按钮,开始修改用户UpdateUserServlet<br> · 修改成功跳转到首页<br> · 修改失败,跳转到修改用户页面
<font color="#c41230">通用Servlet</font>
BaseServlet<br>充当了父类的通用Servlet,所有自定义的Servlet都继承于BaseServlet<br>实现请求的分发,不同的请求交给不同的方法进行处理
高级版
login.html
BaseServlet
UserServlet
<font color="#c41230">生命周期划分</font>
pageContext
作用在<font color="#c41230">当前页面</font>
request
作用在<font color="#c41230">一次请求</font>中
cookie
默认随浏览器关闭而销毁(存储在浏览器,可设置更长生命周期)
session
作用在<font color="#c41230">一次会话</font>中,随浏览器关闭而销毁
filter
随服务器初始化而初始化,服务器关闭而关闭
listener
随服务器初始化而初始化,服务器关闭而关闭
ServletContext / application
作用在<font color="#c41230">服务器开启和关闭</font>
<b>JSP</b>
JSP原理
概念
JSP,<font color="#c41230"><b>java server page</b></font>,和Servlet一样,是sun公司定义的一种动态网页技术。本质就是一个servlet,可以使用jsp代替servlet来处理请求,显示数据。<br>即 jsp可以理解为在html页面中写java代码,或 一个可以获取java数据的html文件。<br>
JSP为什么本质是一个Servlet?<br>testjsp.jsp 继承自 testjsp.java/testjsp.class 继承自 HttpJspPage 继承自 JspPage 继承自 Servlet。<br>Tomcat镜像中将jsp文件转义为了java文件和编译后的class字节码文件:<br>C:\Users\Administrator\.IntelliJIdea2019.3\system\tomcat\<font color="#000000"><b>Tomcat_8_5_53_demo61</b></font>\<font color="#c41230">work\Catalina\localhost\</font><b><font color="#000000">demo</font></b>\org\apache\jsp\<b><font color="#000000">demo.java</font></b><br>
查看生成java文件
/*<br>* Generated by the Jasper component of Apache Tomcat<br>* Version: Apache Tomcat/8.5.53<br>* Generated at: 2020-04-26 07:19:38 UTC<br>* Note: The last modified time of this file was set to<br>* the last modified time of the source file after<br>* generation to assist with modification tracking.<br>*/
/ *<br> * 由Apache Tomcat的Jasper组件生成<br> * 版本:Apache Tomcat/8.5.53<br> * 生成时间:2020-xx-xx xx:xx:xx<br> * 注意:此文件的最后修改时间设置为生成后源文件的最后修改时间,以帮助跟踪修改。<br> * /<br>
① 当在浏览器上输入 http://localhost:8080/demo/index.jsp<br>② 服务器tomcat得到请示,会通过JspServlet将后缀名是.jsp的请求处理<br>③ 会将index.jsp翻译成index_jsp.java文件<br>④ 再将index_jsp.java文件编译成index_jsp.class文件<br>⑤ jvm将.class加载运行<br>⑥ 服务器生成响应,响应信息中就包含了jsp页面上的html代码
JSP脚本
脚本
可以在页面上写java代码<br>
分类:<br>● <b>声明脚本</b>:<b><font color="#f15a23"><%! Java代码 %></font></b><br>在jsp对应的java类中生成一个<font color="#c41230">成员变量</font><br>● <b>片段脚本</b>:<b><font color="#f15a23"><% Java代码 %></font></b><br>在jsp对应的java类的_jspService方法中,生成一个<font color="#c41230">局部变量</font><br>● <b>输出脚本</b>:<b><font color="#f15a23"><%= Java代码 %></font></b><br>向浏览器输出内容,相当于 response.getWriter().write(<font color="#c41230">Java代码</font>)<br>在jsp对应的java类的 out.prinln() 中
注释
jsp文件中可以有 jsp + html + java 代码<br>即 可以使用上述三种语言的注释标签。<br>
● jsp:<font color="#8a8b8f"><%-- 注释 --%></font><br>jsp注释不会生成到jsp对应的java文件中<br>● html:<font color="#8a8b8f"><!-- 注释 --></font><br>● java:<font color="#8a8b8f">/* 注释1 */ // 注释2</font><br>html、java注释均会生成到jsp对应的java文件中<br>
JSP指令
用于指示jsp执行某些操作或特性行为/效果
语法
<b><font color="#f15a23"><%@ </font><font color="#000000">指令名称</font><font color="#f15a23"> 属性1="</font><font color="#662c90">值1</font></b><font color="#f15a23">"</font> <b><font color="#f15a23">属性2="</font><font color="#662c90">值2</font><font color="#f15a23">" %></font></b>
分类
<b style="font-size: inherit;"><font color="#f15a23">page</font></b><span style="font-size: inherit;"> 指令</span><br><span style="font-size: inherit;"></span>
设置jsp页面的基本属性<br>
<font color="#f15a23" style=""><%@ <b>page</b> contentType="</font><font color="#662c90" style="">text/html;charset=UTF‐8</font><font color="#f15a23" style="">" language="</font><font color="#662c90" style="">java</font><font color="#f15a23" style="">" import="</font><font color="#662c90" style="">java.util.List</font><font color="#f15a23" style="">" isELIgnored="</font><font color="#662c90" style="">false</font><font color="#f15a23" style="">" session="</font><font color="#662c90" style="">false</font><font color="#f15a23" style="">"%></font>
<ul><li>contentType="..." 相当于 response.setContentType("...") 设置编解码方式</li><li>language="java" jsp脚本上可以使用的语言,<font color="#000000">一般不用</font>,默认java</li><li>import="java.util.List" 页面上导入java包,<font color="#c41230">多个包使用逗号分隔</font>(IDEA可以导入包,默认导入jsp页面顶部-<font color="#c41230">为单独的page指令导包</font>)</li><li>isELgnored="false" 是否忽略el表达式,默认false是不忽略</li><li>errorPage="error.jsp" 用于指定错误页面,当前页面发生错误后,会跳转到指定的错误页面</li><li>isErrorPage="true" 为true时可以在当前页面直接使用jsp内置对象exception,即 <%= exception.toString() %> 或 ${exception} 页面输出错误信息</li><li>extends="org.apache.jasper.runtime.HttpJspBase" 默认继承自HttpJspBase类,<b><font color="#000000">不动</font></b>!</li></ul>
<b style="font-size: inherit;"><font color="#f15a23">taglib</font></b><span style="font-size: inherit;"> 指令</span><br><span style="font-size: inherit;"></span>
在当前jsp页面导入 jstl 标签库(JSP标准标签库是由JCP所制定的标准规范)<br>
uri属性确定标签库的位置,prefix属性指定标签库的前缀<font color="#f15a23"><br><%@ <b>taglib</b> prefix="</font><font color="#662c90">c</font><font color="#f15a23">" uri="</font><b style=""><font color="#662c90">http://java.sun.com/jsp/jstl/core</font></b><font color="#f15a23">"%></font><br>
<b style="font-size: inherit;"><font color="#f15a23">include</font></b><span style="font-size: inherit;"> 指令</span><br><span style="font-size: inherit;"></span>
嵌套其他jsp文件的jsp代码(其他jsp代码可以只是所需部分)
第一种 include指令:`<font color="#c41230">通过file属性来指定被包含的页面</font>`,当JSP转换成Servlet时引入指定文件,`一般不需要写头`<br><%@ pagecontentType="text/html;charset=GB2312" language="java"errorPage=""%><br><%@ include file="head.jsp"%><br><%@ include file="body.jsp"%><br><%@ include file="tail.jsp"%>
第二种 <jsp:include>动作元素:`<font color="#c41230">通过page属性来指定被包含的页面</font>`,当JSP页面被请求时引入指定文件,`需要写头`<br>可以用<jsp:param>来向所包含页传递参数。<br><%@ page contentType="text/html; charset=GB2312"language="java" errorPage=""%><br><jsp:include page="head.jsp"/><br> <jsp:param name="uid"value="username"/><br> <jsp:param name="pwd"value="password"/><br></jsp:include><br><jsp:include page="body.jsp"/><br><jsp:include page="tail.jsp"/>
<b>内置对象</b>
概念
能够在jsp页面上直接使用这些对象,一共有9个。<br>9大对象就是jsp页面翻译成java文件中创建的对象,所以可以可以在jsp页面中直接使用。<br>
<b>9大内置对象</b>
<ol><li><b><font color="#5c5c5c">page</font></b>:页面对象,java.lang.Object类型的page对象</li><li><b><font color="#c41230">request</font></b>:HttpServletRequest,javax.servlet.http.HttpServletRequest类型的request对象</li><li><b><font color="#c41230">response</font></b>:HttpServletResponse,javax.servlet.http.HttpServletResponse类型的response对象</li><li><b><font color="#c41230">session</font></b>:HttpSession,javax.servlet.http.HttpSession类型的session对象</li><li><b><font color="#f15a23">application</font></b>:ServletContext,javax.servlet.ServletContext类型的application对象</li><li><b><font color="#f15a23">out</font></b>:JspWriter,javax.servlet.jsp.JspWriter类型的out对象</li><li><b><font color="#f15a23">config</font></b>:ServletConfig,javax.servlet.ServletConfig类型的config对象</li><li><b><font color="#f15a23">exception</font></b>:Throwable,java.lang.Throwable类型的exception对象</li><li><b><font color="#c41230">pageContext</font></b>:pageContext,javax.servlet.jsp.PageContext类型的pageContext对象</li></ol><br>
<b>4大域对象</b>
<b>pageContext</b><br>
代表 page 域,但是 jsp 中 page 它的类型是 Object,所以操作 page 域我们使用的是 pageContext 对象,page 域就是指当前页面<br>
<font color="#c41230">作用在当前页面</font>
<b>request</b><br>
<font color="#c41230">作用在一次请求</font><br>
对应 Servlet 域对象:HttpServletRequest<br>
<b>session</b><br>
<font color="#c41230">作用在一次会话</font><br>
对应 Servlet 域对象:HttpSession<br>
<b>application</b><br>
<font color="#c41230">作用在整个项目</font><br>
对应 Servlet 域对象:ServletContext<br>
<b>pageContext</b> 域对象
① 获取其他内置对象
② 操作 page 域及其他域
<b>案例:JSP实现用户登陆</b>
login.jsp
UserServlet
BaseServlet
EL表达式
概念
el, expression language 是由 jsp 内置 jsp-api.jar 提供。<br>el 表达式用来替换 jsp 脚本。
格式
<b style=""><font color="#f15a23">${</font><font color="#000000">表达式</font><font color="#f15a23">}</font></b>
代替 <%=变量值%> jsp脚本。
操作
el 运算操作
算术、关系、逻辑、三目运算 Demo
字符串判断/判空
${str == 'hello'}<br>${str != 'hello'}<br>
${not empty str}<br>${empty str}
域对象操作 × 4<br>
获取方式
page域: <b><font color="#f15a23">${pageScope.</font><font color="#000000">name1</font><font color="#f15a23">}</font></b><br>
request域: <b><font color="#f15a23">${requestScope.</font><font color="#000000">name2</font><font color="#f15a23">}</font></b><br>
session域: <b><font color="#f15a23">${sessionScope.</font><font color="#000000">name3</font><font color="#f15a23">}</font></b>
application域: <b><font color="#f15a23">${applicationScope.</font><font color="#000000">name4</font><font color="#f15a23">}</font></b>
简写:${name}
注意事项:<br>* 如果 el 表达式没有获取到结果,返回的不是 null 而是 "" 空字符串;<br>* ${name} 不指定域的写法,jsp 页面就会从小到大的域数据进行查找:<br>pageScope -> requestScope -> sessionScope -> applicationScope<br>* 域中的共享数据一定要区别 name 的名字,以区别不同的域;
获取内容
数组 Demo
list Demo
map Demo
对象 Demo
web 对象操作 × 11<br>
包含 4 个域对象:<b><font color="#f15a23">pageScope / requestScope / sessionScope / applicationScope</font></b><br>包含 7 个 web 对象:<font color="#f15a23" style="">param / paramValues / initParam / header / headerValues /<b> cookie </b>/<b> pageContext</b></font><br>常用:4个域对象 + cookie + pageContext
param <==> request.getParameter()<br>paramValues <==> request.getParameters()<br>initParam <==> 获取初始化参数<br>header <==> 获取单个请求头<br>headerValues <==> 获取一组请求头<br>cookie <==> 获取 Map 类型的 cookie 对象<br>pageContext <==> 获取 jsp 内置的 9 大对象
Demo
<b>案例:3行实现访问量统计</b>
<%<br> Integer count = (Integer) application.getAttribute("count");<br> count = (count == null || count == 0) ? 1 : count+1;<br> application.setAttribute("count", count);<br>%><br>页面访问量:${count}次
jstl标签库
概念
jstl, java standard tag library 和 el 表达式结合使用,可以让功能更加强大。<br>
环境配置
WEB_INF/lib/ 导入jar包
<b><font color="#0076b3">jstl.jar</font></b><br>
<b><font color="#0076b3">standard.jar</font></b><br>
当前 jsp 页面导入标签库
<%@taglib prefix="<b><font color="#f15a23">c</font></b>" uri="<font color="#c41230">http://java.sun.com/<b>jsp/jstl/core</b></font>" %>
核心标签
set
向域中设置数据,等价于 域对象.setAttribute()<br>
<%-- set标签:往域中设置数据 --%><br><<font color="#f15a23">c:set</font> var="msg" scope="request" value="hello,jstl-set"/><br><%-- 获取 --%><br>${msg}
remove
将数据从域中移除,等价于 域对象.removeAttribute()<br>
<%-- remove标签:从域中移除数据 --%><br><<font color="#f15a23">c:remove</font> var="msg" scope="request"/><br><%-- 获取为空 --%><br>${msg}<br>
catch
捕获异常,等价于 try-catch<br>
<%-- catch标签:捕获异常 --%><br><<font color="#f15a23">c:catch</font> var="e"><br> <%<br> int num = 1/0;<br> %><br><<font color="#f15a23">/c:catch</font>><br><%-- 获取异常信息 --%><br>${e} <br><br>${e.message}<br>
if
条件判断<br>
<%-- if标签:条件判断 --%><br><c:set var="msg" scope="request" value="100"/><br><<font color="#f15a23">c:if</font> test="${msg == 100}"><br> msg 等于 100<br><<font color="#f15a23">/c:if</font>><br><br><c:if test="${msg != 100}"><br> msg 不等于 100<br></c:if><br>
foreach
遍历数组或集合
<%<br> List<String> strs = new ArrayList<>();<br> strs.add("hello");<br> strs.add("world");<br> strs.add("OMG");<br> request.setAttribute("strs", strs);<br>%><br>${strs.size()}<br><br><%-- forEach标签:等价于普通 for 循环 --%><br><<font color="#f15a23">c:forEach</font> var="i" begin="0" end="${strs.size()}" step="1"><br> ${strs[i]}<br><<font color="#f15a23">/c:forEach</font>><br><br><%-- forEach标签:等价于增强 for 循环 --%><br><<font color="#f15a23">c:forEach</font> var="str" items="${strs}" varStatus="status"><br> ${str} <br><br> 当前元素:${status.current} 下标:${status.index} 是否第1个元素:${status.first} 是否最尾元素:${status.last} <br><br><font color="#f15a23"></c:forEach></font><br><br><br>${strs[1]}<br>
fotTokens
分割字符串
<%-- forTokens标签:分割字符串 --%><br><%<br> String s = "hello:word:OMG";<br> request.setAttribute("s", s);<br>%><br><br><<font color="#f15a23">c:forTokens</font> items="${s}" delims=":" var="subStr" varStatus="status"><br> ${subStr}<br><<font color="#f15a23">/c:forTokens</font>>
格式化标签
随用随查
SQL 标签
随用随查
XML 标签
随用随查
JSTL 函数
随用随查
<b>综合案例:显示商品列表信息</b>
productList.jsp
bean.Product
dao.ProductDaoImpl
servlet.ProductServlet
开发模式
<b>JSP 模式</b>
① jsp+javaBean
jsp:请求处理、业务处理、数据库操作、数据显示<br>javaBean:数据封装
优点:开发简单<br>缺点:维护难,代码几乎都在 jsp 中
② jsp+javaBean+Servlet
jsp: 数据显示<br>Servlet: 请求处理、业务处理、数据库操作<br>javaBean: 数据封装<br>
优点:维护方便,开发各司其职利于模块分工,适合开发复杂项目,组件可以重用<br>缺点:开发难度大,对开发要求高<br>
<b><font color="#f15a23">BeanUtils</font> 框架</b><br>
导入3个 jar 包
<b><font color="#0076b3">commons-beanutils-1.9.4.jar<br>commons-collections-3.2.2.jar<br>commons-logging-1.2.jar</font></b><br>
jar 包下载:<br><font color="#0076b3">http://commons.apache.org/proper/commons-beanutils/download_beanutils.cgi</font><br>
要求:页面上的参数 name 名需要与Bean实体类的属性名完全一致。<br>
regist.jsp
<form action="/demo/reg" method="post"><br> 账号:<input type="text" name="username"> <br><br> 密码:<input type="text" name="password"> <br><br> 年龄:<input type="text" name="age"> <br><br> <button type="submit">注册</button><br></form><br>
RegServlet.doPost()
protected void doPost(... request, ... response) {<br> Map<String, String[]> map = request.getParameterMap();<br> User user = new User();<br> try {<br> BeanUtils.populate(user, map);<br> // 获取到封装了设置好jsp提交的参数的实例对象<br> System.out.println(user);<br> } catch (Exception e) {<br> e.printStackTrace();<br> }<br>}
User
public class User {<br> private Integer id;<br> private String username;<br> private String password;<br> private Integer age;<br> ...<br>}
自定义 MyBeanUtils.populate()
精简版的 BeanUtils 源码实现逻辑
<b><font color="#c41230">MVC 设计模式</font></b>
Model View Controller,经典设计模式,用一种业务逻辑,数据,界面分离的方式来组织代码,<br>将业务聚集到一个部件中,方便程序的重复使用,提高开发效率。
MVC 组成
<font color="#f15a23"><b>Model</b></font>
模型层,数据封装
<b><font color="#f15a23">View</font></b>
视图层,数据显示
<b><font color="#0076b3">三层架构</font></b>
<b style=""><font color="#f15a23">C</font><font color="#0076b3">ontroller</font></b>
控制层,请求处理
<font color="#0076b3"><b>Service</b></font>
业务层,业务逻辑
<b><font color="#0076b3">Dao</font></b>
持久层,数据库操作
<b>综合案例:JSP优化用户管理</b>
环境<br>
Tomcat 8.5<br>Intellij IDEA 2020.3<br>JDK 1.8
依赖
BeanUtils<br>DbUtils<br>C3p0<br>MySQL<br>JSTL
配置文件
c3p0.properties
https://simple.blog.csdn.net/article/details/105849671
分页查询
主要解决页面数据加载过多,导致页面访问速度变慢的问题
分类
逻辑分页
一次性全部查询出来,存放到List中,在List中截取subList作为页数据
优:减少操作数据库的次数<br>缺:数据量非常大,查询时间比较长
<b><font color="#c41230">物理分页</font></b>
页面查询一页,就从数据库里查询一页数量的数据
优:减少单次查询数据库的时间<br>缺:增加了操作数据库的次数
效果
第<b><font color="#c41230">1</font></b>/<b><font color="#c41230">10</font></b>页 总记录数:<b><font color="#c41230">100</font></b> 每页<b><font color="#c41230">10</font></b>条 [<font color="#0076b3">首页</font>] [<font color="#0076b3">上一页</font>] [<font color="#0076b3">下一页</font>] [<font color="#0076b3">尾页</font>]
请求和响应
请求
<font color="#0076b3">当前页数</font> currentPage
响应
<font color="#0076b3">当前页数</font> currentPage<br>
<font color="#c41230"><b>总页数</b></font> totalPage<br>
<font color="#c41230">总记录数</font> totalSize<br>
<font color="#c41230">每页记录数</font> pageSize<br>
<font color="#c41230"><b>当前页数据</b></font> pageList<br>
new ScalarHandler<>( )
恶补
源码案例
https://simple.blog.csdn.net/article/details/105868086
上传下载
上传 Upload
本质就是将一台电脑中的文件根据网络协议通过 io 流传递到另一台电脑(服务器)上。
三要素
表单数据提交方式 <font color="#c41230">POST</font>
表单中设置文件上传项 <input type="<font color="#c41230">file</font>">
enctype=multipart/form-data
实现步骤
导入 jar 包
<font color="#0076b3">commons-fileupload-1.4.jar</font><br>
<font color="#0076b3">commons-io-2.6.jar</font>
前台:文件上传项(JSP)
<form action="${pageContext.request.contextPath}/upload" method="<b><font color="#c41230">post</font></b>" <font color="#f15a23">enctype</font>="<b><font color="#c41230">multipart/form-data</font></b>"><br> 描述:<input type="text" name="desc"> <br><br> 上传附件:<input <font color="#f15a23">type</font>="<b><font color="#c41230">file</font></b>" name="file"> <br><br> <button type="submit">提交</button><br></form><br>
后台:编写 Servlet
1. 创建磁盘文件项工厂对象 <font color="#f15a23">DiskFileItemFactory</font><br>2. 创建核心解析类 <font color="#f15a23">ServletFileUpload</font><br>3. 解析请求,获取到所有的文件项
文件上传API
<b><font color="#f15a23">ServletFileUpload</font></b> 核心解析类
<font color="#f15a23">parseRequest</font>(HttpServletRequest request) 解析请求,并获取相关文件项
<font color="#f15a23">setHeaderEncoding</font>(String encoding) 解决中文<font color="#c41230">文件名乱码</font>
<b><font color="#f15a23">FileItem</font></b> 文件项
boolean <font color="#f15a23">isFormField</font>() 返回为true,普通字段。返回为<font color="#c41230">false,就是文件</font>
String <font color="#f15a23">getFieldName</font>() 获取表单 name 字段
String <font color="#f15a23">getString</font>(String encoding) 根据指定编码格式获取字段值,解决<font color="#c41230">描述文本中文乱码</font>
String <font color="#f15a23">getName</font>() 获取上传文件名称
InputStream <font color="#f15a23">getInputStream</font>() 获取上传文件对应的输入流
乱码和重复问题
文件名中文乱码
// 1. 创建磁盘文件项工厂对象<br>// 2. 创建核心解析对象<br>ServletFileUpload servletFileUpload = new ServletFileUpload(new DiskFileItemFactory());<br>// 解决文件名中文乱码问题<br>servletFileUpload.<font color="#f15a23">setHeaderEncoding</font>("<b><font color="#16884a">utf-8</font></b>");
描述内中文乱码
// 判断 fileItem 是否是上传的文件<br>if (fileItem.isFormField()) {<br> // true:其他的 form 项<br> // 描述 text 的中文内容乱码问题<br> System.out.println(fileItem.<font color="#f15a23">getString</font>("<b><font color="#16884a">utf-8</font></b>"));<br>} else { ... }
文件名重复问题
// 文件名 = 当前时间毫秒值 + 用户名(不重复) + 文件名<br>String path = serverPath + File.separator + <b>System.currentTimeMillis() + "-" + username + "-" + fileItem.</b><font color="#f15a23" style="">getName</font><b>();</b>
文件上传+数据库
bean
dao
service
controller
UploadServlet
FileListServlet
下载 Download
本质就是将一台电脑(服务器)中的文件根据网络协议通过 io 流传递到另外一台电脑上。
两种形式
超链接
浏览器支持的文件格式,可在浏览器打开;浏览器不支持才会提示下载
手动编写代码的方式下载
实现步骤
下载入口
<a href="${pageContext.request.contextPath}/download?<b><font color="#000000">fileName</font></b>=${file.fileName}">下载</a>
设置媒体类型
// 1. 设置媒体类型 <- 获取下载文件的媒体类型<br>String fileName = request.getParameter("<b><font color="#000000">fileName</font></b>");<br>String mimeType = request.getServletContext().<font color="#f15a23">getMimeType</font>(fileName);<br><b>response</b>.<font color="#f15a23">setContentType</font>(mimeType);
设置下载窗口
String userAgent = request.getHeader("User-Agent");<br>String newFileName = userAgent.contains("Chrome") ? URLEncoder.encode(fileName, "utf-8") : base64EncodeFileName(fileName);<br>// 2. 设置下载窗口 -> Content-Disposition<br>response.<font color="#f15a23">setHeader</font>("<b><font color="#c41230">Content-Disposition</font></b>", "<b><font color="#c41230">attachment;filename=</font></b>" + newFileName);
IO读写(写-响应给浏览器)
// 3. IO读写文件: 读出服务器文件,响应写入到浏览器<br>String path = request.getServletContext().<font color="#f15a23">getRealPath</font>("upload") + File.separator + fileName;<br>BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path));<br>BufferedOutputStream bos = new BufferedOutputStream(<b>response</b>.<font color="#f15a23">getOutputStream</font>());<br>byte[] bs = new byte[8*1024];<br>int size = -1;<br>while ((size = bis.read(bs)) != -1) {<br> bos.write(bs, 0, size);<br>}<br>bis.close();<br>bos.close();
下载文件名中文乱码问题
不同浏览器编码方式不同:对文件名进行编码时以谷歌为代表的是 <font color="#c41230">utf-8</font>,其他浏览器是 <font color="#c41230">base64</font>
根据浏览器在下载窗口前设置编码方式
String userAgent = request.getHeader("User-Agent");<br>String newFileName = userAgent.contains("Chrome") ? URLEncoder.encode(fileName, "utf-8") : base64EncodeFileName(fileName);<br>response.setHeader("Content-Disposition", "attachment;filename=" + newFileName);<br>
base64编码
public String <font color="#f15a23"><i>base64EncodeFileName</i></font>(String fileName) {<br> BASE64Encoder base64Encoder = new BASE64Encoder();<br> try {<br> return "=?UTF‐8?B?"<br> + new String(base64Encoder.encode(fileName.getBytes("UTF-8")))<br> + "?=";<br> } catch (Exception e) {<br> e.printStackTrace();<br> throw new RuntimeException(e);<br> }<br>}
正则表达式
概述
用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串。即一种规则,有自己特殊的应用。
作用
1. <font color="#c41230">匹配</font><br> 测试字符串内的模式。例如,可以测试输入字符串,以查看字符串内是否出现电话号码模式或信用卡号码模式。这称为数据验证。<br>2. <font color="#c41230">替换</font><br> 可以使用正则表达式来识别文档中的特定文本,完全删除该文本或者用其他文本替换它。<br>3. <font color="#c41230">提取</font><br> 基于模式匹配从字符串中提取子字符串,可以查找文档内或输入域内特定的文本。
方法和类
String 成员方法:<br>boolean <font color="#f15a23">matches</font>(String regex); // 正则匹配<br>String[] <font color="#f15a23">split</font>(String regex); // 正则分割<br>String <font color="#f15a23">replaceFirst</font>(String regex, String replacement); // 正则替换第1个<br>String <font color="#f15a23">replaceAll</font>(String regex, String replacement); // 正则替换所有
Pattern 类<br>Matcher 类<br>
Pattern 类:<br>public static Pattern <font color="#f15a23">compile</font>(String regex); // 编译正则<br>public Matcher <font color="#f15a23">matcher</font>(CharSequence input); // 匹配正则对象<br><br>Matcher 类:<br>boolean <font color="#f15a23">find</font>() // 查找匹配子串<br>String <font color="#f15a23">group</font>() // 返回匹配子串<br>String replaceAll(String replacement) // 替换所有<br>String replaceFirst(String replacement) // 替换第一个 <br>
匹配用法
String reg = "[a]{3}";<br>Pattern pattern = Pattern.<b><font color="#f15a23">compile</font></b>(reg);<br>Matcher matcher = pattern.<b><font color="#f15a23">matcher</font></b>("aaa");<br>boolean b = matcher.<b><font color="#f15a23">matches</font></b>();<br>System.out.println(b); // true
提取用法
String s = "18937162148...safsdfa.f.ds.afsdf18566206696a651sdfas18937111765";<br>String reg = "[1]{1}[356789]{1}\\d{9}";<br>Pattern pattern = Pattern.<b><font color="#f15a23">compile</font></b>(reg);<br>Matcher matcher = pattern.<b><font color="#f15a23">matcher</font></b>(s);<br>List<String> phones = new ArrayList<>();<br>// find() 查找匹配的子字符串<br>while (matcher.<b><font color="#f15a23">find</font></b>()) {<br> // group() 返回匹配的子字符串<br> phones.add(matcher.<b><font color="#f15a23">group</font></b>());<br>}<br>System.out.println(phones);
正则规则
单字符类
● `[abc]` a/b/c任意1个<br>● `[^abc]` 除了a/b/c的任何字符<br>● `[a-zA-Z]` a到z或A到Z含边界字符<br>● `[0-9]` 0-9之间的字符都包括<br>
预定义字符类/元字符
● `.` 任意1个字符<br>● `\d` 单个数字 [0-9]<br>● `\D` 非数字 [^0-9]<br>● `\w` 单词字符 [a-zA-Z_0-9]<br>● `\W` 非单词字符 [^\w]<br>● `\s` 空白字符 [\t\n\x0B\f\r]<br>● `\S` 非空白字符 [^\s]<br>
数量词
X 表示一个字符或者预定义字符<br>● `X?` 0或1次<br>● `X*` 0到n次<br>● `X+` 1到n次<br>● `X{n}` n次<br>● `X{n,}` 至少n次<br>● `X{n,m}` 至少n次,不超过m次<br>
JavaScript
概述
概念
一门客户端脚本语言。<br>
作用
可以用来增强用户和 html 页面的交过过程,可以控制 html 元素,让页面有一些动态的效果,增强用户体验。
发展
1992,Nombase开发,用于表单校验,ScriptEase<br>1995,Netscape(网景)开发LiveScript,SUN公司更名JavaScript<br>1997,ECMA协会制定标准ECMAScript,统一了所有客户端脚本语言的编码方式<br>总结:<b>JavaScript</b> = <b><font color="#c41230">ECMAScript</font></b> + JavaScript(<b><font color="#c41230">BOM</font></b>+<b><font color="#c41230">DOM</font></b>)
输出
<ul><li>使用 <b>window.alert()</b> 弹出警告框。</li><li>使用 <b>document.write()</b> 方法将内容写到 HTML 文档中。</li><li>使用 <b>innerHTML</b> 写入到 HTML 元素。</li><li>使用 <b>console.log()</b> 写入到浏览器的控制台。</li></ul>
使用 console.log() 方法在浏览器中显示 JavaScript 值。<br>F12 启用调试模式, 在调试窗口中点击 "Console" 菜单。<br><font color="#c41230">console.log()的用处</font>:<br>主要是方便你调式javascript用的, 你可以看到你在页面中输出的内容。<br>相比alert他的优点是:<br>他能看到结构化的东西,如果是alert,弹出一个对象就是[object object],但是console能看到对象的内容。<br>console不会打断你页面的操作,如果用alert弹出来内容,那么页面就死了,但是console输出内容后你页面还可以正常操作。<br>console里面的内容非常丰富,你可以在控制台输入 console.log("hello,javascript")
语法
使用
内部JS
定义<b><font color="#f15a23"><script></font></b>标签,标签内就是js代码
<head><br> <title>ECMAScript和页面结合之内部结合</title><br> <%--JS脚本内部结合--%><br> <<font color="#f15a23">script</font>><br> console.log("js脚本111")<br> <<font color="#f15a23">/script</font>><br></head>
外部JS
定义<script>,通过<b><font color="#f15a23">src</font></b>属性引入外部的js文件
<head><br> <title>ECMAScript与页面结合之外部结合</title><br> <script <font color="#f15a23">src</font>="<b><font color="#000000">${pageContext.request.contextPath}/xxx.js</font></b>"><br> /*外部结合方式后,script 标签内js代码无效*/<br> </script><br></head>
注意
a. <script>可以定义在页面的任何地方,<font color="#c41230">位置会决定执行顺序</font><br>b. <script>可以定义多个
注释
单行 //<br>多行 /* */
类型
基本数据类型
<ul><li><b><font color="#f15a23">number</font></b>:数字,整数/小数/NaN(一个不是数字的number类型)</li><li><b><font color="#f15a23">string</font></b>:字符串,"hello" 'abc'</li><li><b><font color="#f15a23">boolean</font></b>:true 和 false</li><li><b><font color="#f15a23">null</font></b>:一个对象为空的占位符</li><li><b><font color="#f15a23">undefined</font></b>:未定义,变量没有初始化时的初始值</li></ul>
引用数据类型
<ul><li><b><font color="#f15a23">对象</font></b></li></ul>
基本对象:<br>Array / Boolean / Date / Number / String / RegExp / Functions(全局函数对象) / Math / Events<br>
Function对象
创建方法
var 方法名 = new Function("形式参数列表", "方法体");
变量
Java是强类型语言,JavaScript是弱类型语言。
语法
<b><font color="#f15a23">var</font></b> 变量名 = 初始化值;
<b><font color="#f15a23">typeof</font></b>
获取变量的类型。
<script><br> console.log(typeof 123); // number<br> console.log(typeof "abc"); // string<br> console.log(typeof true); // boolean<br> console.log(typeof null); // object<br> console.log(typeof NaN); // number<br> console.log(typeof num); // undefined<br> console.log(typeof [1,2,3]);// object<br> console.log(typeof {"name":"Jerry", "age":20}); // object<br></script>
运算符
<ul><li>一元:++ --</li><li>算术:+ - * / %</li><li>赋值:= += -=</li><li>比较:> < >= <= == <b><font color="#c41230">===</font></b>(全等于)</li><li>逻辑:&& || !</li><li>三元:表达式 ? 值1 : 值2</li><li>流程:if-else switch-case while do-while for try-catch</li></ul>
比较方式:<br>1. 类型相同:直接比较,字符串按照字典顺序比较;<br>2. 类型不同:先进行类型转换,再比较;(=== 全等于,类型和值都比较,先判断类型,类型不同,直接返回false)<br>switch分支:<br>1. Java中 switch 可接收的数据类型:byte int short char 枚举(jdk1.5) String(jdk1.7);<br>2. JS中 switch 可接收的数据类型:任意JS中的基本数据类型
注意事项
number:0或者NaN为 false,其他为 true<br>string:除了空字符串""为 false,其他为 true<br>null 和 undefined:都是 false<br>对象:所有对象都是 true
demo
a标签
<a href="#">跳转</a><br>// 死链接,点击跳转时页面和链接不会发生变化<br><a href="javascript:void(0)">跳转</a><br>// 死链接,void中内容会执行但不会有任何返回<br><a href="javascript:void(alert('Warning'))">跳转</a><br>
引用
Array 对象
demo
Date 对象
demo
RegExp 对象
<b><font color="#f15a23">/^</font></b>正则表达式<b><font color="#f15a23">$/</font></b>
demo
全局函数对象
<font color="#f15a23">parseInt</font>() // 数字字符串转换为数字<br><font color="#f15a23">isNaN</font>() // 判断变量是否是NaN<br><font color="#f15a23">eval</font>() // 多用于<font color="#c41230">转换json字符串为js对象</font>,以调用属性
<script><br> // eval() 更多的用于 json 字符串返回 js 对象<br> var jsonStr = '{"username":"root", "password":"1234"}';<br> var obj = <b><font color="#f15a23">eval("(" + </font>jsonStr<font color="#f15a23"> + ")");</font></b> // 固定语法,将json字符串转换成js对象<br> console.log(<b><font color="#c41230">obj.</font>username</b> + "," + <b><font color="#c41230">obj.</font>password</b>);<br></script>
demo
函数
三种方式
// 第一种方式<br><font color="#f15a23">function</font> method01(msg1, msg2, msg3) {<br> console.log(msg1 + ",", msg2 + "," + msg3);<br> // arguments: 属于方法的内置对象,包含的是实参<br> for (var i = 0; i < <font color="#f15a23">arguments</font>.length; i++) {<br> console.log(arguments[i]);<br> }<br> return "hello js function!";<br>}<br>// 调用<br>var returnValue1 = method01("a", "b", "c");<br>console.log(returnValue1);
// 第二种方式<br>var method02 = <font color="#f15a23">function</font> (msg1, msg2, msg3) {<br> console.log(msg1 + ",", msg2 + "," + msg3);<br> return "hello js function2";<br>};<br>// 调用<br>var returnValue2 = method02("d", "e", "f");<br>console.log(returnValue2);
// 第三种方式 - 基本不用<br>var method03 = new Function("msg1, msg2, msg3", "console.log(msg1 + \",\", msg2 + \",\" + msg3); return \"hello js function3\";");<br>// 调用<br>var returnValue3 = method03("h", "i", "j");<br>console.log(returnValue3);
JavaScript 支持 内嵌函数(类似于成员内部类)
JavaScript 闭包
<script><br> /* JavaScript 闭包:能够访问父作用域中的变量,提高了局部变量的生命周期。*/<br> var add = <b>(function () {</b> //自执行的匿名函数<br> var count = 0; // 局部变量<br> return function () { // 内部函数, 把方法返回,赋值给了变量result<br> return count += 1; // 访问外部自执行函数的局部变量<br> }<br> <b>})()</b>;<br> console.log(result()); // 1<br> console.log(result()); // 2<br> console.log(result()); // 3<br></script>
JSON字符串
JavaScript Object Notation 一种轻量级的数据交换格式。<br>易于阅读和编写,同时易于机器解析和生成(网络传输速率)。
<font color="#c41230">同步请求</font>中,数据从后台到前端,需要将数据对象存储在 <b><font color="#c41230">域对象</font></b> 中;<br><font color="#c41230">异步请求</font>中,数据从后台到前端,需要将数据对象转换为 <b><font color="#c41230">JSON 字符串</font></b>。<br>根据 JavaBean 对象生成对应的 JSON 字符串。
JavaBean 有单一对象,容器对象,JSON对单一对象和容器对象有不同的写法。
数据格式
一个数据
{"键1":值1, "键2":值2}
一组数据
[{"键1":值1, "键2":值2}, {"键1":值1, "键2":值2}]
Java中转换
<b><font color="#c41230">FastJSON</font></b>、<b><font color="#c41230">Jackson</font></b>、<b><font color="#c41230">Gson</font></b>
性能对比分析
<b><font color="#c41230">FastJson</font></b>
<b><font color="#0076b3">fastjson-1.2.62.jar</font></b>
对象 >>> json字符串
// 可转对象/list/map >> json<br>User user = new User("root", "1234");<br>String jsonStr = <b><font color="#662c90">JSON</font></b>.<font color="#f15a23">toJSONString</font>(user);
json字符串 >> 对象
// 可转json字符串 >> 为java对象/list/map<br> String jsonStr = "{'username':'root', 'password':'1234'}";<br>User user = <b><font color="#662c90">JSON</font></b>.<font color="#f15a23">parseObject</font>(jsonStr, User<b><font color="#c41230">.class</font></b>);
<font color="#c41230">Jackson</font>
<b><font color="#0076b3">jackson-annotations-2.9.9.jar<br>jackson-core-2.9.9.jar<br>jackson-databind-2.9.9.jar</font></b><br>
ObjectMapper <b>objectMapper</b> = <font color="#c41230">new</font> <b><font color="#f15a23">ObjectMapper</font></b>();<br>
对象 >> json字符串
// 可转对象/list/map >> json<br>User user = new User("root", "1234");<br>String jsonStr = <b>objectMapper</b>.<font color="#f15a23">writeValueAsString</font>(user);<br>
json字符串 >> 对象
// 可转json字符串 >> 为java对象/list/map<br>String jsonStr = "{'username':'root', 'password':'1234'}";<br>User user = <b>objectMapper</b>.<font color="#f15a23">readValue</font>(jsonStr, User<font color="#c41230"><b>.class</b></font>);<br>
<font color="#c41230">Gson</font>
<b><font color="#0076b3">gson.jar</font></b>
Gson <b>gson</b> = <font color="#c41230">new</font> <b><font color="#f15a23">Gson</font></b>();<br>
对象 >> json字符串
// 可转对象/list/map >> json<br>User user = new User("root", "1234");<br>String jsonStr = <b>gson</b>.<font color="#f15a23">toJson</font>(user);
json字符串 >> 对象
// 可转json字符串 >> 为java对象/list/map<br> String jsonStr = "{'username':'root', 'password':'1234'}";<br>User user = <b>gson</b>.<font color="#f15a23">fromJson</font>(jsonStr, User<b><font color="#c41230">.class</font></b>);
JavaScript中转换
<script><br> // 方式一:JSON.stringify() JSON.parse()<br> var user = {"username": "root", "password": "1234"};<br> // JS >> JSON<br> var str = <b><font color="#662c90">JSON</font></b>.<font color="#f15a23">stringify</font>(user);<br> alert(str);<br> // JSON >> JS<br> var js = <b><font color="#662c90">JSON</font></b>.<font color="#f15a23">parse</font>(str);<br> alert(js.username + ", " + js.password);<br></script>
<script><br> // 方式二:eval() 更多的用于 json 字符串返回 js 对象<br> var jsonStr = '{"username":"root", "password":"1234"}';<br> var obj = <b><font color="#f15a23">eval("(" + </font>jsonStr<font color="#f15a23"> + ")");</font></b> // 固定语法,将json字符串转换成js对象<br> console.log(<b><font color="#c41230">obj.</font>username</b> + "," + <b><font color="#c41230">obj.</font>password</b>);<br></script>
事件
事件参考手册
触发条件
事件源:html标签<br>监听器:js方法<br>绑定/注册:标签中的属性赋值<br>事件:具体的操作
<%--事件源 + <b><font color="#c41230">绑定方式①</font></b>--%><br>// 监听器<br>function <b>fn1</b>() {<br> console.log("按钮1点击了...");<br>}<br>...<br><button <font color="#f15a23">onclick</font>="<b>fn1()</b>">事件按钮1</button><br><br>
<%--事件源 + <b><font color="#c41230">绑定方式②</font></b>--%><br>// 获取 id 为 btn 的标签对象<br>var ele = <font color="#f15a23">document.getElementById</font>("<b>btn</b>");<br>// fn2 使用方式 ① -- 最佳<br>ele.<font color="#f15a23">onclick</font> = <b>function</b> () {<br> console.log("按钮2点击了...");<br>}<br>...<br><button id="btn">事件按钮2</button><br>
<%--事件源 + <b><font color="#c41230">绑定方式②</font></b>--%><br>// 获取 id 为 btn 的标签对象<br>var ele = <font color="#f15a23">document.getElementById</font>("<b>btn</b>");<br>// fn2 使用方式 ② - 不推荐<br>function <b>fn2</b>() {<br> console.log("按钮2点击了...");<br>}<br>ele.onclick = <b>fn2</b>;<br>...<br><button id="<b>btn</b>">事件按钮2</button><br>
监听事件
加载
<b><font color="#f15a23">onload</font></b>
页面或图像加载完成
图像
function <b>fn1()</b> {<br> console.log("这是个图片。。");<br>}<br>...<br><img src="img/girl.jpg" <font color="#f15a23">onload</font>="<b>fn1()</b>">
页面
// 如果<font color="#c41230"><b>使用 dom 分配事件,推荐该方式</b></font>(获取标签id的js代码可写在页面上方)<br>// 监听页面加载完成后的操作<br>window.<font color="#f15a23">onload</font> = <b>function</b> () {<br> console.log("页面加载完成");<br> var ele = document.<font color="#f15a23">getElementById</font>("girl");<br> ele.onclick = <b>function</b> () {<br> console.log("我正在疯狂的点击图片...");<br> }<br>}<br>...<br><img id="girl" src="img/girl.jpg"><br>
onunload
用户退出页面
onabort
图像加载被中断
onerror
当加载文档或图像时发生某个错误
焦点
<font color="#f15a23">onfocus</font>
元素获得焦点<br>
<script><br>function fn1() { console.log("1 获取焦点"); }<br>function fn2() { console.log("2 失去焦点"); }<br>function fn3() { console.log("3 获取焦点"); }<br>function fn4() { console.log("4 失去焦点"); }<br></script><br><input type="text" <b>onfocus</b>="fn1()" <b>onblur</b>="fn2()"> <br><br><input type="text" <b>onfocus</b>="fn3()" <b>onblur</b>="fn4()">
<font color="#f15a23">onblur</font>
元素失去焦点
鼠标
<font color="#f15a23">onclick</font>
鼠标单击某个对象
ondblclick
鼠标双击某个对象
<font color="#f15a23">onmousedown</font>
鼠标的按键被按下
<script><br>function fn1() { console.log("鼠标按下"); }<br>function fn2() { console.log("鼠标移动"); }<br>function fn3() { console.log("鼠标松开"); }<br></script><br><body <b>onmousedown</b>="fn1()" <b>onmousemove</b>="fn2()" <b>onmouseup</b>="fn3()">
<font color="#f15a23">onmouseup</font>
鼠标的按键被松开
<font color="#f15a23">onmousemove</font>
鼠标移动
onmouseover
鼠标移到某个元素上
onmouseout
鼠标从某个元素移开
键盘
<font color="#f15a23">onkeydown</font>
键盘的键被按下
<script><br>function fn1() { console.log(<font color="#c41230">event.keyCode</font> + " 键盘按下 "); }<br>function fn2() { console.log(<font color="#c41230">event.keyCode</font> + " 键盘松开 "); }<br></script><br><input type="text" <b>onkeydown</b>="fn1()" <b>onkeyup</b>="fn2()">
onkeypress
键盘的键被按下或按住
<font color="#f15a23">onkeyup</font>
键盘的键被松开
按钮
onreset
重置按钮被点击
<font color="#f15a23">onsubmit</font>
提交按钮被点击
<script><br>function fn1() {<br> console.log("表单提交了..."); <br> var num = 1; // 数据校验<br> if (num === 1) { return true; // 不拦截表单 } else { return false; // 拦截表单提交 }<br>}<br></script><br><%-- return fn1() --%><br><form action="index.jsp" <b>onsubmit</b>="<b><font color="#c41230">return</font></b> fn1()"><br>消息:<input type="text" name="message"> <br><br><button type="submit">发送</button><br></form>
其他
<font color="#f15a23">onchange</font>
用户改变了内容
<script><br>function fn1() { console.log("内容发生改变"); }<br>function fn2() { console.log("选项发生改变..."); }<br></script><br><input type="text" <b>onchange</b>="fn1()"><br><select <b>onchange</b>="fn2()"><br><option>选项1</option><br><option>选项2</option><br><option>选项3</option><br></select>
onselect
文本被选定
onresize
窗口或框架被调整尺寸
BOM 对象
Browser Object Model,浏览器对象模型
<font color="#f15a23">window</font> 对象
属性
可以通过 window 对象获取其他4个BOM对象<br><ul><li><b style="font-size: inherit;"><font color="#f15a23">document</font></b><span style="font-size: inherit;"> 对 Document 对象的只读引用。</span><br></li><li><b>history</b> 对 History 对象的只读引用。<br></li><li><b style="font-size: inherit;">location</b><span style="font-size: inherit;"> 用于窗口或框架的 Location 对象。<font color="#c41230">可以设置页面跳转路径</font></span><br></li><li><b style="font-size: inherit;">Navigator</b><span style="font-size: inherit;"> 对 Navigator 对象的只读引用。</span><br></li><li><b style="font-size: inherit;">Screen</b><span style="font-size: inherit;"> 对 Screen 对象的只读引用。</span></li></ul>
方法
<ul><li><font color="#f15a23" style="font-size: inherit;">alert</font><span style="font-size: inherit;">(message) 显示带有一段消息和一个确认按钮的<font color="#c41230">警告框</font>。</span></li><li><font color="#f15a23" style="font-size: inherit;">confirm</font><span style="font-size: inherit;">(message) 显示带有一段消息以及<font color="#c41230">确认/取消对话框</font>。</span></li><li><font color="#f15a23" style="font-size: inherit;">prompt</font><span style="font-size: inherit;">([text], [defaultText]) 显示可<font color="#c41230">提示用户输入对话框</font>。<br></span></li><li>close() 关闭浏览器窗口 - 必须是新开的页面窗口才能关闭。</li><li><font color="#f15a23" style="font-size: inherit;">clearInterval</font><span style="font-size: inherit;">(重复对象) 清除由 setInterval() 设置的调用。</span></li><li><font color="#f15a23" style="font-size: inherit;">clearTimeout</font><span style="font-size: inherit;">(延迟对象) 清除由 setTimeout() 方法设置的调用。</span></li><li><font color="#f15a23" style="font-size: inherit;">setInterval</font><span style="font-size: inherit;">(code, millisec[, "lang"]) 按照间隔的周期(毫秒)来调用函数或计算表达式。返回值是重复对象</span></li><li><font color="#f15a23" style="font-size: inherit;">setTimeout</font><span style="font-size: inherit;">(code, millisec) 在<font color="#c41230">延迟</font>毫秒数后调用函数或计算表达式。返回值是延迟对象</span></li></ul><span style="font-size: inherit;"></span>
demo
navigator 对象
screen 对象
<font color="#f15a23">history</font> 对象
属性
<ul><li>length 返回浏览器历史列表中的 URL 数量。</li></ul>
方法
<ul><li>back() 加载 history 列表中的前一个 URL。</li><li>forward() 加载 history 列表中的下一个 URL。</li><li>go() 加载 history 列表中的某个具体页面。</li></ul>
demo
<font color="#f15a23">location</font> 对象
属性
<ul><li>hash 设置或返回从井号 (#) 开始的 URL(锚)。</li><li>host 设置或返回主机名和当前 URL 的端口号。</li><li>hostname 设置或返回当前 URL 的主机名。</li><li>href 设置或返回完整的 URL。</li><li>pathname 设置或返回当前 URL 的路径部分。</li><li>port 设置或返回当前 URL 的端口号。</li><li>protocol 设置或返回当前 URL 的协议。</li><li>search 设置或返回从问号 (?) 开始的 URL(查询部分)。</li></ul>
方法
<ul><li>assign() 加载新的文档。<br></li><li>reload() 重新加载当前文档。<br></li><li>replace() 用新的文档替换当前文档。</li></ul>
demo
XML DOM
核心 DOM 模型:document + element + node
<font color="#f15a23">document</font> 文档对象
<font color="#f15a23">element</font> 元素对象
<font color="#f15a23">node</font> 节点对象
HTML DOM
HTML DOM 定义了访问和操作 HTML 文档的标准方法。<br>HTML DOM 把 HTML 文档呈现为带有元素、属性和文本的树结构(节点树)。
<b><font color="#f15a23">innerHTML</font></b> / <b><font color="#f15a23">innerText</font></b>
使用 HTML 元素对象的属性
控制元素样式
JS:综合案例
获取 select 下所有的 option 中的文本信息
获取 select 下选中的 option 中的文本信息和 value 属性的值
在 select 下增加一个选项
全选 & 全不选 & 反选
正则校验的注册表单
Ajax
基本信息
概述
Asynchronous Javascript And XML,<b><font color="#c41230">异步 JavaScript 和 XML</font></b>,一种创建交互式网页应用的网页开发技术。
原理
通过在后台与服务器进行少量数据交换,AJAX可以是网页实现异步更新。<br>这意味着可以在不重新加载整个网页的情况下,对网页的部分内容进行更新。<br>(普通不适用AJAX的网页如果需要更新则必须刷新整个页面内容)
作用
1. 可以刷新局部页面内容<br>2. 可以发起异步请求
异步&同步请求
<ul><li>同步请求:当页面内容发生改变时,必须全部刷新,且刷新的时候不能发出其他请求。</li><li>异步请求:可以局部改变网页的内容,当正在发生改变时,其他的模块内容也可以发出请求。</li></ul>
<b><font color="#f15a23">XMLHttpRequest</font> 对象</b>
ajax异步请求对象。<br>
流程
典型的xhr建立ajax的过程:<br>1、new一个xhr对象;<br>2、调用xhr对象的open方法;<br>3、send一些数据;<br>4、对服务器的响应过程进行监听,来知道服务器是否正确得做出了响应,接着就可以做一些事情。比如获取服务器响应的内容,在页面上进行呈现。
创建
function createXMLHttpRequest() {<br> var xmlHttp;<br> try {<br> // IE7+, Chrome, Firefox, Opera 8.0+, Safari 主流浏览器<br> xmlHttp = new <font color="#f15a23">XMLHttpRequest</font>();<br> } catch (e) {<br> try {<br> // IE6, IE5 浏览器<br> xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");<br> } catch (e) {<br> try {<br> // 其他浏览器<br> xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");<br> } catch (e) {<br> // Nothing to do.<br> }<br> }<br> }<br> return xmlHttp;<br>}<br>var <b><font color="#662c90"><i>xhr</i></font></b> = createXMLHttpRequest();
属性
<font color="#f15a23">onreadystatechange</font>, 用于指定XMLHttpRequest对象状态改变时的事件处理函数
响应
<font color="#f15a23">status </font>/ <font color="#f15a23">statusText</font>:以数字/文本形式返回http状态码
<font color="#f15a23">readyState</font>, XMLHttpRequest对象的处理状态,响应返回成功的时候得到通知<br><ul><li><span style="font-size: inherit;">0 :请求未初始化,open还没有调用</span></li><li><span style="font-size: inherit;">1 :服务器连接已建立,open已经调用了</span></li><li><span style="font-size: inherit;">2 :请求已经接收,也就是接收到头信息了</span></li><li><span style="font-size: inherit;">3 :请求处理中,也就是接收到响应主体了</span></li><li><span style="font-size: inherit;">4 :请求已完成,且响应已就绪,也就是响应完成了</span></li></ul>
* <font color="#c41230">当 </font><b style="color: rgb(196, 18, 48);">status === 200</b> <b style=""><font color="#000000">&&</font></b> <b style="color: rgb(196, 18, 48);">readyState === 4</b><font color="#c41230"> 时才去读取响应数据。</font>
<font color="#f15a23" style="font-size: inherit;">responseText </font><span style="font-size: inherit;">/ <font color="#f15a23">responsXML</font>:获得字符串/XML形式的相应数据</span><br>
<font color="#f15a23">getAllResponseHeader</font>():获取所有的响应报头
<font color="#f15a23">getResponseHeader</font>():查询响应中的某个字段的值
方法
open, 打开链接
<font color="#f15a23">open</font>(请求方式, 请求路径, <font color="#c41230"><b>flag</b></font>); // flag==<font color="#c41230">true 异步请求</font>, false 同步请求
setRequestHeader, 设置请求头
<font color="#f15a23">setRequestHeader</font>("<font color="#000000">Content-Type</font>", "<font color="#000000">application/x-www-form-urlencoded</font>");
模拟form表单,<font color="#c41230">专用于POST请求</font>
send, 发送数据
<font color="#f15a23">send</font>(数据);
<font color="#c41230">GET请求,send 方法不需要携带参数,直接将参数拼接在 open 方法的路径后面</font><br>POST 请求,需要 send 方法带参来发送
异步 GET/POST请求
GET 请求
demo
POST 请求
demo
注意事项
在以下情况中,请使用 POST 请求:<br><ol><li><font color="#c41230">无法使用缓存文件</font>(更新服务器上的文件或数据库)</li><li>向服务器<font color="#c41230">发送大量数据</font>(POST 没有数据量限制)</li><li>发送<font color="#c41230">包含未知字符的用户输入</font>时,POST 比 GET 更稳定也更可靠</li></ol>
CodePart
Java<br>
枚举
四舍五入
Stream流
Thread
MySQL
0 条评论
下一页