HTML&XML
1.JavaWeb的概述
A: 什么是Web----->就是网页或者网站
B: 什么是JavaWeb----->就是使用java语言做web
C: 浏览器访问网站的原理 && 静态资源和动态资源的区别
2. Html的概述
Html: Hyper Text Markup Language 超文本标记语言
超文本: 超出纯文本的范畴
标记语言: 标记其实就是标签 标签的格式: <标签名称>
3. Html文档的组成以及标签规范
A: Html文档的组成
(1): <html></html>来明确html文档的范围
(2): <head></head>标签可以设置一个内容比如: <title></title>
(3): <body></body>标签设置要在页面显示的内容
B: Html标签的规范
(1): Html标签通常是成对出现的,比如 <b> 和 </b>
(2): 标签对中的第一个标签是开始标签,第二个标签是结束标签
(3): 绝大多数的标签都具有属性,建议属性值使用引号引起。例如:<body text=”red”>
(4): 大多数标签是可以嵌套的
(5): Html标签是不区分大小写的
(6): Html文件的后缀名是html或者htm
4. Html标签之文字标签和注释标签
注释标签: <!-- 注释的文字 -->
文字标签:
(1): 标签格式: <font>具体的文字</font>
(2): 标签的属性
(a)size: 指定文字的大小,取值范围值是1~7.如果取值超出7按照7进行设置 ;如果取值小于1,按照1进行设置
(b)face: 规定文本的字体
(c)color: 指定文字的颜色
颜色的取值有3中形式
第一种: 直接使用英文字母表示,比如: red , blue , yellow , green ....
第二种: 使用RGB (值1, 值2 , 值3)表示.每一个值得取值范围是 0~255
第三种: 使用#值1值2值3表示.每一个值得取值是一个两位的16进制数据
5. Html标签之标题标签和水平线标签
A: 标题标签
(1): 标签格式: <h1>对应的文字</h1> , <h2>对应的文字</h2> , ..... <h6>对应的文字</h6>
(2): 标签的特点: 从h1到h6依次变小,并且带有换行
B: 水平线标签
(1): 标签的格式: <hr/>
(2): 标签的属性:
(a): color:设置颜色
(b): size:设置粗细
(c): 设置长度
(d): align:设置具体的位置取值:right , left , center
6. Html标签之列表标签
A: 定义列表标签(dl标签)
标签名: <dl><dt></dt> <dd></dd> </dl>
B: 有序列表标签(ol标签)
标签名<ol type=“1”><li></li><ol>
type取值: 1(默认) , a , i
C: 无序列表标签(ul标签)
标签名: <ul type=“circle”><li></li></ul>
type取值: 空心圆circle , 实心圆disc(默认) , 实心方块square
7. Html标签之图像标签
A: 标签格式: <img src="图片的路径"/>
B: 标签的属性:
(a): src: 指定图片的路径
(b): 设置图片的宽度
(c): height: 设置图片的高度
C: 绝对路径: 从盘符开始的路径或者从一个域名开始的路径
D: 相对路径: 相对于某一个文件的路径
(a): 引用的文件和当前文件在同一个路径,直接写文件名称
(b): 引用的文件在当前文件的上级目录中,需要使用../../这种形式指定
(c): 引用的文件在当前文件的下级目录中,从对应的文件夹开始即可
技巧: 把对象的文件的路径做比较,比较不同的部分
8. Html标签之超链接标签
A: 链接资源
(1): 标签格式: <a href=“链接到资源的路径”>显示在页面上的内容</a>
(2): 属性
(a): href: 链接到的资源路径
(b): target: “_blank”(新页面打开) , “_self”(当前页打开,默认)
当不需要链接具体的页面的时候href需要设置默认的占位符”#”
B: 定位资源
(1): 定位位置;比如:<a name=“top”>顶部位置</a>
(2): 回到这个位置; 比如: <a href=“#top”>回到顶部位置</a>
C: 原样输出标签: <pre>要显示的内容</pre>
9. Html标签之表格标签
A: 作用: 可以对数据进行格式化,使数据显示更加清晰
B: 标签名称:
表格标签:<table></table>
行标签: <tr></tr>
单元格标签: <td><td>
单元格居中以及加粗标签: <th></th>
表格标题标签: <caption></caption>
C:表格标签属性:
border: 设置边框
cellspacing: 设置单元格的间距
宽
height: 高
D: 行标签属性:
align: 设置对齐方式: center , right , left
E: 单元格标签属性:
align: 设置对齐方式: center , right , left
colspan: 跨列
rowspan: 跨行
10. Html标签之表单标签
A: 作用: 提交数据到服务器端
B: 表单的属性
form定义表单的范围<form action="#" method="get"> …….</form>
action : 指定提交的服务器的地址
method: 指定表单提交数据的方式
文本框: <input type="text" name="userName">
密码框: <input type="password" name="password">
单选项: <input type="radio" name="sex" value="1" >, 需要添加name属性和value属性 ,默认选中要设置为: checked="checked"
复选框: <input type="checkbox"> , 需要添加name属性和value属性 ,默认选中为: checked="checked"
文件框: <input type="file" >
文本域: <textarea cols="列" rows="行" name="userInfo"></textarea>
提交按钮: <input type="submit" value="显示的文字"/>
图片提交: <input type="image" src="图片的路径" />
重置按钮: <input type="reset" value="显示的文字"/>
普通按钮: <input type="button" value="显示的文字"/> (通常和js配合使用)
隐藏项: <input type="hidden" name="id" value="123">
下拉输入项:
<select name="stu">
<option>--请选择--</option>
<option value="1">高中</option>
<option value="2">大学</option>
</select><br/>
表单的提交方式:
get: 提交的时候把请求参数直接拼接到url后面 , 不安全 , 对请求参数的数据大小有限制,不能超过1k
post: 提交的时候请求参数没有在url后面 , 安全 ;
案例:
<!DOCTYPE html> <html> <head> <title>表单.html</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="this is my page"> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <!--<link rel="stylesheet" type="text/css" href="./styles.css">--> </head> <body> <form action="#" method="get" > <table border="1" width="300" cellspacing="0" align = "center"> <tr> <td align="right"><b>用户名:</b></td> <td align="left"><input type="text" size="30"></td> </tr> <tr> <td align="right"><b>密 码:</b></td> <td align="left"><input type="password" size="31"></td> </tr> <tr> <td align="right"><b>性 别:</b></td> <td align="left"> <input type="radio" name="sex" value="female" checked="checked" >男 <input type="radio" name="sex" value="male">女 </td> </tr> <tr> <td align="right"><b>爱 好:</b></td> <td align="left"> <input type="checkbox" name="habbit" value="Java">Java <input type="checkbox" name="habbit" value="Android">Android <input type="checkbox" name="habbit" value="IOS">IOS <input type="checkbox" name="habbit" value="PHP">PHP </td> </tr> <tr> <td align="right"><b>学 历:</b></td> <td align="left"><select name="edu"> <option value="" >请选择</option> <option value="zk" >专科</option> <option value="bk" >本科</option> <option value="ss" >硕士</option> </select> </td> </tr> <tr> <td align="right"><b>近 照:</b></td> <td align="left"><input type="file" name="file"></td> </tr> <tr> <td align="right"><b>备 注:</b></td> <td align="left"><textarea rows="10" cols="20" name="desc" >这家伙很懒!神马也没留下!</textarea> </td> </tr> <tr> <td align="center" colspan = "2"> <input type="submit" value="提交"/> <input type="reset" value="重置"/> </td> </tr> </table> </form> </body> </html>
11. Html标签之其他标签和特殊字符
A: 其他常用标签
b (加粗), s(删除线) , u(下划线) , i(斜体) , pre(原样输出) , sub(下标) ,sup(上标) , p(段落标签) , div(自动换行) , span(在一行上显示)
B: 特殊字符标签
空格
< 小于号
> 大于号
® 注册符
© 版权
12. Html标签之框架标签
A: 注意: 框架标签的页面不能写在<body></body>中
B: <frameset>: 框架的格式
属性:
rows=“30%,*”
cols=“3%,*”
C: <frame>: 指定引入的页面
属性:
name=“名称”
src=“页面的路径”
13. XML的概述和作用
A: 概述: Extensible Markup Language: 可扩展的标记语言
B: 特点:
语法很严格
标签自定义
C: 作用:
* 存储数据
* 做配置文件
* 用于进行数据传输
D: 文档声明: 标示这个文档是一个xml文档
<?xml version="1.0" ?>
属性:
* version: 版本号, 必须属性 , 只能为1.x
* encoding: 编码 , 作用是告诉解析器该文档使用的编码
* standalone: 是否独立
E: 标签
F: 属性
B: 文本: 转义 , <![CDATA[...]]>
14. XML的解析
A: 获取文档中的数据: 反序列化[巧记:反读]
B: 把内存中的数据存储到文档中: 序列化[巧记:序写]
C: XML解析思想
* DOM: 就是将文档中的数据全部加载到内存,在内存中形成DOM树,然后对数据进行增删改查操作
* 缺点: 耗内存 , 解析慢
* 优点: 可以对数据进行增删改查的操作
* SAX: 基于事件驱动 , 逐行读取
* 优点: 占用内存小,解析速度快
* 缺点: 只能对数据进行查,不能进行增删改
15.常见的解析器以及pull解析器的获取事件
A: 解析器的作用: 解析xml文件
B: 创建的解析器: JAXP(sun公司的,支持DOM和sax的思想 ,但是很垃圾) , JDOM ,DOM4J ,
PULL: sax思想的解析器,android内置的解析器
C: 使用PULL解析器解析xml文件
16.pull解析器解析xml文件封装对象到集合中
import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory; import com.loaderman.domain.Person; public class PullPerson { public static void main(String[] args) throws IOException, XmlPullParserException { XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); XmlPullParser parser = factory.newPullParser(); parser.setInput( new FileInputStream( "D:\MyEclipse_Workspace\myday01\src\com\loaderman\test\Person.xml"), "UTF-8"); int type = parser.getEventType(); List<Person> list = null; Person p = null; while (type != XmlPullParser.END_DOCUMENT) { String tagName = parser.getName(); switch (type) { case XmlPullParser.START_TAG: if ("persons".equals(tagName)) { list = new ArrayList<>(); } else if ("person".equals(tagName)) { p = new Person(); } else if ("name".equals(tagName)) { String name = parser.nextText(); p.setName(name); } else if ("age".equals(tagName)) { String age = parser.nextText(); p.setAge(Integer.parseInt(age)); } else if ("address".equals(tagName)) { String address = parser.nextText(); p.setAddress(address); } else if ("phone".equals(tagName)) { String phone = parser.nextText(); p.setPhone(phone); } break; case XmlPullParser.END_TAG: if ("person".equals(tagName)) { list.add(p); } break; } type = parser.next(); } System.out.println(list); } } 注: 需要借助kxml2-2.3.0.jar和xmlpull_1_1_3_4c.jar文件
Person.xml
<?xml version="1.0" encoding="UTF-8" ?> <persons> <person> <name>张三</name> <age>23</age> <address>北京</address> <phone>13121031022</phone> </person> <person> <name>李四</name> <age>24</age> <address>西安</address> <phone>13121031024</phone> </person> <person> <name>王五</name> <age>24</age> <address>上海</address> <phone>13121031026</phone> </person> </persons>
Person实例类中代码
public class Person { private String name; private int age; private String address; private String phone; public Person() { super(); } public Person(String name, int age, String address, String phone) { super(); this.name = name; this.age = age; this.address = address; this.phone = phone; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String toString() { return "Person [name=" + name + ", age=" + age + ", address=" + address + ", phone=" + phone + "]"; } }
mysql
1.xml写数据: 序列化
import java.io.FileOutputStream; import org.xmlpull.v1.XmlPullParserFactory; import org.xmlpull.v1.XmlSerializer; import com.loaderman.domain.Student; public class DemoPull { public static void main(String[] args) throws Exception { Student stu = new Student(); stu.setName("JCF"); stu.setAge(20); stu.setScore(100); XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); XmlSerializer serializer = factory.newSerializer(); serializer.setOutput(new FileOutputStream("students.xml"), "utf-8"); serializer.startDocument("utf-8",true); serializer.startTag(null, "students"); serializer.startTag(null, "student"); serializer.startTag(null, "name"); serializer.text(stu.getName()); serializer.endTag(null, "name"); serializer.startTag(null, "age"); serializer.text(String.valueOf(stu.getAge())); serializer.endTag(null, "age"); serializer.startTag(null, "score"); serializer.text(String.valueOf(stu.getScore())); serializer.endTag(null, "score"); serializer.endTag(null, "student"); serializer.endTag(null,"students" ); serializer.endDocument(); } }
2.json
A: json的概述: JavaScript Object Notation , JavaScript对象表示法
B: 作用: 数据表示格式
C: 特点: JSON 比 XML 更小、更快,更易解析。
D: 格式: {} , []
E: 使用jsonlib解析json数据
注:需要借助commons-beanutils-1.8.3.jar, commons-collections-3.2.1.jar,
commons-lang-2.6.jar, commons-logging-1.1.1.jar, ezmorph-1.0.6.jar和json-lib-2.4-jdk15.jar文件
import net.sf.json.JSONArray; import net.sf.json.JSONObject; public class DemoJson { /** * @param args 解析json格式的数据 */ public static void main(String[] args) { String s = "{'name' : 'zhansgan' , 'age' : 23 , 'score': 99.88}"; JSONObject jo = JSONObject.fromObject(s); Object bean= jo.toBean(jo, Student.class); System.out.println(bean); System.out.println("---------------------------------------------------------------"); String ss = "[{'name' : 'zhansgan' , 'age' : 23 , 'score': 99.88} ,{'name' : 'lisi' , 'age' : 24 , 'score': 100}
,{'name' : 'wangwu' , 'age' : 25 , 'score': 23.45} ]"; JSONArray fo = JSONArray.fromObject(ss); Student[] array = (Student[]) fo.toArray(fo,Student.class); for (Student student : array) { System.out.println(student); } } }
3.数据库的概述
A: 数据库的概述: 用来存储和管理数据的仓库
B: 常见的数据库:
Oracle:甲骨文; 大型的关系型数据库 , 收费的
DB2:IBM; 大型的关系型数据库 , 收费的
SQL Server:微软; 中型的关系型数据库 , 收费的
MySQL:甲骨文; 小型的关系型数据库 , 免费的 , 但是6.x以后就开始收费了
4. MySql数据库的下载,安装以及卸载
A: 下载
B: 卸载
1.找到mysql安装目录下的my.ini文件
2.找到配置项datadir datadir="D:/develop /MySQL/MySQL Server 5.0/Data/"
3.关闭mysql服务
4.卸载
5.删除datadir
C: 安装
D: 访问:cmd命令: mysql -uroot –p 回车 ,再输入密码
5. MySql数据库的相关配置
A: 服务的启动与关闭
* 启动 net start mysql
* 关闭 net stop mysql
* 打开服务窗口 services.msc
*查询端口号: netstat -ano
B: mysql密码忘记以后,如何修改密码
1) 停止mysql服务 运行输入services.msc 停止mysql服务或者 cmd -- net stop mysql
2) 在cmd下 输入 mysqld --skip-grant-tables 启动服务 光标不动 (不要关闭该窗口)
3) 新打开cmd 输入mysql -u root -p 不需要密码 use mysql; update user set password=password('abc') WHERE User='root';
4) 关闭两个cmd窗口 在任务管理器结束mysqld 进程
5) 在服务管理页面 重启mysql服务
6. MySql数据库的SQL
A: SQL:Structured Query Language是“结构化查询语言”,它是对关系型数据库的操作语言。就是定义了一些操作关系型数据库的统一规范.而每一种数据库之间
又存在一些不同之处,这些不同之处称之为"方言"
B: SQL的分类
DDL(Data Definition Language):数据定义语言,用来操作库,表
DML(Data Manipulation Language):数据操作语言,用来操作表中存储的数据,但是只能完成增 , 删 , 改
DCL(Data Control Language):数据控制语言,操作用户自己的,完成权限的相关控制
DQL(Data Query Language):数据查询语言,用来操作表中存储的数据,但是只能完成查
7. MySql数据库的SQL(DDL)操作库
A: 操作库
* 增 create database [if not exists] my db ;
* 删 drop database [if exists] mtdb ;
* 查 show databases ;
* 改 alter database mydb character set utf-8 ;
B: 查看前面创建的数据库的定义信息:show create database mydb1;
C: 查询正在使用的数据库:select database();
8. MySql数据库的SQL(DDL)操作表之创建与查询
A: 使用数据库: use 数据库名称 ;
B: 创建表:
create table 表名 (
字段名称 数据类型 ,
字段名称 数据类型 ,
...
字段名称 数据类型
) ;
* 数据库中的数据类型
int:整型
double:浮点型,例如double(5,2)表示最多5位,其中必须有2位小数,即最大值为999.99;
char:固定长度字符串类型;
varchar:可变长度字符串类型;
text:字符串类型;
blob:字节类型;
date:日期类型,格式为:yyyy-MM-dd;
time:时间类型,格式为:hh:mm:ss
timestamp:时间戳类型 格式为: yyyy-MM-dd hh:mm:ss
* 特点: 如果没有给该字段赋值,那么存储的就是当前的时间
C: 查询:
show tables; 显示当前库下的所有的表
desc 表名; 显示表的结构
9. MySql数据库的SQL(DDL)操作表之删除与修改
A: 删除: drop table 表名称 ;
B: 修改:
1. 添加列:给stu表添加classname列:
alter table stu add (classname varchar(100));
2. 修改列类型:修改stu表的gender列类型为CHAR(2):
alter table stu modify gender CHAR(2);
3. 修改列名:修改stu表的gender列名为sex:
alter table stu change gender sex CHAR(2);
4. 删除列:删除stu表的classname列:
alter table stu drop classname;
5. 修改表名称:修改stu表名称为student:
alter table stu rename to student;
10. MySql数据库的SQL(DML)操作表之添加和完整约束
A: 增加: insert into 表名 (字段列明集合) values(值得集合) ;
* 要保证数据的正确性和完整性
完整性约束:
* 主键 一条数据在数据库中的唯一标识, 特点: 非空唯一 primary key
* 主键自增长 如果主键的是int,那么如果给主键赋值为null , 会自动根据上一条记录的值+1 ; primary key aoto_increment
* 唯一 unique
* 非空 not null
* 外键
11. MySql数据库的SQL(DML)操作表之外键约束
A: 外键约束: 一张表的主键作为另一张表的外键,就保证数据的完整性
* 注意事项: 主键必须和外键的数据类型一致,名称可以不一致
B: 表和表之间的关系
* 一对一的关系 主外键可以在任意一方
* 一对多或者多对一的关系 外键添加到多的一方
* 多对多的关系 定义中间表,中间表的两个字段都是外键,分别用于关联两个表的主键
C: 外键约束SQL演示
12. MySql数据库的SQL(DML)操作表之删除和修改
A: 删除: delete from 表名 [where 条件] ;
* delete from 表名 ; -- 删除所有的数据 逐行删除
* truncate table 表名 ; -- 删除所有的数据(直接把表删除然后在在创建表)
B: 修改: update 表名 set 字段名 = 字段值 , 字段名 = 字段值 , ... [where 条件] ;
13.DML案例
-- 创建数据库
create databases mydb ;
-- 查询所有数据库名称
show databases ;
-- 删除数据库
drop database stu;
-- 选择使用的数据库
use day02;
-- 创建表
create table student(
-- 字段名 数据类型
sid INT ,
sname VARCHAR(20),
gender CHAR(1),
score DOUBLE(4,2),
birthday TIMESTAMP
);
-- 查看表名称
show tables ;
-- 删除表
drop table stu;
-- 查看表结构
desc student;
-- 修改表结构
-- 修改之添加列:给stu表添加classname列:
Alter table student add classname vercar(100);
-- 修改之修改列类型:修改stu表的gender列类型为char(2):
ALTER TABLE student MODIFY gender CHAR(2);
-- 修改之修改列名:修改stu表的gender列名为sex:
ALTER TABLE student CHANGE sex gender CHAR(1);
- 修改之删除列:删除stu表的classname列:
ALTER TABLE student DROP classname;
-- 修改表名称
ALTER TABLE student RENAME TO tb_student;
DESC tb_student;
-- 插入数据
INSERT INTO tb_student(sid,sname,gender,score,birthday) VALUES(1,'风清扬','男',99.99,'1998-11-11');
INSERT INTO tb_student(sid,sname,gender,score,birthday) VALUES(2,'岳不群','女',88.99,NULL);
INSERT INTO tb_student(sid,sname) VALUES(3,'貂蝉');
INSERT INTO tb_student VALUES(4,'吕布','男',88.99,NULL);
-- 删除数据
DELETE FROM tb_student WHERE sname = '貂蝉';
-- 查询数据
SELECT * FROM tb_student;
-- 清空表中所有记录
TRUNCATE TABLE tb_student;
-- 先删除表
DROP TABLE tb_student;
-- 再创建一张空表
CREATE TABLE tb_student(
-- 字段名 数据类型
sid INT ,
sname VARCHAR(20),
gender CHAR(1),
score DOUBLE(4,2),
birthday TIMESTAMP
);
-- 修改数据
UPDATE
tb_student
SET
gender = '无',
score = 12.88
WHERE
sid = 2;
-- 创建emp表
CREATE TABLE emp(
empno INT, -- 员工编号
ename VARCHAR(50), -- 员工姓名
job VARCHAR(50), -- 员工工种
mgr INT, -- 领导编号
hiredate DATE, -- 入职日期
sal DECIMAL(7,2), -- 工资
comm DECIMAL(7,2), -- 奖金
deptno INT -- 部门编号
) ;
-- 添加数据
INSERT INTO emp VALUES(7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL,20);
INSERT INTO emp VALUES(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30);
INSERT INTO emp VALUES(7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500,30);
INSERT INTO emp VALUES(7566,'JONES','MANAGER',7839,'1981-04-02',2975,NULL,20);
INSERT INTO emp VALUES(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30);
-- 查询所有列数据
SELECT * FROM emp;
SELECT
empno,
ename,
job
FROM
emp;
-- 结果集
-- 查询工资是800块的员工信息
SELECT * FROM emp WHERE sal = 800;
-- 查询工资大于等于2500的员工信息
SELECT * FROM emp WHERE sal >= 2500;
-- 查询工资小于等于2500的员工信息
SELECT * FROM emp WHERE sal <= 2500;
-- 查询员工资在1500 到 2500 之间
SELECT * FROM emp WHERE sal >= 1500 AND sal <=2500;
-- 查询员工资在1500 到 2500 之间
SELECT * FROM emp WHERE sal BETWEEN 1500 AND 2500;
-- 查询员工工资是1000 或者2000的人
SELECT * FROM emp WHERE sal = 800 OR sal = 5000;
-- 查询员工工资是1000 或者2000的人
SELECT * FROM emp WHERE sal IN(800,5000);
-- 查询员工工资不是800
SELECT * FROM emp WHERE sal != 800;
SELECT * FROM emp WHERE sal <> 800;
-- 查询有奖金的员工信息
SELECT * FROM emp WHERE comm IS NOT NULL;
-- 查询没有有奖金的员工信息
SELECT * FROM emp WHERE comm IS NULL;
-- 查询姓s的用户
SELECT * FROM emp WHERE ename LIKE 's%';
-- 查询姓名第三个字符是I的用户
SELECT * FROM emp WHERE ename LIKE '__I%';
-- 查询名字有五位的用户
SELECT * FROM emp WHERE ename LIKE '_____';
-- 查询名字包含A的用户
SELECT * FROM emp WHERE ename LIKE '%A%';
-- 起别名
SELECT ename 姓名,sal AS 工资, comm AS 奖金 FROM emp;
SELECT e.ename,e.job
FROM emp e;
-- 计算
SELECT ename , sal , comm , (sal+IFNULL(comm,0)) 月薪 FROM emp;
-- 去除重复记录
SELECT DISTINCT sal FROM emp;
14. DQL案例
-- select empno , ename , job from emp ;
-- select * from emp where ename = 'smith';
SELECT * FROM emp WHERE ename != 'smith';
SELECT * FROM emp WHERE ename <> 'smith';
SELECT * FROM emp WHERE sal >= 1100 ;
SELECT * FROM emp WHERE sal >= 1250 AND comm > 400 ;
SELECT * FROM emp WHERE sal >= 1250 OR comm > 400 ;
SELECT * FROM emp WHERE comm IS NULL ;
SELECT * FROM emp WHERE comm IS NOT NULL ;
-- 查询emp表中empno是7369 或者 7499 或者 7521的员工信息
SELECT * FROM emp WHERE empno = 7369 OR empno = 7499 OR empno = 7521 ;
SELECT * FROM emp WHERE empno IN (7369 , 7499 , 7521) ;
SELECT * FROM emp WHERE empno NOT IN (7369 , 7499 , 7521) ;
SELECT * FROM emp WHERE empno BETWEEN 7782 AND 7902 ;
SELECT * FROM emp WHERE ename LIKE '%M%';
-- _: 表示匹配任意单个字符
-- %: 表示匹配任意多个字符
-- 查询ename由4个字母组成的员工的数据
SELECT * FROM emp WHERE ename LIKE '____' ;
-- 查询ename由M开始的员工的数据
SELECT * FROM emp WHERE ename LIKE 'M%' ;
SELECT DISTINCT sal FROM emp ;
SELECT * FROM emp ;
-- null在参与运算的时候结果都是null
-- ifnull(字段名称 , 值)
SELECT * , sal + comm FROM emp ;
SELECT * , sal + IFNULL(comm , 0) FROM emp ;
-- as 关键字用来起别名
SELECT * , sal + IFNULL(comm , 0) AS income FROM emp ;
JDBC
1.MySql数据库的SQL(DQL)操作表之查询数据(条件查询)
A: 查询:
SELECT selection_list /*要查询的列名称*/
FROM table_list /*要查询的表名称*/
WHERE condition /*行条件*/
GROUP BY grouping_columns /*对结果分组*/
HAVING condition /*分组后的行条件*/
ORDER BY sorting_columns /*对结果排序*/
LIMIT offset_start, row_count /*结果限定*/
B: 基础查询
* 查询所有的列: select * from 表名 ;
* 查询指定的列: select 列名1 , 列名2 , ... from 表名 ;
C: 条件查询
=、!=、<>、<、<=、>、>=;
BETWEEN…AND;
IN(set);
IS NULL; 空不能使用 = 或者 != 进行判断. 需要使用is null 或者 is not null ;
AND;
OR;
NOT;
2. MySql数据库的SQL(DQL)操作表之查询数据(模糊查询)
A: 模糊查询: select 列名1 , 列名2 , ... from 表名 where 字段名 like '值' ;
通配符:
* _ 匹配任意单个字符
* % 匹配任意多个字符
B: 字段控制查
* 去除重复: SELECT DISTINCT sal FROM emp;
* 字段运算: null 参与的运算结果都是null ; 如果是null我们就认为是0: IFNULL(字段名称 , 要取的值)
* 别名: 使用 AS 关键字
3. MySql数据库的SQL(DQL)操作表之查询数据(排序)
A: 排序: order by 字段名 ; 后面可以跟多个排序字段,多个排序字段用”,”隔开
SELECT * FROM stu ORDER BY; 默认是升序
B: 升序: order by 字段名 asc ;
SELECT * FROM stu ORDER BY SUM ASC;
C: 降序: order by 字段名 desc ;
SELECT * FROM stu ORDER BY SUM ASC;
4. MySql数据库的SQL(DQL)操作表之查询数据(聚合函数和分组)
A: 聚合函数: 用来做纵向运算的函数
COUNT():统计指定列不为NULL的记录行数;
MAX():计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算;
MIN():计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算;
SUM():计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0;
AVG():计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0;
B: 分组查询: group by 分组字段 ;
* 注意事项: 在分组以后 , 查询的字段只能是分组字段或者聚合函数
* Where在分组之前,having在分组之后
* 在分组之前对结果进行限定,使用where子句
* 在分组之后对结果进行限定,使用having子句
* 需求: 查询每一个部门的工资总和
Select deptno,sum(sal) from emp group by deptno;
* 需求: 查询每个部门的部门编号以及每个部门的人数
Select deptno,count(1) from emp group by deptno;
* 需求: 查询每个部门的部门编号以及每个部门工资大于1500的人数
Select deptno, count(1) from emp where sal>1500 group by deptno;
* 需求: 查询工资总和大于9000的部门编号以及工资和
Select deptno, count(1) from emp group by deptno having sum(sal)>9000;
C: 分页: limit 开始的记录角标 , 每一页的条数 ;
Select * from emp limit 0 , 5 ;
公式: 开始的记录角标 = (页码 - 1) * 每一页的条数
5. JDBC概述
A: JDBC: Java DataBase Connective java连接数据库
B: JDBC:sun公司定义的一套操作数据库的规范(接口)。要求所有数据库驱动要想被Java操作都必须实现这套接口
C: 数据库驱动:各个数据库生成厂商,实现了JDBC接口,提供的一套实现了。来操作各自具体的数据库。
6. JDBC快速入门
A: 实现步骤:
1.导入驱动jar包
2.注册驱动。
3.获取数据库连接对象 Connection
4.定义sql语句
5.获取执行sql的对象 Statement
6.执行sql。获取返回值
7.处理结果。
8.释放资源。
public static void main(String[] args) throws ClassNotFoundException, SQLException { // 注册驱动 Class.forName("com.mysql.jdbc.Driver") ; // 获取连接对象 Connection conn = DriverManager.getConnection("jdbc:mysql:///mydb", "root", "1234") ; // 获取执行sql的对象 Statement statement = conn.createStatement() ; // 执行sql String sql = "insert into stu (sid , name , sal) values (38 , '嘿嘿' , 56.89)" ; int count = statement.executeUpdate(sql) ; // 代表的意思是影响的行数 // 处理结果 System.out.println(count); // 释放资源 statement.close() ; conn.close() ; } } 注:需要借助mysql-connector-java-5.1.7-bin.jar
7. JDBC各个类详解-DriverManager
A: 作用:
1: 注册驱动
Class.forName("com.mysql.jdbc.Driver") ; static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } }
2: 获取数据库连接对象
DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "1234") ;
jdbc: mysql:// localhost:3306 /mydb
jdbc的主协议 子协议 ip地址以及端口号 要连接的数据库的名称
如果我们连接的是本地的数据库,那么localhost:3306可以省略
jdbc:mysql:///mydb
8. JDBC各个类详解-Connection
A: 作用:
* 获取执行sql语句对象
** createStatement(): 获取Statement对象
** prepareStatement(String sql): 获取预处理对象
** prepareCall(String sql): 获取CallableStatement, 这个对象用来执行存储过程
9. JDBC各个类详解-Statement
A: 作用:
* boolean execute(String sql): 可以执行所有类型的sql,如果第一个结果为 ResultSet 对象,则返回 true;如果其为更新计数或者不存在任何结果,则返回false
* int executeUpdate(String sql): 执行DML , 返回的int类型的值表达的意思是影响的行数
* ResultSet executeQuery(String sql): 执行DQL , 返回的ResultSet是存储的查询结果的集合
10. JDBC各个类详解-ResultSet
A: boolean next(): 判断是否存在下一行数据,如果存在返回为true,并且将光标向下移动一位
B: getXxx(...) 获取指定的字段对应的值
* 方法参数可以是指定列对应的编号,这个编号从1开始
* 方法参数也可以是对应的列的名称
11. JDBC异常的处理方式
A: try...catch(...) {...} finally {}
B: 关闭ResultSet,Statement , Connection
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; public class ExceptionDemo { public static void main(String[] args) { Connection conn = null ; Statement st = null ; try { // 注册驱动 Class.forName("com.mysql.jdbc.Driver") ; // 获取连接对象 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "1234") ; // 获取执行sql的对象 st = conn.createStatement() ; // 执行sql , 获取结果 String sql = "insert into user(uid , name , sal) values (1 , 'zhansgan' , 34.56)" ; int count = st.executeUpdate(sql) ; // 处理结果 System.out.println(count); } catch (Exception e) { e.printStackTrace() ; } finally { // 释放资源 if(st != null) { try { st.close() ; } catch (SQLException e) { e.printStackTrace(); } } if(conn != null) { try { conn.close() ; } catch (SQLException e) { e.printStackTrace(); } } } } }
12. JDBC工具类
A: 抽取两个方法,一个获取Connection对象,一个是释放资源
import java.io.FileReader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; public class JdbcUtil { private JdbcUtil() {} // 私有化构造方法 // 定义成员变量 private static String jdbcUrl= null ; private static String userName = null ; private static String password = null ; // 加载数据 static { try { Properties prop = new Properties() ; prop.load(new FileReader("jdbc.properties")) ; jdbcUrl = prop.getProperty("jdbcUrl") ; userName = prop.getProperty("userName") ; password = prop.getProperty("password") ; Class.forName(prop.getProperty("driverClassName")) } catch (Exception e) { e.printStackTrace(); } } /** * 获取连接 */ public static Connection getConnection() throws SQLException { return DriverManager.getConnection(jdbcUrl, userName, password) ; } /** * 释放资源 */ public static void close(Connection conn , Statement st , ResultSet rs) throws SQLException { if(conn != null) conn.close() ; if(st != null) st.close() ; if(rs != null) rs.close() ; } }
13. JDBC类-PrepareStatement
A: 使用步骤
1: 定义sql的时候参数值使用占位符 ? 替换
2: 获取PrepareStatement对象传入sql
3: 使用PrepareStatement的setXxx方法给占位符复制
参数:
* int类型: 就是占位符的编号 ,从1开始
* Xxx类型: 要赋的具体的值
4: 执行sql的时候不需要传递具体的sql
B: 优点
1: 防止sql注入
2: 提高效率
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import com.loaderman.jdbc.utils.JdbcUtil; /** * 预编译的执行sql的对象 */ public class PreparedStatementDemo { public static void main(String[] args) throws Exception { // 获取连接对象 Connection conn = JdbcUtil.getConnection() ; // 定义sql String sql = "select * from user where uid = ?" ; // 获取PreparedStatement对象 PreparedStatement ps = conn.prepareStatement(sql) ; // 给占位符设置值 // 第一个参数占位符所对应的角标(角标从1开始), 第二个参数表示具体的值 ; ps.setInt(1, 1) ; // 执行 ResultSet rs = ps.executeQuery() ; while(rs.next()) { int uid = rs.getInt(1) ; String name = rs.getString(2) ; String password = rs.getString(3) ; System.out.println(uid + "---" + name + "---" + password); } //释放资源 JdbcUtil.close(conn, ps, rs) ; } } 14. JDBC类-日期的转换 import java.sql.Connection; import java.sql.PreparedStatement; import java.util.Date; import com.loaderman.jdbc.domain.Emp; import com.loaderman.jdbc.utils.JdbcUtil; public class JdbcDateDemo { public static void main(String[] args) throws Exception { // 创建emp对象 Emp emp = new Emp() ; emp.setEmpNo(9527) ; emp.setEname("华安") ; emp.setHireDate(new Date()) ; // 获取连接对象以及PreparedStatement Connection conn = JdbcUtil.getConnection() ; String sql = "insert into emp(empno , ename , hiredate) values (? , ? , ?)" ; PreparedStatement ps = conn.prepareStatement(sql) ; // 赋值 ps.setInt(1, emp.getEmpNo()) ; ps.setString(2, emp.getEname()) ; Date date = emp.getHireDate() ; long time = date.getTime() ; java.sql.Date date2 = new java.sql.Date(time) ; ps.setDate(3, date2) ; // 执行sql ps.executeUpdate() ; // 释放资源 JdbcUtil.close(conn, ps, null) ; } }
import java.util.Date; public class Emp { private int empNo ; // 员工编号 private String ename ; // 员工名称 private String job; // 岗位信息 private int mgr ; // 经理编号 private Date hireDate ; // 入职日期 private double sal ; // 薪资 private double comm ; // 奖金 private int deptNo ; // 部门编号 public int getEmpNo() { return empNo; } public void setEmpNo(int empNo) { this.empNo = empNo; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } public int getMgr() { return mgr; } public void setMgr(int mgr) { this.mgr = mgr; } public Date getHireDate() { return hireDate; } public void setHireDate(Date hireDate) { this.hireDate = hireDate; } public double getSal() { return sal; } public void setSal(double sal) { this.sal = sal; } public double getComm() { return comm; } public void setComm(double comm) { this.comm = comm; } public int getDeptNo() { return deptNo; } public void setDeptNo(int deptNo) { this.deptNo = deptNo; } @Override public String toString() { return "Emp [empNo=" + empNo + ", ename=" + ename + ", job=" + job + ", mgr=" + mgr + ", hireDate=" + hireDate + ", sal=" + sal + ", comm=" + comm + ", deptNo=" + deptNo + "]"; } }
15. MetaData
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.util.HashMap; import java.util.Map; import org.apache.commons.beanutils.BeanUtils; public class MetaDataDemo { public static void main(String[] args) throws Exception { Connection conn = JdbcUtil.getConnection() ; // 获取连接对象 String sql = "select * from emp" ; // 定义sql模板 PreparedStatement ps = conn.prepareStatement(sql) ; // 获取PreparedStatement对象 ResultSetMetaData metaData = ps.getMetaData() ; // 获取结果集元数据 int columnCount = metaData.getColumnCount() ; // 获取列的总数 ResultSet rs = ps.executeQuery() ; // 执行sql while(rs.next()) { Map<String , Object> map = new HashMap<String , Object>() ; // 定义一个Map集合对象,用这个对象存储用户的数据 , 一条数据就是一个Map集合 Emp emp = new Emp() ; // 创建Emp对象 , 用这个对象来封装数据 for(int x = 1 ; x <= columnCount ; x++) { // 遍历列 String columnName = metaData.getColumnName(x) ; // 获取列名称 Object obj = rs.getObject(x) ; // 获取列对应的值 if("empno".equals(columnName)) { // 把列的名称作为键 , 值作为值存储到Map集合中 map.put("empNo", obj) ; }else { map.put(columnName, obj) ; } } BeanUtils.populate(emp, map) ; // 使用BeanUtils封装数据 System.out.println(emp); // 打印对象 System.out.println("----------------------------------------"); // 打印华丽的分割线 } } }
tomcat+Http协议
1.WEB开发的三层架构
Web层:接收客户端发送过来的数据,然后需要将数据传递给service层
Service层:业务逻辑层:业务:比如检验用户名的是否存在,如果不存在则需要把用户的数据存储在数据库中,如果存在,给web返回一个false.
Dao层:数据访问层/持久化层
2. 事务的概述以及事务的处理
A:事务概述: 是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。
B:事务的处理
* 开始事务
* 提交事务
* 回滚事务
C:代码演示转账案例,加入事务处理
D: 注意: 在进行事务管理的时候,要求必须使用的是同一个连接对象
import java.sql.Connection; import java.sql.PreparedStatement; import com.loaderman.jdbc.utils.JdbcUtil; public class AccountDao { // 更新数据库 public void updateAccount(String name , double money) throws Exception { Connection conn = JdbcUtil.getConnection() ; String sql = "update cust set account = account + ? where name = ?" ; PreparedStatement ps = conn.prepareStatement(sql) ; ps.setDouble(1, money) ; ps.setString(2, name) ; ps.executeUpdate() ; } }
import java.sql.Connection; import java.sql.SQLException; import com.loaderman.jdbc.dao.AccountDao; import com.loaderman.jdbc.utils.JdbcUtil; public class AccountService { // 创建AccountDao对象 private AccountDao ad = new AccountDao() ; /** * 完成转账操作 * @param from * @param to * @param money * @throws Exception */ public void switchAccount(String from , String to , double money) { Connection conn = null ; try { conn = JdbcUtil.getConnection() ; conn.setAutoCommit(false) ; ad.updateAccount(from, -money) ; System.out.println(1/0); ad.updateAccount(to, money) ; conn.commit() ; } catch (Exception e) { e.printStackTrace() ; try { conn.rollback() ; } catch (SQLException e1) { e1.printStackTrace(); } } finally { try { JdbcUtil.close(conn, null, null) ; } catch (SQLException e) { e.printStackTrace(); } } } }
import org.junit.Test; import com.loaderman.jdbc.service.AccountService; public class AccountServiceTest { @Test public void testSwitchAccount() throws Exception { AccountService as = new AccountService() ; as.switchAccount("zhangsan", "lisi", 500) ; } }
import java.io.FileReader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; public class JdbcUtil { private JdbcUtil() {} // 私有化构造方法 // 定义成员变量 private static String jdbcUrl= null ; private static String userName = null ; private static String password = null ; // private static MyThreadLocal<Connection> tl = new MyThreadLocal<Connection>() ; private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>() ; // 加载数据 static { try { Properties prop = new Properties() ; prop.load(new FileReader("jdbc.properties")) ; jdbcUrl = prop.getProperty("jdbcUrl") ; userName = prop.getProperty("userName") ; password = prop.getProperty("password") ; Class.forName(prop.getProperty("driverClassName")) ; } catch (Exception e) { e.printStackTrace(); } } /** * 获取连接 */ public static Connection getConnection() throws SQLException { Connection conn = tl.get() ; if(conn == null) { conn = DriverManager.getConnection(jdbcUrl, userName, password) ; tl.set(conn) ; } return conn; } /* * 释放资源 */ public static void close(Connection conn , Statement st , ResultSet rs) throws SQLException { if(conn != null) conn.close() ; if(st != null) st.close() ; if(rs != null) rs.close() ; } }
import java.security.MessageDigest; import org.apache.commons.codec.binary.Hex; public class Md5 { public static String md5(String s) throws Exception { MessageDigest instance = MessageDigest.getInstance("MD5") ; byte[] bytes = instance.digest(s.getBytes()) ; char[] hex = Hex.encodeHex(bytes) ; return new String(hex) ; } } import java.util.HashMap; import java.util.Map; /** * 作用: 在同一个线程中共享数据 */ public class MyThreadLocal<T> { private Map<Thread , T> hashMap = new HashMap<Thread , T>() ; /** * 存储数据 * @param conn */ public void set(T t) { hashMap.put(Thread.currentThread(), t) ; } public T get() { return hashMap.get(Thread.currentThread()) ; } }
import java.security.MessageDigest; import org.apache.commons.codec.binary.Hex; public class Md5 { public static String md5(String s) throws Exception { MessageDigest instance = MessageDigest.getInstance("MD5") ; byte[] bytes = instance.digest(s.getBytes()) ; char[] hex = Hex.encodeHex(bytes) ; return new String(hex) ; } }
3.WEB服务器的概述
A: 简述WEB服务器
作用:
* 用来接收客户端的请求
* 处理请求, 把动态资源转换成了静态资源(web容器)
* 给客户端响应
B: 服务器的分类:
* weblogic:oracle公司 大型的JavaEE服务器 收费的
* websphere:IBM公司 大型的JavaEE服务器 收费的
* JBOOS:红帽公司 大型的JavaEE服务器 收费的
* tomcat:apache基金组织 中小型的JavaEE服务器 开源的免费的。java语言开发的
4. Tomcat的启动和关闭
A: 启动,遇到一闪而过的问题,可能尚未配置JAVA_HOME
B: 8080端口被占用导致启动失败
C: 关闭Tomcat的三种方式
* 点击x (不推荐)
* 双击shutdown.bat
* ctrl + c
5. Tomcat发布项目
A: WEB项目的目录结构介绍
B: 演示动态项目的创建
把项目打包成war包:
进入这个项目中,使用命令: jar cvf aaa.war *
C: 发布动态项目的三种方式:
1. 直接复制项目到webapps下
2. 把项目打包成war包
3. 配置映射关系: <Context path="/aaa" docBase="项目所在路径" />或者在confCatalinalocalhost下创建xxx.xml然后在该文件中编写Context
6. Http的概述
A: Http: Hyper Text Transfer Protocol 超文本传输协议
B: 传输协议: 定义了传输数据的格式
C: Http协议的特点:
* 是一种高级协议
* 是一种基于TCP的 协议
* 基于请求和响应模式
* 是一种无状态的协议
7. Http的请求协议请求行的介绍
A: 请求协议包含的内容
* 请求行 GET /day04-tomcat/index.jsp HTTP/1.1
HTTP/1.1: 表示的是我们使用的是http协议的1.1版本
http协议1.0和http协议1.1的区别:
http1.0每一次请求都是一个连接
http1.1一次请求完毕以后,这个连接还不会立马消失,而是存活一段时间,这个时间大概是3秒
/day04-tomcat/index.jsp: 请求项目的虚拟目录 表示uri(统一资源标识符)
http://localhost/day04-tomcat/index.jsp url(统一资源定位符)
GET: 表示的是请求方式
GET请求数据请求行中,不安全, 并且数据不能超过1k
POST请求的数据存储在请求体中,安全
* 请求头
* 请求空行
* 请求体: 存储POST请求的数据
Servlet
1.Http的请求协议请求头介绍
A: Referer
B: User-Agent
2. Http的url编码
A: URL编码的原理
B: 使用jdk提供的类完成URL的编解码
public class UrlDemo { public static void main(String[] args) throws Exception { /** * URLEncoder: 进行URL编码 */ String encode = URLEncoder.encode("张三", "utf-8") ; // %E5%BC%A0%E4%B8%89 System.out.println(encode); System.out.println("----------------------------------------------"); /** * URLDecoder: 进行解码 */ String result = URLDecoder.decode(encode, "utf-8") ; System.out.println(result); } }
3. Http的响应协议
A: 响应行介绍,响应状态码
1XX: 客户端请求服务器,但是请求未完成,服务器什么事也没干
2XX: 表示响应成功,代表性的状态码就是200
3XX: 请求重定向,代表性的状态码302
4XX: 客户端发送失败,代表性的状态码是404
5XX: 服务器错误,代表性的状态码是500
B: 内容:
* 响应行
* 响应头
* 响应空行
* 响应体
4. Http的响应协议
A: 响应头介绍
* Content-Type:text/html;charset=utf-8
* 告诉客户端,服务器发送消息体数据的数据类型和编码方式。客户端会按照相对应的解析器和编码方式解析响应消息体数据
* mime类型:一种数据类型
* refresh:定时跳转
* 时间;url=值
* 5;url=https:www.baidu.com
在<head></head> 中设置,要重定向的语句:
<meta http-equiv="refresh" content="5;url=http://localhost:8080/myday04-tomcat/MyJsp.jsp">
5. Servlet的概述
A: Servlet的概述: server applet , 是一个运行在服务器端的小应用程序
B: 就是一个接口,作用: servlet 通常通过 HTTP(超文本传输协议)接收和响应来自 Web 客户端的请求。
6. Servlet的入门案例
A: 编写入门案例
* 建立一个web项目
* 定义一个类,然后让该类去实现Servlet接口, 重写方法
* 配置servlet的访问路径
import java.io.IOException; import javax.servlet.Servlet; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class ServletDemo1 implements Servlet { @Override public void destroy(){ } @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { System.out.println("哦....ServletDemo1...被访问了................"); } @Override public ServletConfig getServletConfig() { return null; } @Override public String getServletInfo() { return ""; } @Override public void init(ServletConfig config) throws ServletException { System.out.println("init....ServletDemo1................"); } }
在web.xml<web-app></web-app>中配置:
<servlet>
<servlet-name>servletDemo1</servlet-name>
<servlet-class>com.loaderman.servlet.ServletDemo1</servlet-class>
<load-on-startup>5</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>servletDemo1</servlet-name>
<url-pattern>/haha</url-pattern> 注:这是代表要访问的路径,可以随意定义,这是浏览器要输入的路径
</servlet-mapping>
7.Servlet的运行原理
见图
8. Servlet中的生命周期
A: Servlet的方法:
* init 初始化工作
* service 提供服务的,每访问一次就执行一次
* destroy 销毁前执行
* getServletConfig 获取配置信息
* getServletInfo 获取servlet信息
B: Servlet的生命周期
* 被创建
* 提供服务
* 被销毁
C: 见图
9. ServletConfig对象的使用
A: 作用:
* 获取Servlet的配置信息
* 获取ServletContext对象
B: 接收ServletConfig对象
10.Servlet的三种实现方式
A: 实现Servlet接口
B: 继承GenericServlet
C: 继承HttpServlet,它是对Http协议进行了封装
11. 使用MyEclipse自动配置servlet
A: 新建servlet
B: 修改servlet模板: MyEclipseCommonplugins 搜索wizard ,
找com.genuitec.eclipse.wizards_9.0.0.me201108091322.jar
12. ServletContext对象的概述以及展示存储数据的功能
A: ServletContext对象的概述
B: 特点: 该对象是单例的
C: 作用:
* 它是域对象,可以用来存储数据
* 获取文件的MIME类型
* 获取文件运行时候的真实路径
D: 展示存储数据
13. ServletContext对象获取MIME类型以及获取真实路径
A: MIME类型: MIME类型就是设定某种扩展名的文件用指定的应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。
获取获取方式: public String getMimeType(String file)
B: 获取真实路径
* 问题: 只能在web环境下使用
* JDBCUtils获取路径改进,使用ClassLoader进行获取
ServletContext context = getServletConfig().getServletContext() ;
String path = context.getRealPath("/") ; //D: omcatapache-tomcat-7.0.26webappsday05-servlet
String path = context.getRealPath("/mv.jpg") ; // 把mv.jpg存储到WebRoot下的获取方式
String path = context.getRealPath("/WEB-INF/classes/mv.jpg") ; // 把mv.jpg存储到了src下的获取方式 String path = context.getRealPath("/WEB-INF/mv.jpg") ; // 把mv.jpg存储到WEB-INF目录下的获取方式
System.out.println(path);
Httpservlet
1.HttpServletRequest&HttpServletResponse简单概述
注意: HttpServletRequest&HttpServletResponse对象不是由我们来创建的,而是由tomcat服务器创建,那么我们就可以直接来使用这两个对象
A: HttpServletRequest: 封装了我们的请求消息,获取到请求数据
B: HttpServletResponse: 封装了我们的响应消息,设置响应数据
C: 使用HttpServletResponse设置响应头以及响应状态码完成重定向操作
* 响应行 http/1.1 200 OK void setStatus(int sc): 设置响应状态码
* 响应头 void setHeader(String name, String value): 设置响应头信息
* 响应体 ServletOutputStream getOutputStream(): 获取字节输出流,可以响应字节数据
PrintWriter getWriter(): 获取字符输出流 , 可以响应字符数据
2.HttpServletResponse设置响应体响应字符数据
PrintWriter getWriter(): 获取字符输出流 , 可以响应字符数据
例子: response.getWriter().write("<h1>HelloWorld!<h1>") ;
第一种形式:
esponse.setCharacterEncoding("UTF-8");//获取这个流对象之前设置一个编码方式
response.setHeader("content-type", "text/html;charset=UTF-8") ;// 响应头content-type
response.getWriter().write("你好啊啊 啊");
第二种形式:
response.setContentType("text/html;charset=utf-8") ;
response.getWriter().write("你好") ;
3. HttpServletResponse设置响应体响应字节数据
ServletContext context = getServletConfig().getServletContext(); String path = context.getRealPath("/WEB-INF/classes/mv.jpg"); FileInputStream fis = new FileInputStream(path); ServletOutputStream stream = response.getOutputStream(); IOUtils.copy(fis, stream) ;//借助commons-io-2.0.jar和commons-fileupload-1.2.1.jar
4. HttpServletRequest获取请求行以及获取请求头
A: 作用: 1. 获取请求消息数据 2. 完成请求转发 3. 是域对象
B: 获取请求行 GET /uri HTTP/1.1
String getMethod() 获取请求方式
String getQueryString() 获取请求参数
String getContextPath() 获取虚拟目录
String getRemoteAddr() 获取ip地址
C: 获取请求头
String getHeader(String name) (user-agent) String header = request.getHeader("user-agent") ; if(header.contains("MSIE")) { System.out.println("IE浏览器..............."); response.sendRedirect("http://www.baidu.com") ; }else if(header.contains("Chrome")) { System.out.println("谷歌浏览器..............."); response.sendRedirect("http://www.jd.com") ; }else if(header.contains("Firefox")) { System.out.println("火狐浏览器..............."); }else { System.out.println("其它浏览器..............."); }
5. HttpServletRequest获取请求体
A: 获取请求体数据
* BufferedReader getReader()
* ServletInputStream getInputStream()
Doget:
String qs = request.getQueryString(); String line = request.getQueryString() ; // userName=zhangsan&password=123 String[] split = line.split("&") ; for(String data : split) { String[] info = data.split("=") ; System.out.println(request.getMethod() + "----" + info[0] + "---" + info[1]); /* * GET----username---zhangsan GET----password---123 */ }
Dopost:
BufferedReader reader = request.getReader() ; String line = reader.readLine() ; // userName=zhangsan&password=123 String[] split = line.split("&") ; for(String data : split) { String[] info = data.split("=") ; System.out.println(request.getMethod() + "----" + info[0] + "---" + info[1]); // POST----userName---qq // POST----password---9 }
6. HttpServletRequest获取请求参数通用的方式
* GET 和 POST 请求通用的获取数据的方式
String getParameter(String name): 根据名称获取对应的请求参数的值
Enumeration getParameterNames(): 获取所有的请求参数的名称
Map<String , String[]> getParameterMap(): 获取所有的请求参数对应的Map集合, 键是请求参数的名称 ,值是请求参数的值
String[] getParameterValues(String name): 根据名称获取对应的请求参数的值对应的数组
String userName = request.getParameter("userName"); System.out.println(request.getMethod()+"----"+userName); System.out.println("------------------"); Enumeration names = request.getParameterNames(); while(names.hasMoreElements()){ String name = (String) names.nextElement(); String value = request.getParameter(name); System.out.println(name+"---"+value); } Map<String,String[]> map = request.getParameterMap(); Set<Entry<String, String[]>> entrySet = map.entrySet(); for (Entry<String, String[]> entry : entrySet) { String key = entry.getKey(); String[] value = entry.getValue(); System.out.println(key + "----" + Arrays.toString(value)); } User user = new User() ; try { BeanUtils.populate(user, map) ; // User [userName=zhangsan, password=888, hobby=[1, 2, 3]] } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } System.out.println(user);
7. 获取请求参数乱码问题
A: 通用的解决方案
第一种方式:
String userName = request.getParameter("userName") ; byte[] bytes = userName.getBytes("iso8859-1"); userName = new String(bytes , "UTF-8") ; System.out.println(request.getMethod()+userName);
第二种方式:
request.setCharacterEncoding("UTF-8") ; String userName = request.getParameter("userName") ; System.out.println(userName);
B: POST请求的乱码
8. 请求转发和重定向
A: 请求转发 request.getRequestDispatcher("/servlet09").forward(request, response) ;
请求重定向 response.sendRedirect(request.getContextPath() + "/servlet09") ;
B: 域对象
C: 转发和重定向的区别
9.文件上传对表单的要求(掌握)
A: 表单中要存在file文件项
B: 表单必须为POST请求
C: 表单的enctype="multipart/form-data"
10. 文件上传对Servlet的要求
A: request.getParamter(String name)方法不能再使用了
B: 需要使用request.getInputStream()获取输入流对象然后在进行读取数据
C: 解析数据
ServletInputStream inputStream = request.getInputStream() ; byte[] bytes = new byte[1024] ; int len = 0 ; while((len = inputStream.read(bytes)) != -1) { System.out.print(new String(bytes , 0 , len)); }
11. 文件上传使用Fileupload组件代码实现
A: 使用FileUpload组件进行代码实现
B: 实现步骤
1. 获取解析器工厂: DiskFileItemFactory
2. 获取解析器对象: ServletFileUpload
3. 解析request: public java.util.List<FileItem> parseRequest(javax.servlet.http.HttpServletRequest request)
4. 遍历这个List集合获取每一个表单项,然后在进行其他操作
// 获取解析器工厂 DiskFileItemFactory factory = new DiskFileItemFactory() ; // 获取解析器 ServletFileUpload sfu = new ServletFileUpload(factory) ; // 解析request List<FileItem> list = sfu.parseRequest(request) ; // 遍历这个List集合 for(FileItem fi : list) { if(fi.isFormField()) { // 普通表单项 String fieldName = fi.getFieldName() ; String value = fi.getString("utf-8") ; System.out.println(fieldName + "----" + value); }else { // 获取上传文件的名称 String name = fi.getName() ; name = name.substring(name.lastIndexOf("\") + 1) ; name = UUIDUtil.getId() + "_" + name ; String path = getServletContext().getRealPath("/images/" + name) ; fi.write(new File(path));
12. 文件下载(掌握)
A: 实现方式:
* 超链接实现
* 代码实现
* 通过response输出流将数据写到客户端
* 设置响应头:content-disposition:attachment;filename=xxx.jpg
/** * 设置一个响应头,然后给定两个流,一个是输入流一个是输出流 * 一个头两个流 */ response.setHeader("content-disposition", "attachment;filename=mv.jpg" ); //+ new String("哈哈.jpg".getBytes("GBK") , "iso8859-1")) ; response.setHeader("content-disposition", "attachment;filename=+ new String("哈哈.jpg".getBytes("GBK") , "iso8859-1")) ; //如果是汉字的处理方式 String path = getServletContext().getRealPath("/mv.jpg") ; FileInputStream fis = new FileInputStream(path) ; ServletOutputStream out = response.getOutputStream() ; IOUtils.copy(fis, out) ;