JavaWeb

摘要

主要用于记录JavaWeb的学习过程,希望对大家有所帮助。
该学习是基于黑马的JavaWeb课程,感兴趣的盆友可以在b站搜索javaweb进行观看学习。

Day 01 内容

04/07/2020

* Junit单元测试
* 反射
* 注解

Junit单元测试:

* 测试分类:* 黑盒测试:不需要写代码,给输入值,看程序能否输出期望值。* 白盒测试:需要写代码。关注程序具体的执行流程。* Junit使用:白盒测试* 步骤:1. 定义一个测试类(测试用例)* 建议:* 测试类名:被测试的类名Test   calculatorTest* 包名:xxx.xxx.xxx.test2. 定义测试方法:可以独立运行* 建议:* 方法名:test测试的方法名    testadd* 返回值:void* 参数列表:空参3. 给方法加@Test4. 导入Junit依赖环境* 判定结果:* 红色:失败* 绿色:成功* 一般我们会使用断言操作来处理结果:* Assert.assertEquals(期望的结果, 运算的结果);* 补充* @before:* 修饰的方法会在测试方法之前被自动执行* @after:* 修饰的方法会在测试方法执行之后被自动执行

反射:框架设计的灵魂

* 框架:半成品软件。可以在框架的基础上进行软件开发,简化编码
* 反射:将类的各个组成部分封装为其他对象,这就是反射机制* 好处:1. 可以在程序运行过程中,操作这些对象。2. 可以解耦,提高程序的可扩展性* 获取Class对象的方式:1. Class.forName("全类名"); 将字节码文件加载进内存,返回Class对象* 多用于配置文件,将类名定义在配置文件中。读取文件,加载类2. 类名.class; 通过类名的属性class来获取* 多用于参数的传递3. 对象.getClass(); getClass()方法在Object类中定义* 多用于对象的获取字节码的方式
* 结论:同一个字节码文件(*.class)在一次程序的运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。* Class对象功能:* 获取功能:1. 获取成员变量们* Field[] getFileds()* Filed getFiled(String name)* Field[] getDeclaredFileds()* Filed getDeclaredFiled(String name)2. 获取构造方法们* Constructor<?>[] getConstructors()* Constructor\<?\> getConstructor(类\<?\>... parameterTypes)* Constructor<?>[] getDeclaredConstructors()* Constructor\<?\> getDeclaredConstructor(类\<?\>... parameterTypes)3. 获取成员方法们* Method[] getMethods()* Method getMethod(String name)* Method[] getDeclaredMethods()* Method getDeclaredMethod(String name)4. 获取类名* String getName()* Field:成员变量* 操作:1. 设置值* void set(Object obj, Object value)2. 获取值* get(Object obj)3. 忽略访问权限修饰符的安全检查* setAccessible(true):暴力反射* Constructor:构造方法* 创建对象:* T newInstance(Object... initargs)* 如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法* Method:方法对象* 执行方法:* Object invoke(Object obj, Object... args)* 获取方法名称:* String getName()获取方法名* 案例:* 需求:写一个"框架",不能改变该类的任何代码的前提下,可以帮我们创建任意类的对象,并且执行其中任意方法。* 实现:1. 配置文件2. 反射* 步骤:1. 将需要创建的对象的全类名和需要执行的方法定义在配置文件中2. 在程序中去加载读取配置文件3. 使用反射技术来加载类文件进内存4. 创建对象5. 执行方法

注解:

* 概念:说明程序的。给计算机看的。* 注释:用文字描述程序。给程序员看的。* 概念描述:* jdk1.5之后的新特性* 说明程序的* 使用注解:@注解名称* 作用分类* 编写文档:生成文档【doc文档】* 代码分析:通过注解对代码进行分析【使用反射】* 编译检查:让编辑器能实现基本的编译检查【@Override】* JDK中预定义的一些注解* @Override:检测被该注解标注的方法是否是继承自父类(接口)的* @Deprecated:将该注解标注的内容,表示已过时* @SuppressWarnings:压制警告* 一般传递参数all   @SuppressWarnings("all")* 自定义注解* 格式:* 元注解* public @interface 注解名称() {属性列表;}* 本质:注解本质上就是一个接口,该接口默认继承Annotation* public interface 注解名称 extends java.lang.annotation.Annotation {}* 属性:接口中的抽象方法* 要求:1. 属性的返回值类型有下列取值:* 基本数据类型* String* 枚举* 注解* 以上类型的数组2. 定义了属性,在使用时需要给属性赋值1. 如果定义属性时,使用default关键字给属性默认初始值,则使用注解时可以不进行属性的赋值2. 如果只有一个属性需要赋值,并且属性的名称为value,则value可以省略,直接定义值即可【@SuppressWarnings】3. 数组赋值时,值使用{}包裹,如果数组中只有一个值,则{}可以省略* 元注解:用于描述注解的注解* @Target:描述注解能够作用的位置* ElementType取值:* TYPE:可以作用于类上* METHOD:可以作用于方法上* FIELD:可以作用于成员变量上* @Retention:描述注解被保留的一个阶段* @Rentention(RententionPolicy.RUNTIME):当前被描述的注解,会保留到class字节码文件中,并被JVM读取到* @Documented:描述注解是否被抽取到api文档中* @Inherited:描述注解是否被子类继承* 在程序中使用(解析)注解:获取注解中定义的属性值1. 获取注解定义的位置的对象   【Class,Method,Field】2. 获取指定的注解* getAnnotation(Class)* public class ProImpl implements Pro{public String className(){return "day01.annotation.Demo1";}public String methodName(){return "show";}}3. 调用注解中的抽象方法,获取配置的属性值* 小结1. 以后大多数时候,我们会使用注解,而不是自定义注解2. 注解给谁用?1. 编译器2. 给解析程序用3. 注解不是程序的一部分,可以理解为注解就是一个标签

Day 02 内容

05/07/2020

* 数据库的基本概念
* MySQL数据库软件* 安装* 卸载* 配置
* SQL

数据库的基本概念

1. 数据库的英文单词:DataBase 简称 : DB
2. 什么是数据库?* 用于存储和管理数据的仓库。3. 数据库的特点:1. 持久化存储数据的。其实数据库就是一个文件系统2. 方便存储和管理数据3. 使用了统一的方式来操作数据库 -- SQL4. 常见的数据库软件   * 参见《MySQL基础.pdf》

MySQL数据库软件

1. 安装* 参见《MySQL基础.pdf》
2. 卸载1. 去mysql的安装目录找到my.ini文件* 复制 datadir="C:/ProgramData/MySQL/MySQL Server 5.5/Data"2. 卸载MySQL3. 删除C:/ProgramData目录下的MySQL文件夹。3. 配置* MySQL服务启动1. 手动2. cmd--> services.msc 打开服务的窗口3. 使用管理员打开cmd* net start mysql :启动mysql的服务* net stop mysql :关闭mysql的服务* MySQL登录1. mysql -uroot -p【password】2. mysql -h【ip】 -uroot -p【连接目标的password】3. mysql --host=【ip】 --user=root --password=【密码】* MySQL退出1. exit2. quit* MySQL目录结构1. MySQL安装目录* 配置文件 my.ini2. MySQL数据目录* 几个概念* 数据库:文件夹* 表:文件* 数据:数据

SQL

1. 什么是SQL?Structured Query Language:结构化编程语言其实就是定义了操作所有关系型数据库的规则。每一种数据库操作的方式存在不一样的地方,称为"方言"2. SQL通用语法1. SQL语句可以单行或多行书写,以分号结尾。2. 可使用空格和缩进来增强语句的可读性。3. MySQL数据库的SQL语句不区分大小写,关键字建议使用大写。4. 3种注释* 单行注释:-- 注释内容 或 # 注释内容(mysql 特有)* 多行注释:/* 注释 */3. SQL分类1) DDL(Data Definition Language)数据定义语言用来定义数据库对象:数据库,表,列等。关键字:create, drop,alter 等2) DML(Data Manipulation Language)数据操作语言用来对数据库中表的数据进行增删改。关键字:insert, delete, update 等3) DQL(Data Query Language)数据查询语言用来查询数据库中表的记录(数据)。关键字:select, where 等4) DCL(Data Control Language)数据控制语言(了解)用来定义数据库的访问权限和安全级别,及创建用户。关键字:GRANT, REVOKE 等

DDL:操作数据库、表

1. 操作数据库:CRUD1. C(Create):创建* 创建数据库:* create database 数据库名称;* 创建数据库,判断不存在,再创建:* create database if not exists 数据库名称;* 创建数据库,并指定字符集* create database 数据库名称 character set 字符集名;* 练习: 创建db4数据库,判断是否存在,并制定字符集为gbk* create database if not exists db4 character set gbk;2. R(Retrieve):查询* 查询所有数据库的名称:* show databases;* 查询某个数据库的字符集:查询某个数据库的创建语句* show create database 数据库名称;3. U(Update):修改* 修改数据库的字符集* alter database 数据库名称 character set 字符集名称;4. D(Delete):删除* 删除数据库* drop database 数据库名称;* 判断数据库存在,存在再删除* drop database if exists 数据库名称;5. 使用数据库* 查询当前正在使用的数据库名称* select database();* 使用数据库* use 数据库名称;
2. 操作表1. C(Create):创建1. 语法:create table 表名(列名1 数据类型1,列名2 数据类型2,....列名n 数据类型n);* 注意:最后一列,不需要加逗号(,)* 数据库类型:1. int:整数类型* age int,2. double:小数类型* score double(5,2)3. date:日期,只包含年月日,yyyy-MM-dd4. datetime:日期,包含年月日时分秒     yyyy-MM-dd HH:mm:ss5. timestamp:时间戳类型  包含年月日时分秒     yyyy-MM-dd HH:mm:ss    * 如果将来不给这个字段赋值,或赋值为null,则默认使用当前的系统时间,来自动赋值6. varchar:字符串* name varchar(20):姓名最大20个字符* zhangsan 8个字符  张三 2个字符* 创建表:create table student(id int,name varchar(32),age int ,score double(4,1),birthday date,insert_time timestamp);* 复制表:* create table 表名 like 被复制的表名;       2. R(Retrieve):查询* 查询某个数据库中所有的表名称* show tables;* 查询表结构* desc 表名;3. U(Update):修改1. 修改表名alter table 表名 rename to 新的表名;2. 修改表的字符集alter table 表名 character set 字符集名称;3. 添加一列alter table 表名 add 列名 数据类型;4. 修改列名称 类型alter table 表名 change 列名 新列别 新数据类型;alter table 表名 modify 列名 新数据类型;5. 删除列alter table 表名 drop 列名;4. D(Delete):删除* drop table 表名;* drop table if exists 表名 ;
  • 客户端图形化工具:SQLYog

    1. 添加数据:

      • 语法:

        • insert into 表名(列名1,列名2,…列名n) values(值1,值2,…值n);
      • 注意:
        1. 列名和值要一一对应。
        2. 如果表名后,不定义列名,则默认给所有列添加值
          insert into 表名 values(值1,值2,…值n);
        3. 除了数字类型,其他类型需要使用引号(单双都可以)引起来
    2. 删除数据:

      • 语法:

        • delete from 表名 [where 条件]
      • 注意:
        1. 如果不加条件,则删除表中所有记录。
        2. 如果要删除所有记录
          1. delete from 表名; – 不推荐使用。有多少条记录就会执行多少次删除操作
          2. TRUNCATE TABLE 表名; – 推荐使用,效率更高 先删除表,然后再创建一张一样的表。
    3. 修改数据:

      • 语法:

        • update 表名 set 列名1 = 值1, 列名2 = 值2,… [where 条件];
      • 注意:

        1. 如果不加任何条件,则会将表中所有记录全部修改。

Day 03 内容

06/07/2020

1. DQL:查询语句1. 排序查询2. 聚合函数3. 分组查询4. 分页查询2. 约束
3. 多表之间的关系
4. 范式
5. 数据库的备份和还原

DQL:查询语句

DQL:查询表中的记录

* select * from 表名;1. 语法:select 字段列表from表名列表where条件列表group by分组字段having分组之后的条件order by排序limit分页限定2. 基础查询1. 多个字段的查询select 字段名1,字段名2... from 表名;* 注意:* 如果查询所有字段,则可以使用*来替代字段列表。2. 去除重复:* distinct3. 计算列* 一般可以使用四则运算计算一些列的值。(一般只会进行数值型的计算)* ifnull(表达式1,表达式2):null参与的运算,计算结果都为null* 表达式1:哪个字段需要判断是否为null* 表达式2:如果该字段为null后的替换值。4. 起别名:* as:as也可以省略3. 条件查询1. where子句后跟条件2. 运算符* > 、< 、<= 、>= 、= 、<>* BETWEEN...AND  * IN( 集合) * LIKE:模糊查询* 占位符:* _:单个任意字符* %:多个任意字符* IS NULL  * and  或 &&* or  或 || * not  或 !-- 查询年龄大于20岁SELECT * FROM student WHERE age > 20;SELECT * FROM student WHERE age >= 20;-- 查询年龄等于20岁SELECT * FROM student WHERE age = 20;-- 查询年龄不等于20岁SELECT * FROM student WHERE age != 20;SELECT * FROM student WHERE age <> 20;-- 查询年龄大于等于20 小于等于30SELECT * FROM student WHERE age >= 20 &&  age <=30;SELECT * FROM student WHERE age >= 20 AND  age <=30;SELECT * FROM student WHERE age BETWEEN 20 AND 30;-- 查询年龄22岁,18岁,25岁的信息SELECT * FROM student WHERE age = 22 OR age = 18 OR age = 25SELECT * FROM student WHERE age IN (22,18,25);-- 查询英语成绩为nullSELECT * FROM student WHERE english = NULL; -- 不对的。null值不能使用 = (!=) 判断SELECT * FROM student WHERE english IS NULL;-- 查询英语成绩不为nullSELECT * FROM student WHERE english  IS NOT NULL;-- 查询姓马的有哪些? likeSELECT * FROM student WHERE NAME LIKE '马%';-- 查询姓名第二个字是化的人SELECT * FROM student WHERE NAME LIKE "_化%";-- 查询姓名是3个字的人SELECT * FROM student WHERE NAME LIKE '___';-- 查询姓名中包含德的人SELECT * FROM student WHERE NAME LIKE '%德%';

中间的部分内容在这里没有给出,因为本人这部分内容已经掌握,所以未给出。

今日内容

1. 多表查询
2. 事务
3. DCL

多表查询

* 查询语法:select列名列表from表名列表where....
* 准备sql# 创建部门表CREATE TABLE dept(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(20));INSERT INTO dept (NAME) VALUES ('开发部'),('市场部'),('财务部');# 创建员工表CREATE TABLE emp (id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(10),gender CHAR(1), -- 性别salary DOUBLE, -- 工资join_date DATE, -- 入职日期dept_id INT,FOREIGN KEY (dept_id) REFERENCES dept(id) -- 外键,关联部门表(部门表的主键));INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('孙悟空','男',7200,'2013-02-24',1);INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('猪八戒','男',3600,'2010-12-02',2);INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('唐僧','男',9000,'2008-08-08',2);INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('白骨精','女',5000,'2015-10-07',3);INSERT INTO emp(NAME,gender,salary,join_date,dept_id) VALUES('蜘蛛精','女',4500,'2011-03-14',1);
* 笛卡尔积:* 有两个集合A,B .取这两个集合的所有组成情况。* 要完成多表查询,需要消除无用的数据
* 多表查询的分类:1. 内连接查询:1. 隐式内连接:使用where条件消除无用数据* 例子:-- 查询所有员工信息和对应的部门信息SELECT * FROM emp,dept WHERE emp.`dept_id` = dept.`id`;-- 查询员工表的名称,性别。部门表的名称SELECT emp.name,emp.gender,dept.name FROM emp,dept WHERE emp.`dept_id` = dept.`id`;SELECT t1.name, -- 员工表的姓名t1.gender,-- 员工表的性别t2.name -- 部门表的名称FROMemp t1,dept t2WHERE t1.`dept_id` = t2.`id`;2. 显式内连接:* 语法: select 字段列表 from 表名1 [inner] join 表名2 on 条件* 例如:* SELECT * FROM emp INNER JOIN dept ON emp.`dept_id` = dept.`id`;  * SELECT * FROM emp JOIN dept ON emp.`dept_id` = dept.`id`;    3. 内连接查询:1. 从哪些表中查询数据2. 条件是什么3. 查询哪些字段2. 外链接查询:1. 左外连接:* 语法:select 字段列表 from 表1 left [outer] join 表2 on 条件;* 查询的是左表所有数据以及其交集部分。* 例子:-- 查询所有员工信息,如果员工有部门,则查询部门名称,没有部门,则不显示部门名称SELECT   t1.*,t2.`name` FROM emp t1 LEFT JOIN dept t2 ON t1.`dept_id` = t2.`id`;2. 右外连接:* 语法:select 字段列表 from 表1 right [outer] join 表2 on 条件;* 查询的是右表所有数据以及其交集部分。* 例子:SELECT  * FROM dept t2 RIGHT JOIN emp t1 ON t1.`dept_id` = t2.`id`;3. 子查询:* 概念:查询中嵌套查询,称嵌套查询为子查询。-- 查询工资最高的员工信息-- 1 查询最高的工资是多少 9000SELECT MAX(salary) FROM emp;-- 2 查询员工信息,并且工资等于9000的SELECT * FROM emp WHERE emp.`salary` = 9000;-- 一条sql就完成这个操作。子查询SELECT * FROM emp WHERE emp.`salary` = (SELECT MAX(salary) FROM emp);* 子查询不同情况1. 子查询的结果是单行单列的:* 子查询可以作为条件,使用运算符去判断。 运算符: > >= < <= =* -- 查询员工工资小于平均工资的人SELECT * FROM emp WHERE emp.salary < (SELECT AVG(salary) FROM emp);2. 子查询的结果是多行单列的:* 子查询可以作为条件,使用运算符in来判断-- 查询'财务部'和'市场部'所有的员工信息SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部';SELECT * FROM emp WHERE dept_id = 3 OR dept_id = 2;-- 子查询SELECT * FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE NAME = '财务部' OR NAME = '市场部');3. 子查询的结果是多行多列的:* 子查询可以作为一张虚拟表参与查询-- 查询员工入职日期是2011-11-11日之后的员工信息和部门信息-- 子查询SELECT * FROM dept t1 ,(SELECT * FROM emp WHERE emp.`join_date` > '2011-11-11') t2WHERE t1.id = t2.dept_id;-- 普通内连接SELECT * FROM emp t1,dept t2 WHERE t1.`dept_id` = t2.`id` AND t1.`join_date` >  '2011-11-11'* 多表查询练习-- 部门表CREATE TABLE dept (id INT PRIMARY KEY PRIMARY KEY, -- 部门iddname VARCHAR(50), -- 部门名称loc VARCHAR(50) -- 部门所在地);-- 添加4个部门INSERT INTO dept(id,dname,loc) VALUES (10,'教研部','北京'),(20,'学工部','上海'),(30,'销售部','广州'),(40,'财务部','深圳');-- 职务表,职务名称,职务描述CREATE TABLE job (id INT PRIMARY KEY,jname VARCHAR(20),description VARCHAR(50));-- 添加4个职务INSERT INTO job (id, jname, description) VALUES(1, '董事长', '管理整个公司,接单'),(2, '经理', '管理部门员工'),(3, '销售员', '向客人推销产品'),(4, '文员', '使用办公软件');-- 员工表CREATE TABLE emp (id INT PRIMARY KEY, -- 员工idename VARCHAR(50), -- 员工姓名job_id INT, -- 职务idmgr INT , -- 上级领导joindate DATE, -- 入职日期salary DECIMAL(7,2), -- 工资bonus DECIMAL(7,2), -- 奖金dept_id INT, -- 所在部门编号CONSTRAINT emp_jobid_ref_job_id_fk FOREIGN KEY (job_id) REFERENCES job (id),CONSTRAINT emp_deptid_ref_dept_id_fk FOREIGN KEY (dept_id) REFERENCES dept (id));-- 添加员工INSERT INTO emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id) VALUES (1001,'孙悟空',4,1004,'2000-12-17','8000.00',NULL,20),(1002,'卢俊义',3,1006,'2001-02-20','16000.00','3000.00',30),(1003,'林冲',3,1006,'2001-02-22','12500.00','5000.00',30),(1004,'唐僧',2,1009,'2001-04-02','29750.00',NULL,20),(1005,'李逵',4,1006,'2001-09-28','12500.00','14000.00',30),(1006,'宋江',2,1009,'2001-05-01','28500.00',NULL,30),(1007,'刘备',2,1009,'2001-09-01','24500.00',NULL,10),(1008,'猪八戒',4,1004,'2007-04-19','30000.00',NULL,20),(1009,'罗贯中',1,NULL,'2001-11-17','50000.00',NULL,10),(1010,'吴用',3,1006,'2001-09-08','15000.00','0.00',30),(1011,'沙僧',4,1004,'2007-05-23','11000.00',NULL,20),(1012,'李逵',4,1006,'2001-12-03','9500.00',NULL,30),(1013,'小白龙',4,1004,'2001-12-03','30000.00',NULL,20),(1014,'关羽',4,1007,'2002-01-23','13000.00',NULL,10);-- 工资等级表CREATE TABLE salarygrade (grade INT PRIMARY KEY,   -- 级别losalary INT,  -- 最低工资hisalary INT -- 最高工资);-- 添加5个工资等级INSERT INTO salarygrade(grade,losalary,hisalary) VALUES (1,7000,12000),(2,12010,14000),(3,14010,20000),(4,20010,30000),(5,30010,99990);-- 需求:-- 1.查询所有员工信息。查询员工编号,员工姓名,工资,职务名称,职务描述/*分析:1.员工编号,员工姓名,工资,需要查询emp表  职务名称,职务描述 需要查询job表2.查询条件 emp.job_id = job.id*/SELECT t1.`id`, -- 员工编号t1.`ename`, -- 员工姓名t1.`salary`,-- 工资t2.`jname`, -- 职务名称t2.`description` -- 职务描述FROM emp t1, job t2WHERE t1.`job_id` = t2.`id`;-- 2.查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置/*分析:1. 员工编号,员工姓名,工资 emp  职务名称,职务描述 job  部门名称,部门位置 dept2. 条件: emp.job_id = job.id and emp.dept_id = dept.id*/SELECT t1.`id`, -- 员工编号t1.`ename`, -- 员工姓名t1.`salary`,-- 工资t2.`jname`, -- 职务名称t2.`description`, -- 职务描述t3.`dname`, -- 部门名称t3.`loc` -- 部门位置FROM emp t1, job t2,dept t3WHERE t1.`job_id` = t2.`id` AND t1.`dept_id` = t3.`id`;-- 3.查询员工姓名,工资,工资等级/*分析:1.员工姓名,工资 emp  工资等级 salarygrade2.条件 emp.salary >= salarygrade.losalary and emp.salary <= salarygrade.hisalaryemp.salary BETWEEN salarygrade.losalary and salarygrade.hisalary*/SELECT t1.ename ,t1.`salary`,t2.*FROM emp t1, salarygrade t2WHERE t1.`salary` BETWEEN t2.`losalary` AND t2.`hisalary`;-- 4.查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级/*分析:1. 员工姓名,工资 emp , 职务名称,职务描述 job 部门名称,部门位置,dept  工资等级 salarygrade2. 条件: emp.job_id = job.id and emp.dept_id = dept.id and emp.salary BETWEEN salarygrade.losalary and salarygrade.hisalary*/SELECT t1.`ename`,t1.`salary`,t2.`jname`,t2.`description`,t3.`dname`,t3.`loc`,t4.`grade`FROM emp t1,job t2,dept t3,salarygrade t4WHERE t1.`job_id` = t2.`id` AND t1.`dept_id` = t3.`id`AND t1.`salary` BETWEEN t4.`losalary` AND t4.`hisalary`;-- 5.查询出部门编号、部门名称、部门位置、部门人数/*分析:1.部门编号、部门名称、部门位置 dept 表。 部门人数 emp表2.使用分组查询。按照emp.dept_id完成分组,查询count(id)3.使用子查询将第2步的查询结果和dept表进行关联查询*/SELECT t1.`id`,t1.`dname`,t1.`loc` , t2.totalFROM dept t1,(SELECTdept_id,COUNT(id) totalFROM empGROUP BY dept_id) t2WHERE t1.`id` = t2.dept_id;-- 6.查询所有员工的姓名及其直接上级的姓名,没有领导的员工也需要查询/*分析:1.姓名 emp, 直接上级的姓名 emp* emp表的id 和 mgr 是自关联2.条件 emp.id = emp.mgr3.查询左表的所有数据,和 交集数据* 使用左外连接查询*//*selectt1.ename,t1.mgr,t2.`id`,t2.enamefrom emp t1, emp t2where t1.mgr = t2.`id`;*/SELECT t1.ename,t1.mgr,t2.`id`,t2.`ename`FROM emp t1LEFT JOIN emp t2ON t1.`mgr` = t2.`id`;

事务

1. 事务的基本介绍1. 概念:* 如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败2. 操作:1. 开启事务:start transection2. 回滚:rollback3. 提交:commit3. MySQL数据库中事务默认提交* 事务提交的两种方式:* 自动提交:* mysql就是自动提交的* 一条DML(增删改)语句会自动提交一次事务。* 手动提交:* Oracle数据库默认是手动提交事务* 需要先开启事务,再提交* 修改事务的默认提交方式:* 查看事务的默认提交方式:SELECT @@autocommit; -- 1 代表自动提交  0 代表手动提交* 修改默认提交方式: set @@autocommit = 0;
2. 事务的四大特征1. 原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。2. 持久性:当事务提交或回滚后,数据库会持久化的保存数据。3. 隔离性:多个事务之间。相互独立。4. 一致性:事务操作前后,数据总量不变
3. 事务的隔离级别(了解)* 概念:多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。* 存在问题:1. 脏读:一个事务,读取到另一个事务中没有提交的数据2. 不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。3. 幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。* 隔离级别:1. read uncommitted:读未提交* 产生的问题:脏读、不可重复读、幻读2. read committed:读已提交 (Oracle)* 产生的问题:不可重复读、幻读3. repeatable read:可重复读 (MySQL默认)* 产生的问题:幻读4. serializable:串行化* 可以解决所有的问题* 注意:隔离级别从小到大安全性越来越高,但是效率越来越低* 数据库查询隔离级别:* select @@tx_isolation;* 数据库设置隔离级别:* set global transaction isolation level  级别字符串;* 演示:set global transaction isolation level read uncommitted;start transaction;-- 转账操作update account set balance = balance - 500 where id = 1;update account set balance = balance + 500 where id = 2;

DCL

* SQL分类:1. DDL:操作数据库和表2. DML:增删改表中数据3. DQL:查询表中数据4. DCL:管理用户,授权* DBA:数据库管理员* DCL:管理用户,授权1. 管理用户1. 添加用户:* 语法:CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';2. 删除用户:* 语法:DROP USER '用户名'@'主机名';3. 修改用户密码:UPDATE USER SET PASSWORD = PASSWORD('新密码') WHERE USER = '用户名';UPDATE USER SET PASSWORD = PASSWORD('abc') WHERE USER = 'lisi';SET PASSWORD FOR '用户名'@'主机名' = PASSWORD('新密码');SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123');* mysql中忘记了root用户的密码?1. cmd -- > net stop mysql 停止mysql服务* 需要管理员运行该cmd2. 使用无验证方式启动mysql服务: mysqld --skip-grant-tables3. 打开新的cmd窗口,直接输入mysql命令,敲回车。就可以登录成功4. use mysql;5. update user set password = password('你的新密码') where user = 'root';6. 关闭两个窗口7. 打开任务管理器,手动结束mysqld.exe 的进程8. 启动mysql服务9. 使用新密码登录。4. 查询用户:-- 1. 切换到mysql数据库USE myql;-- 2. 查询user表SELECT * FROM USER;* 通配符: % 表示可以在任意主机使用用户登录数据库2. 权限管理:1. 查询权限:-- 查询权限SHOW GRANTS FOR '用户名'@'主机名';SHOW GRANTS FOR 'lisi'@'%';2. 授予权限:-- 授予权限grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';-- 给张三用户授予所有权限,在任意数据库任意表上GRANT ALL ON *.* TO 'zhangsan'@'localhost';3. 撤销权限:-- 撤销权限:revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';REVOKE UPDATE ON db3.`account` FROM 'lisi'@'%';

Day 04 内容:

07/07/2020

1. JDBC基本概念
2. 快速入门
3. 对JDBC中各个接口和类详解

JDBC

1. 概念:Java DataBase Connectivity  Java数据库连接,Java语言操作数据库* JDBC本质:其实是官网(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商可以去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类2. 快速入门:* 步骤:1. 导入驱动jar包 mysql-connnector-java-x.x.x-bin.jar1. 复制mysql-connnector-java-x.x.x-bin.jar包到项目libs目录下2. 右键-->Add as library2. 注册驱动3. 获取数据库的连接对象 Connection4. 定义sql5. 获取执行sql语句的对象 Statement6. 执行sql,接收返回结果7. 处理结果8. 释放资源* 代码实现:// 1.导入驱动jar包// 2.注册驱动Class.forName("com.mysql.jdbc.Driver");// 3.获取数据库连接对象Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1","root", "********");// 4.定义sql语句String sql = "insert into test values(1, \"test\")";// 5.获取执行sql的对象StatementStatement statement = connection.createStatement();// 6.执行sqlint count = statement.executeUpdate(sql);// 7.处理结果System.out.println(count);// 8.释放资源statement.close();connection.close();3. 详解各个对象1. DriverManager: 驱动管理对象* 功能:1. 注册驱动:告诉程序该使用哪一个数据库驱动jar包static void registerDriver(Driver driver): 注册给定的驱动程序 DriverManager写代码使用: Class.forName("com.mysql.jdbc.Driver");通过查看源码发现: 在com.mysql.jdbc.Driver类中存在静态代码块static {try {DriverManager.registerDriver(new Driver());} catch (SQLException var1) {throw new RuntimeException("Can't register driver!");}}注意:mysql5之后的驱动jar包可以省略注册驱动的步骤2. 获取数据库连接:* 方法: static Connerction getConnection(String url, String user, String password)* 参数:* url:指定连接的路径* 语法: jdbc:mysql://ip地址(域名):端口号/数据库名称* 例子: jdbc:mysql://localhost:3306/db1* 细节: 如果连接的是本机mysql服务器,并且mysql服务默认端口为3306,则url可以简写为jdbc:mysql:///数据库名称* user:用户名* password:密码2. Connection: 数据库连接对象1. 功能:1. 获取执行sql的对象* Statement createStatement()* PreparedStatement prepareStatement(String sql)2。 管理事务:* 开启事务: void setAutoCommit(boolean autoCommit) : 调用该方法设置参数为false,即开启事务* 提交事务: void commit()* 回滚事务: void rollback()3. Statement: 执行sql的对象1. 执行sql1. booleann execute(String sql) : 可以执行任意的sql 了解2. int executeUpdate(String sql) : 执行DML(insert、update、delete)语句、DDL(create、alter、drop)语句* 返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功 返回值>0执行成功 反之失败3. ResultSet executeQuery(String sql) : 执行DQL(select)语句2. 练习:1. account表 添加一条记录2. account表 修改记录3. account表 删除一条记录代码:Connection connection = null;Statement statement = null;try {// 1.注册驱动Class.forName("com.mysql.cj.jdbc.Driver");// 2.定义sqlString sql = "insert into account values(null, '王五', 3000)";// 3.获取Connection对象connection= DriverManager.getConnection("jdbc:mysql:///db1","root", "******");// 4.获取执行sql的对象statement = connection.createStatement();// 5.执行sqlint count = statement.executeUpdate(sql);// 6.处理结果System.out.println(count);if(count > 0){System.out.println("添加成功");}else{System.out.println("添加失败");}} catch (ClassNotFoundException | SQLException e) {e.printStackTrace();} finally {// 避免空指针异常if(statement != null){try {statement.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(connection != null){try {connection.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}4. ResultSet: 结果集对象,封装查询结果* next():游标向下移动一行,判断当前行是否是最后一行末尾(是否有数据),返回boolean值* getXxx(参数):获取数据* Xxx代表数据类型  如: int getInt()* 参数:1. int: 代表列的编号,从1开始2. String: 代表列名称* 注意:* 使用步骤:1. 游标向下移动一行2. 判断是否有数据3. 获取数据while(rs.next()){...}* 练习:* 定义一个方法,查询emp表的数据将其封装为对象,然后装载集合,返回。1. 定义Emp类2. 定义方法 public List<Emp> findAll(){}3. 实现方法 select * from emp;5. PreparedStatement: 执行sql的对象1. SQL注入问题: 在拼接SQL时,有一些sql的特殊关键字参与字符串的拼接,会造成安全性问题1. 输入用户随便,输入密码:a' or 'a' = 'a2. sql : select * from USER where username = 'xxx' and password = 'a' or 'a' = 'a';2. 解决sql注入问题:使用PreparedStatement来解决3. 预编译的SQL:参数使用?作为占位符4. 步骤:1. 导入驱动jar包 mysql-connnector-java-x.x.x-bin.jar2. 注册驱动3. 获取数据库的连接对象 Connection4. 定义sql* 注意:sql的参数使用?作为占位符。如: select * from user where username = ? and password = ?5. 获取执行sql语句的对象 PreparedStatement   Connection.preparedStatement(String sql)6. 给?赋值:* 方法:setXxx(参数1, 参数2)* 参数1: ?的位置编号 从1 开始* 参数2: ?的值7. 执行sql,接收返回结果,不需要传递sql语句8. 处理结果9. 释放资源5. 注意:后期都会使用PreparedStatement来完成增删改查的所有操作1. 可以防止sql注入2. 效率更高

抽取JDBC工具类 : JDBCUtils

* 目的:简化书写
* 分析:1. 注册驱动也抽取2. 抽取一个方法获取连接对象* 需求:不想传递参数(麻烦),还得保证工具类的通用性。* 解决:配置文件jdbc.propertiesurl=user=password=3. 抽取一个方法释放资源
* 代码实现:public class JDBCUtils {private static String url;private static String user;private static String password;private static String driver;/*** 文件的读取只需要读取一次即可拿到这些值,使用静态代码块完成*/static {try {// 读取资源文件,获取值。// 1.创建Properties集合类Properties pro = new Properties();// 获取src路径下的文件的方式--->ClassLoader 类加载器ClassLoader classLoader = JDBCUtils.class.getClassLoader();URL result = classLoader.getResource("jdbc.properties");String path = result.getPath();// 2.加载文件pro.load(new FileReader(path));// 3.获取属性赋值url = pro.getProperty("url");user = pro.getProperty("user");password = pro.getProperty("password");driver = pro.getProperty("driver");// 4.注册驱动try {Class.forName(driver);} catch (ClassNotFoundException e) {e.printStackTrace();}} catch (IOException e) {e.printStackTrace();}}/*** 获取连接* @return 连接对象*/public static Connection getConnection() throws SQLException {return DriverManager.getConnection(url, user, password);}/*** 释放资源* @param statement* @param connection*/public static void close(Statement statement, Connection connection){if(statement != null){try {statement.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(connection != null){try {connection.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}public static void close(ResultSet resultSet, Statement statement, Connection connection){if(statement != null){try {statement.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(connection != null){try {connection.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(resultSet != null){try {resultSet.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}}* 练习:* 需求:1. 通过键盘录入用户名和密码2. 判断用户是否登录成功* select * from USER where username = '' and password = '';* 如果这个sql有查询结果,则成功,反之失败* 步骤:1. 创建数据库表 userCREATE TABLE USER(id INT PRIMARY KEY AUTO_INCREMENT,username varchar(32),password varchar(32));INSERT INTO USER VALUES(NULL,'zhangsan','123');INSERT INTO USER VALUES(NULL,'lisi','234');2. 创建一个类......

JDBC控制事务

1. 事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则者多个步骤要么同时成功,要么同时失败。
2. 操作:1. 开启事务2. 提交事务3. 回滚事务
3. 使用Connection对象来管理事务* 开启事务: void setAutoCommit(boolean autoCommit)    : 调用该方法设置参数为false,即开启事务* 在执行sql之前开启事务(在获得连接后开启)* 提交事务: void commit()* 当所有sql都执行完提交事务* 回滚事务: void rollback()* 在catch中回滚事务

Day 05 内容:

1. 数据库连接池
2. Spring JDBC : JDBC Template

数据库连接池

1. 概念:其实就是一个容器(集合),存放数据库连接的容器当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。2. 好处:1. 节约资源2. 用户访问高效3. 实现:1. 标准接口:DataSource   javax.sql包下的1. 方法:* 获取连接:getConnection()* 归还连接:Connection.close()如果连接对象Connection是从连接池中获取的,那么调用Connection.close(),则不会再关闭连接,而是归还连接。2. 一般我们不去实现它,由数据库厂商实现1. C3P0:数据库连接池技术2. Druid:数据库连接池实现技术,由阿里巴巴提供的4. C3P0:数据库连接池技术* 步骤:1. 导入jar包 (两个)c3p0-0.6.5.2.jar mchange-commons-java-0.2.12.jar* 不要忘记导入数据库驱动jar包2. 定义配置文件:* 名称:c3p0.properties 或者 c3p0-config.xml* 路径:直接将文件放在src目录下即可3. 创建核心对象:数据库连接池对象 ComboPooledDataSource4. 获取连接:getConnection()5. Druid:数据库连接池实现技术,由阿里巴巴提供的1. 步骤:1. 导入jar包 druid-1.0.9.jar2. 定义配置文件:* 是properties形式的* 可以叫任意名称,可以放在任意目录下3. 加载配置文件  Properties4. 获取数据库连接池对象:通过工厂类来获取 DruidDataSourceFactory5. 获取连接:getConnection()2. 定义工具类1. 定义一个类 JDBCUtils2. 提供静态代码块加载配置文件,初始化连接池对象3. 提供方法1. 获取连接方法:通过数据库连接池获取连接2. 释放资源3. 获取连接池的方法代码:/*** Druid连接池的工具类*/public class JDBCUtils {// 1.定义成员变量 DataSourceprivate static DataSource ds;static {try {// 1.加载配置文件Properties pro = new Properties();pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));// 2.获取DataSourceds = DruidDataSourceFactory.createDataSource(pro);} catch (Exception e) {e.printStackTrace();}}/*** 获取连接*/public static Connection getConnection() throws SQLException {return ds.getConnection();}/*** 释放资源* @param statement* @param connection*/public static void close(Statement statement, Connection connection){if(statement != null){try {statement.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(connection != null){try {connection.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}public static void close(ResultSet resultSet, Statement statement, Connection connection){if(statement != null){try {statement.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(connection != null){try {connection.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if(resultSet != null){try {resultSet.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}/*** 获取连接池方法*/public static DataSource getDataSource(){return ds;}}

Spring JDBC

* Spring框架对JDBC的简单封装。提供了JDBC Template对象简化JDBC的开发
* 步骤:1. 导入jar包2. 创建JdbcTemplate对象。依赖于数据源DataSource* JdbcTemplate template = new JdbcTemplate(ds);3. 调用JdbcTemplate的方法来完成CRUD的操作* update(): 执行DML语句。增、删、改语句* queryForMap(): 查询结果,将结果集封装为Map集合,将列名作为key,将值作为value,将这条记录封装为value* 注意:这个方法查询的结果集长度只能是1* queryForList(): 查询结果,将结果集封装为list集合* 注意:将每一条记录封装为Map集合,再将Map集合装载在List集合中* query(): 查询结果,将结果封装为JavaBean对象* query方法的参数:RowMapper* 一般使用BeanPropertiyRowMapper实现类。可以完成数据到JavaBean的自动封装。* new BeanPropertyRowMapper<类型>(类型.class)* queryForObject(): 查询结果,将结果封装为对象* 一般用于聚合函数的查询 4. 练习:* 需求:1. 修改1号数据的 salary 为 100002. 添加一条记录3. 删除刚才添加的记录4. 查询id为1的记录,将其封装为Map集合5. 查询所有的记录,将其封装为List集合6. 查询所有记录,将其封装为Emp对象的List集合7. 查询总的记录数

Day 06 内容:

1. web概念概述
2. HTML

web概念概述

* JavaWeb:* 使用Java语言开发基于互联网的项目* 软件的架构:1. C/S:Client/Server 客户端/服务器端* 在用户本地有一个客户端程序,在远程有一个服务器端程序* 如:QQ,迅雷...* 优点:1. 用户体验好* 缺点:1. 开发、安装、部署、维护麻烦2. B/S:Browser/Server 浏览器/服务器端* 只需要一个浏览器,用户通过不同的网址(URL),可以访问远程不同的服务器端程序* 优点:1. 开发、安装、部署、维护简单* 缺点:1. 如果应用过大,用户的体验可能会受到影响2. 对硬件要求过高* B/S架构详解* 资源分类:1. 静态资源:* 使用静态网页开发技术发布的资源* 特点:* 所有用户访问,得到的结果是一样的* 如:文本、图片、音频、视频,HTML,CSS,JavaScript* 如果用户请求的是静态资源,那么服务器会直接将静态资源发送给浏览器,浏览器中内置了静态资源的解析引擎2. 动态资源:* 使用动态网页技术发布的资源* 特点:* 所有用户访问,得到的结果可能不一样* 如:jsp/servlet,php,asp...* 如果用户请求的是动态资源,那么服务器将会执行动态资源,转换为静态资源,再发送给浏览器* 我们要学习动态资源,必须先学习静态资源!* 静态资源:* HTML:用于搭建基础网页,展示页面的内容* CSS:用于美化页面,布局页面* JavaScript:控制页面的元素,让页面有一些动态的效果

HTML

1. 概念:是最基础的网页开发语言* Hyper Text Markup Language 超文本标记语言* 超文本:* 超文本是用超链接的方法,将各种不同空间的文字信息组织在一起的网状文本。* 标记语言:* 由标签构成的语言。<标签名称> 如html, xml* 标记语言不是编程语言2. 快速入门:* 语法:1. html文档后缀名 .html 或者 .htm2. 标签分为1. 围堵标签:有开始标签和结束标签。如 <html> </html>2. 自闭和标签:开始标签和结束标签在一起。 如 <br />3. 标签可以嵌套:需要正确嵌套,不能你中有我,我中有你错误: <a><b></a></b>正确: <a><b></b></a>4. 在开始标签中可以定义属性。属性是由键值对组成,值需要用引号(单双都可)引起来5. html的标签不区分大小写,建议使用小写。3. 标签学习:1. 文件标签:构成html最基本的标签* html:html文档的根标签* head:头标签。用于指定html文档的一些属性。引入外部的资源* title:标题标签* body:体标签* <!DOCTYPE html>:html5中定义改文档是html文档2. 文本标签:和文本有关的标签* 注释:<!-- -->* <h1> to <h6>:标题标签* h1~h6字体大小主键递减* <p>:段落标签* <br>:换行标签* <hr>:展示一条水平线* 属性:* color:颜色* width:宽度* size:高度* align:对齐方式* center:居中* left:左对齐* right:右对齐* <b>:字体加粗* <i>:字体斜体* <font>:字体标签* 属性:* color:颜色* size:大小* face:字体* <center>:文本居中* 属性定义:* color:1. 英文单词:red,green,blue2. rgb(值1, 值2, 值3):值的范围:0~255 如 rgb(0,0,2555)3. #值1值2值3:值的范围:00~FF。 如: #FF00FF* width:1. 数值:width='20',数值的单位,默认是 px(像素)2. 数值% :占比相对于父元素的比例* 案例...3. 图片标签* img:展示图片* 属性:* src:指定图片位置* 相对路径:* 以.开头的路径* ./: 代表当前目录  ./image/1.jpg* ../: 代表上一级目录4. 列表标签:* 有序列表:* ol* li* 无序标签:* ul* li5. 链接标签* a:定义一个超链接* 属性:* href:指定访问资源的URL(统一资源定位符)* target:指定打开资源的方式* _self:默认值,在当前页面打开* _blank:在空白页面打开6. div和span:* div:每个div占满一整行。块级标签* span:文本信息在一行展示,行内标签,内联标签。7. 语义化标签:html5中为了提高程序的可读性,提供了一些标签1. <header>: 页眉2. <footer>: 页脚8. 表格标签* table:定义表格* width:宽度* border:边框* cellpadding:定义内容和单元格的距离* cellspacing:定义单元格之间的距离。如果指定为0,则单元格的线会合为一条。* bgcolor:背景色* align:对齐方式* tr:定义行* bgcolor:背景色* align:对齐方式* td:定义单元格* colspan:合并行* rowspan:合并列* th:定义表头单元格* <caption>:表格标题* <thead>:表示表格的头部分* <tbody>:表示表格的体部分* <tfoot>:表示表格的脚部分

案例:旅游网站首页

1. 确定使用table来完成布局
2. 如果某一行只有一个单元格,则使用<tr><td></td></tr>
3. 如果某一行有多个单元格,则使用<tr><td><table></table></td></tr>

Day 07 内容:

1. HTML标签:表单标签
2. CSS:

HTML标签:表单标签

* 表单:* 概念:用于采集用户输入的数据的。用于和服务器进行交互。* form: 用于定义表单的。可以定义一个范围,范围代表用户采集数据的范围* 属性:* action:指定提交数据的URL* method:指定提交方式* 分类:一共七种,两种比较常用* GET:1. 请求参数会在地址栏中显示,会封装到请求行中(HTTP协议后讲解)2. 请求参数的大小是有限制的3. 不太安全* POST:1. 请求参数不会在地址栏中显示,会封装在请求体中(HTTP协议后讲解)2. 请求参数的大小没有限制3. 较为安全* 表单项中的数据要想被提交,必须指定其name属性* 表单项标签:* input:可以通过type属性值,改变元素展示的样式* type属性:* text:文本输入框,默认值* placeholder:指定输入框的提示信息,当输入框的内容发生变化,会自动清楚提示信息* password:密码输入框* radio:单选框* 注意:1. 要想让多个单选框实现单选的效果,则多个单选框的name属性值必须一样2. 一般会给每一个单选框提供value属性,指定其被选中后提交的值3. checked属性,可以指定默认值* checkbox:复选框* 注意:1. 一般会给每一个单选框提供value属性,指定其被选中后提交的值2. checked属性,可以指定默认值* file:文件选择框* hidden:隐藏域,用于提交一些信息* 按钮:* submit: 提交按钮,用于提交表单* button:普通按钮* image:图片提交按钮* label:指定输入项的文字描述信息* 注意* label的for属性一般会和input的id属性值对应。如果对应了,则点击label区域,会让input输入框获取焦点* select:下拉列表* 子元素option,指定列表项* textarea:文本域* cols:指定列数* rows:指定行数

CSS: 页面美化和布局控制

1. 概念:Cascading Style Sheets 层叠样式表* 层叠:多个样式可以作用在同一个html的元素上,同时生效2. 好处:1. 功能强大2. 将内容展示和样式控制分类* 降低耦合度,解耦* 让分工合作更容易* 提高开发效率3. CSS的使用:CSS和HTML结合方式1. 内联样式* 在标签内使用style属性指定css代码* 如 <div style="color:red;"></div>2. 内部样式* 在head标签内部定义style标签,style的标签内容就是css代码* 如    <style>div{color:blue;}</style><div></div>3. 外部样式1. 定义css资源文件2. 在head标签内定义link标签,引入外部资源文件* 注意:* 1、2、3种方式,作用范围越来越大* 1方式不常用,后期常用2、3* 第3种格式可以写为:<style>@import "css/a.css";</style>4. css语法:* 格式:选择器 {属性名1:属性值1;属性名2:属性值2;...}* 选择器:筛选具有相似特征的元素* 注意:* 每一对属性需要用分号隔开,最后一对属性可以不加5. 选择器:* 分类:1. 基础选择器1. id选择器:选择具体的id属性值的元素,建议在一个html界面中id值唯一* 语法:#id属性值{}2. 元素选择器:选择具有相同标签的元素* 语法:标签名称{}* 注意:id选择器优先级高于元素选择器3. 类选择器:选择具有相同的class属性的元素* 语法:.class属性值{}* 注意:类选择器优先级高于元素选择器2. 扩展选择器:1. 选择所有元素* 语法:* {}2. 并集选择器* 语法:选择器1,选择器2 {}3. 子选择器:筛选选择器1元素下的选择器2* 语法:选择器1 选择器2 {}4. 父选择器:筛选选择器2父元素选择器1* 语法:选择器1 > 选择器2 {}5. 属性选择器:选择元素名称,属性名=属性值的元素* 语法:元素名称[属性名="属性值"] {}6. 伪类选择器:选择一些元素具有的状态* 语法:元素:状态 {}* 如:<a>* 状态:* link:初始化的状态* visited:被访问过的状态* active:正在访问状态* hover:鼠标悬浮状态6. 属性1. 字体、文本* font-size:字体大小* color:文本颜色* text-alion:对齐方式* line-height:行高2. 背景* background:复合属性3. 边框* border:设置边框,复合属性4. 尺寸* width:宽度* height:高度5. 盒子模型:控制布局* margin:外边距* padding:内边距* 默认情况下内边距会影响整个盒子的大小* box-sizing: border-box* float:浮动* left* right

Day 08 内容:

1. JavaScript基础

JavaScript:

* 概念:一门客户端脚本语言* 运行在客户端浏览器中。每一个浏览器都有JavaScript的解析引擎* 脚本语言:不需要编译,直接就可以被浏览器解析执行了* 功能:* 可以来增强用户和HTML页面的交互过程,可以来控制HTML元素,让页面有一些动态的效果,增强用户的体验。* JavaScript发展史:1. 1992年,Nombase公司,开发出第一门客户端脚本语言,专门用于表单的校验。命名为:C--,后来更名为:ScriptEase2. 1995年,Netscape(网景)公司,开发了一门客户端脚本语言:LiveScript。请来SUN公司的专家,修改LiveScript,命名为JavaScript3. 1996年,微软抄袭JavaScript开发出JScript语言4. 1997年,ECMA(欧洲计算机制造商协会),ECMAScript,就是所有客户端脚本语言的标准。* JavaScript = ECMAScript + JavaScript自己特有的东西(BOM + DOM)* ECMAScript:客户端脚本语言的标准1. 基本语法:1. 与HTML结合方式1. 内部JS:* 定义<script>,标签体内容就是js代码2. 外部JS:* 定义<script>,通过src属性引入外部的js文件* 注意:1. <script>可以定义在html页面的任何地方,但是定义的位置会影响执行的顺序。2. <script>可以定义多个。2. 注释1. 单行注释:// 注释内容2. 多行注释:/* 注释内容 */3. 数据类型:1. 原始数据类型(基本数据类型):1. number:数字。 整数/小数/NaN(not a number 一个不是数字的数字类型)2. string:字符串。 字符串 'abc' "a"3. boolean:true和false4. null:一个对象为空的占位符5. undefined:未定义。如果一个变量没有给初始化值,则会被默认为undefined2. 引用数据类型:对象4. 变量* 变量:一小块存储数据的内存空间* Java语言是强类型语言,而JavaScript是弱类型语言* 强类型:在开辟变量存储空间时,定义了空间将来存储的数据的数据类型。只能存储固定类型的数据。* 弱类型:在开辟变量存储空间时,不定义空间将来存储的数据的数据类型。可以存储任意类型的数据。* 语法:* var 变量名 = 初始化值;* typeof运算符:获取变量的类型* 注:null运算符后得到的时object5. 运算符1. 一元运算符:只有一个运算数的运算符++ -- +(正号)2. 算数运算符+ - * / %3. 赋值运算符= += -= ...4. 比较运算符> < >= <= == ===(全等于)* 比较方式1. 类型相同,直接比较* 字符串,按照字典顺序比较,按位逐一比较,直到得出大小为止。2. 类型不同,先进行类型转换,再比较* ===,全等于,在比较前先判断类型,如果类型不一样,则直接返回false5. 逻辑运算符&& || !* 其他类型转boolean1. number:0或NaN为假,其他为真2. string:除了空字符串(""),其他都是true3. null&undefined:false4. 对象:所有对象都为true* 可用if(obj)判断1. obj为空字符串2. obj为null或者undefined6. 三元运算符? :6. 流程控制语句:1. if...else...2. swtich* 在java种,switch语句可以接受的数据类型: byte int short char enum(1.5) String(1.7)* 在JS种,swtich语句可以接受任意的原始数据类型3. while4. do...while5. for7. JS特殊语法:1. 语句以;结尾,如果一行只有一条语句,则可以省略2. 变量的定义使用var关键字,也可以不使用* 用,定义的变量是局部变量* 不用,定义的变量是全局变量2. 基本对象:* Function:函数对象1. 创建1. var 方法名 = new Function(形式参数列表, 方法体);2. function 方法名(形式参数列表) {方法体}3. var 方法名 = function(形式参数列表) {方法体}2. 方法3. 属性length:代表形参的个数4. 特点1. 方法定义是,形参的类型不用写,返回值类型也不写2. 方法是一个对象,如果定义名称相同的方法,会覆盖3. 在JS中,方法的调用只与方法的名称有关,和参数列表无关4. 在方法声明中有一个隐藏的内置对象(数组),arguments,封装所有的实际参数5. 调用方法名称(实际参数列表);* Array:数组对象1. 创建:1. var arr = new Array(元素列表);2. var arr = new Array(默认长度);3. var arr = [元素列表];2. 方法join(参数):将数组中的元素按照指定的分隔符拼接为字符串push(参数):往数组最后添加一个元素3. 属性length:数组长度4. 特点1. JS中,数组元素的类型可变的。2. JS中,数组的长度是可变的。* Boolean* Date:日期对象1. 创建var date  = new Date();2. 方法toLocaleString():返回当前Date对象对应的实际本地字符串格式getTime():获取毫秒值,返回当前日期对象描述的时间和1970年1月1日零点的毫秒值差* Math:数学对象1. 创建:* 特点:Math对象不用创建直接使用。  Math.方法名();2. 方法:random():返回0~1之间的随机数。含0不含1cell(x):向上取整floor(x):向下取整round(x):四舍五入3. 属性PI* NUmber* String* RegExp:正则表达式对象1. 正则表达式:定义字符串的组成规则。1. 单个字符:[]如:[a] [ab] [a-zA-Z0-9]* 特殊符合代表特殊含义的单个字符\d:单个数字字符[0-9]\w:单个单词字符[a-zA-Z0-9_]2. 量词符号:?:表示出现0次或1次*:表示出现0次或多次+:出现一次或多次{m,n}:表示数量 m<=数量<=n* m如果缺省:{,n}:最多n次* n如果缺省:{m,}:最少m次3. 开始结束符号* ^:开始* $:结束2. 正则对象:1. 创建:1. var reg = new RegExp("正则表达式"); 注意反斜线的转义\\2. var reg = /正则表达式/;2. 方法1. test(参数):验证指定的字符串是否符合正则表达式* Global1. 特点:全局对象,这个Global中封装的方法不需要对象就可以直接调用。 方法名();2. 方法:encodeURI():url编码decodeURI():url解码encodeURIComponent():url编码,编码的字符更多decodeURIComponent():url解码parseInt():将字符串转为数字* 注意判断每一个字符是否是数字,直到不是数字为止,将前面数字的部分转为number* 没有数字转为NaNisNaN():判断一个值是否为NaN* 参与的==比较都为false 包括其自身参与的比较eval():将JS字符串转换为脚本运行3. URL编码* GBK编码:一个汉字两个字节* UTF-8编码:一个汉字三个字节* BOM
* DOM

Day 09 内容:

1. JavaScript:1. ECMAScript2. BOM3. DOM:1. 事件

DOM简单学习:为了满足案例要求

* 功能:控制HTML文档的内容
* 代码:获取页面标签(元素)对象    Element* document.getElementById("id值");  通过元素id获取元素对象* 操作Element对象:1. 修改属性值:1. 明确获取的对象是哪一个2. 查看API文档,找其中有哪些属性可以设置2. 修改标签体内容:* 属性:innerHTML

事件简单学习

* 功能:某些组件被执行了某些操作后,触发某些代码的执行。
* 如何绑定事件1. 直接在HTML标签上,指定事件的属性,属性值就是JS代码1. 事件:onclick--- 单击事件2. 通过JS获取元素对象,指定事件属性,设置一个函数

案例

* 分析1. 获取图片对象2. 绑定单击事件3. 每次点击切换图片* 规则,如果on换为off,反之亦然* 使用标记flag完成

BOM

1. 概念:Browser Object Model 浏览器对象模型* 将浏览器的各个部分封装成对象。
2. 组成* Window:窗口对象* Navigator:浏览器对象* Screen:显示器屏幕对象* History:历史记录对象* Location:地址栏对象3. Window:窗口对象1. 创建2. 方法1. 与弹出框有关的方法alert()    弹出警告框confirm()  弹出对话框(确认或者取消)* 如果点击确定 返回true* 点击取消 返回falseprompt()  弹出可输入的对话框* 返回值,获取用画输入的内容2. 与打开关闭有关的方法close() 关闭浏览器窗口* 谁调用关谁open() 打开一个浏览器窗口* 返回新的Window对象3. 与定时器有关的方法setTimeout()    在指定的毫秒数后调用函数或计算表达式。* 参数:1. js代码或者方法对象2. 毫秒值* 返回值:唯一标识,用于取消定时器clearTimeout()    取消由setTimeout()方法设置的timeout。setInterval()   按照指定的周期(以毫秒计)来调用函数或计算表达式。clearInterval()  取消由setInterval()设置的timeout。3. 属性1. 获取其他BOM对象historylocationNavigatorScreen2. 获取DOM对象document4. 特点* Window对象不需要创建可以直接使用 window来使用 window.方法名();* window引用可以省略。   方法名();4. Location:地址栏对象1. 创建(获取):1. window.location2. location2. 方法* reload() 重新加载当前文档 刷新3. 属性* href 设置或返回完整的URL5. History:历史记录对象1. 创建(获取):1. window.history2. history2. 方法:* back()    加载history列表中的前一个 URL。* forward()    加载history列表中的下一个 URL。* go(参数)   加载history列表中的某个具体页面。* 参数* 正数:前进几个历史记录* 负数:后退几个历史记录3. 属性* length   返回浏览器历史列表中的 URL 数量。

DOM

* 概念:Document Object Model 文档对象模型* 将标记语言文档的各个部分,封装为对象。可以使用这些对象,对标记语言文档进行CRUD的动态操作
* W3C DOM 标准被分为3个不同的部分:* 核心DOM - 针对任何结构化文档的标准模型* Document:文档对象* Element:元素对象* Attribute:属性对象* Text:文本对象* Comment:注释对象* Node:节点对象,其他5个的父对象* XML DOM - 针对XML文档的标准模型* HTML DOM - 针对HTML文档的标准模型 * 核心DOM模型:* Document:文档对象1. 创建(获取),在html dom模型中可以使用window对象来获取1. window.document2. document2. 方法1. 获取Element对象:1. getElementById():根据id属性值获取元素对象,id属性值一般唯一2. getElementByTagName():根据元素名称获取元素对象们,返回值是一个数组3. getElementByClassName():根据Class属性值获取元素对象们,返回值是一个数组4. getElementByName():根据name属性值获取元素对象们,返回值是一个数组2. 创建其他DOM对象createAttribute(name)createComment()createElement()createTextNode()* Element:元素对象1. 创建(获取),通过document来获取和创建2. 方法:1. removeAttribute():删除属性2. setAttribute():设置属性* Node:节点对象,其他5个的父对象* 特点:所有dom对象都可以被认为是一个节点* 方法:* CRUD dom树* appendChild():向节点的子节点列表的结尾添加新的子节点。* removeChild():删除(并返回)当前节点的指定子节点。* replaceChild():用新节点替换一个子节点。* 属性* parentNode:返回节点的父节点。* HTML DOM1. 标签体的设置和获取:innerHTML2. 使用html元素对象和属性3. 控制样式1. 使用元素的style属性来设置如: div.style.fontSize = "20px";2. 提前定义好类选择器的样式,通过元素的className属性来设置其class属性值

事件监听机制

* 概念:某些组件被执行了某些操作后,触发某些代码的执行。* 事件:某些操作  如:单击、双击、键盘* 事件源:组件    如:按钮、文本输入框* 监听器:代码    * 注册监听:将事件源、事件、监听器绑定在一起。当事件源上发生了某个事件,则触发执行某个监听器代码* 常见的事件:1. 点击事件:1. onclick:单击事件。2. ondblclick:双击事件。2. 焦点事件:1. onblur:失去焦点。* 一般用于表单验证2. onfocus:元素获得焦点。3. 加载事件1. onload:一张页面或一张图像加载完成。4. 鼠标事件1. onmousedown   鼠标按钮被按下。* 定义方法时,定义一个形参,接收event对象。* event对象的button属性可以获取鼠标哪个键被点击了2. onmousemove    鼠标被移动。3. onmouseout 鼠标从某元素移开。4. onmouseover 鼠标移到某元素之上。5. onmouseup  鼠标按键被松开。5. 键盘事件1. onkeydown 某个键盘按键被按下。2. onkeyup    某个键盘按键被松开。3. onkeypress 某个键盘按键被按下并松开。6. 选择和改变1. onchange    域的内容被改变。2. onselect 文本被选中。7. 表单事件1. onsubmit 确认按钮被点击。* 可以阻止表单的提交* 方法返回false,则表单被阻止提交* 注意:如果在标签中使用onsubmit 如<form onsubmit='false'></from>这样是无法实现的,原因是在系统进行创建html页面时会调用onsubmit = function(){"onsubmit=内的内容"}也就是onsubmit = function(){false},这个就相当于是没有返回值的,所以无法完成,要想完成,可以通过<form onsubmit='return false'></from>这样来完成,或者在script标签中通过DOM获取form对象设置onsubmit来完成,即document.getElementById('form').onsubmit=function (){return false};即可2. onreset   重置按钮被点击。* 案例...见相应教程 这里就不赘述了https://www.bilibili.com/video/BV1J4411877m?p=189https://www.bilibili.com/video/BV1J4411877m?p=190

Day 10 内容:

1. Bootstrap

Boostrap

1. 概念:一个前端开发的框架。Bootstrap是美国Twitter公司的设计师Mark Otto和Jacob Thornton合作基于HTML、CSS、JavaScript 开发的简洁、直观、强悍的前端开发框架,使得 Web 开发更加快捷。* 框架:一个半成品软件,开发人员可以在框架基础上,再进行开发,简化编码* 好处1. 定义了很多css样式和js插件。我们开发人员可以直接使用这些样式和插件得到丰富的页面效果。2. 响应式布局。* 同一套页面可以兼容不同分辨率的设备。2. 快速入门1. 下载Bootstrap2. 在项目中将这三个文件夹复制3. 创建html页面,引入必要的资源文件

响应式布局

* 同一套页面可以兼容不同分辨率的设备。
* 实现:依赖于栅格系统——将一行平均分成12个格子,可以去指定元素占几个格子
* 步骤:1. 定义容器,相当于之前的table* 容器分类:1. container:两边留白2. container-fluid:每一种设备都是100%宽度2. 定义行,相当于之前的tr       样式:row3. 定义元素。指定该元素在不同的设备上所占的格子数目。   样式:col-设备代号-格子数目* 设备代号:1. xs:超小屏幕 手机 (<768px):col-xs-122. sm:小屏幕 平板 (≥768px)3. md:中等屏幕 桌面显示器 (≥992px)4. lg:大屏幕 大桌面显示器 (≥1200px)* 注意:1. 一行中如果格子数目超过12,则超出部分自动换行2. 栅格类属性可以向上兼容,栅格类适用于与屏幕宽度大于或等于分界点大小的设备 3. 如果真实设备宽度小于了设置的栅格类属性的设备代码的最小值,元素会占满一整行

CSS样式和JS插件

1. 全局CSS样式:* 按钮:class="btn btn-default"* 图片* class="img-responsive": 图片任意尺寸占100%* 形状:class="img-rounded" ...见文档* 表格* class="table"* class="table-hover"* 表单* 给表单项添加:class="form-control"
2. 组件:* 导航条* 分页条
3. 插件:* 轮播图

Day 11 内容:

1. XML1. 概念2. 语法3. 解析

XML

1. 概念:Extensible Markup Language 可扩展标记语言* 可扩展:标签都是自定义的。    <user> <student>* 功能:* 存储数据1. 配置文件2. 在网络中传输* xml和html的区别:1. xml标签都是自定义的,html的标签是预定义。2. xml的语法严格,html语法松散。3. xml是存储数据,html是展示数据的。* w3c:万维网联盟2. 语法* 基本语法:1. xml后缀名 .xml2. xml第一行必须定义为文档声明3. xml文档中有且仅有一个根标签4. 属性值必须使用引号引起来(单双都可)5. 标签必须正确关闭6. xml标签名称区分大小写* 快速入门<?xml versionm='1.0' ?><users><user id='1'><name>zhangsan</name></user><user id='2'><name>lisi</name></user></users>* 组成部分:1. 文档声明1. 格式:<?xml 属性列表 ?>2. 属性列表* version:版本号,必须的属性* encoding:编码方式,告知解析引擎当前文档使用的字符集,默认值:ISO-8859-1* standalone:是否独立* 取值:* yes:不依赖其他文件* no:依赖其他文件2. 指令(了解):结合css* <?xml-stylesheet type="text/css" href="a.css" ?>3. 标签:标签名称是自定义的* 规则:* 名称可以包含字母、数字以及其他的字符* 名称不能以数字或者标点符号开始* 名称不能以字母xml或者(XML、Xml等等)开始* 名称不能包含空格4. 属性:id属性值唯一5. 文本* CDATA区:在该区域中的数据会被原样展示* 格式:<![CDATA[数据]]>* 约束:规定xml文档的书写规则* 作为框架的使用者(程序员):1. 能够在xml中引入约束文档2. 能够简单读懂约束文档* 分类:1. DTD:一种简单的约束技术2. Schema:一种复杂的约束技术* DTD:* 引入dtd文档到xml文档中* 内部dtd,将约束规则定义在xml文档中* 外部dtd,将约束规则定义在外部dtd文件中* 本地:<!DOCTYPE 根标签名 SYSTEM "dyd文件的位置">* 网络:<!DOCTYPE 根标签名 PUBLIC "dtd文件的名字" "dyd文件的位置url">* Schema:* 引入:1. 填写xml文档的根元素2. 引入xsi前缀 xmlns:xsi="..."3. 引入xsd文件命名空间 xsi:schemaLocation="... ..."(键值对的形式 前面代表名称 后面代表路径)4. 为每一个xsd约束声明一个前缀作为标识 xmlns:(自定义前缀)="..."3. 解析:操作xml文档,将文档中的数据读取到内存中* 操作xml文档1. 解析(读取):将文档中的数据读取到内存中2. 写入:将内存中的数据保存到xml文档中,持久化的存储* 解析xml的方式:1. DOM:将标记语言文档一次性加载进内存,在内存中形成DOM树* 优点:操作方便,可以对文档进行CRUD的所有操作* 缺点:占内存2. SAX:逐行读取,基于事件驱动的。* 优点:不占内存。* 缺点:只能读取,不能增删改* xml常见的解析器:1. JAXP:sun公司提供的解析器,支持dom和sax两种思想2. DOM4J:一款非常优秀的解析器3. Jsoup:jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。4. PULL:Android操作系统内置的解析器,sax方式的。* Jsoup:jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。* 快速入门:* 步骤:1. 导入jar包2. 获取Document对象3. 获取对应的标签Element对象4. 获取数据* 代码// 2.获取Document对象 根据xml文档获取// 2.1获取studetns.xml路径String res = JsoupDemo1.class.getClassLoader().getResource("student.xml").getPath();String path = java.net.URLDecoder.decode(res, "utf-8");// 2.2解析xml文档 加载文档进内存 获取dom树Document document = Jsoup.parse(new File(path), "utf-8");// 3.获取元素对象 ElementElements ele = document.getElementsByTag("name");System.out.println(ele.size());// 3.1获取第一个name的element对象System.out.println(ele.get(0).text());* 对象的使用:1. Jsoup:工具类,可以解析html或xml文档,返回Document* parse:解析html或xml文档,返回Document* parse(File in, String charsetName):解析html或xml文件的* parse(String html):解析xml或xml字符串* parse(URL url, int timeoutMillis):通过网络路径获取指定的html或xml的文档对象2. Document:文档对象,代表内存中的dom树* 获取Element对象* getElementsByTag(String tagName):根据标签名称获取元素对象集合* getElementByAttribute(String key):根据书写名称获取元素对象集合* getElementByArributeValue(String key, String value):根据对应的属性名和属性值获取元素对象集合* getElementById(String id):根据id属性值获取唯一的Element对象3. Elements:元素Element对象的集合。可以当作ArrayList<Element>来使用4. Element:元素对象1. 获取子元素对象* getElementsByTag(String tagName):根据标签名称获取元素对象集合* getElementByAttribute(String key):根据书写名称获取元素对象集合* getElementByArributeValue(String key, String value):根据对应的属性名和属性值获取元素对象集合* getElementById(String id):根据id属性值获取唯一的Element对象2. 获取属性值* String attr(String key):根据属性名称获取属性值3. 获取文本内容* String text():获取所有子标签的纯文本内容* String html():获取标签体的所有内容,包括子标签的标签和文本内容5. Node:节点对象* 是Document和Element的父类* 快捷查询方式:1. selector:选择器* 使用的方法:Elements select(String cssQuery)* 语法:参考Selector类中定义的语法2. Xpath:XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。* 使用Jsoup的Xpath需要额外导入jar包* 查询w3cschool的参考手册,使用xpath语法完成查询

Day 12 内容:

1. web相关概念回顾
2. web服务器软件:Tomcat
3. Servlet入门学习

web相关概念回顾

1. 软件架构1. C/S:客户端/服务器端2. B/S:浏览器/服务器端2. 资源分类1. 静态资源2. 动态资源3. 网络通信三要素1. IP2. 端口3. 传输协议

web服务器软件

* 服务器:安装了服务器软件的计算机
* 服务器软件:接收用户的请求,处理请求,做出响应
* web服务器软件:接收用户的请求,处理请求,做出响应* 在web服务器软件中,可以部署web项目,让用户通过浏览器来访问这些项目* web容器* 常见的java相关的web服务器软件:* webLogic:oracle公司,大型的JavaEE服务器,支持所有的JavaEE规范,收费的。* webSphere:IBM公司,大型的JavaEE服务器,支持所有的JavaEE规范,收费的。* JBOSS:JBOSS公司,大型的JavaEE服务器,支持所有的JavaEE规范,收费的。* Tomcat:Apache基金组织,中小型JavaEE服务器,仅支持少量的JavaEE规范servlet/jsp。开源的免费的。* JavaEE:Java语言在企业级开发中使用的技术规范的综合,一共规范了13项大的规范* Tomcat:web服务器软件1. 下载:官网下载2. 安装:解压压缩包即可* 注意:安装目录建议不要有中文空格3. 卸载:删除该目录4. 启动* bin/startup.bat,双击运行该文件即可* 访问:http://localhost:8080 访问自己 http://其他ip:8080 访问别人* 可能遇到的问题1. 黑窗口一闪而过* 原因:没有正确配置JAVA_HOME环境变量* 解决方案:正确配置JAVA_HOME环境变量2. 启动报错:1. 暴力:找到占用端口的进程并杀死* netstat -ano2. 温柔:修改自身的端口号* config/server.xml* 一般会将tomcat的默认端口号修改为80,为http协议的默认端口号* 好处:访问时不用输入端口号5. 关闭1. 正常关闭* bin/shutdown.bat* ctrl+c2. 强制关闭* 点击启动窗口的X按钮6. 配置:* 部署项目的方式:1. 直接将项目放到webapps目录下即可。* /hello:项目的访问路径-->虚拟目录* 简化部署:将项目打成war包,再将war包放置到webapps目录下。* war包会自动解压缩2. 配置conf/server.xml文件在<Host>标签体中配置<Context docBase="文件路径" path="虚拟目录"/>3. 在conf/Catalina/localhost创建任意名称的xml文件,在文件中编写<Context docBase="文件路径" /> 虚拟目录即文件名称* 静态项目和动态项目:* 目录结构* java动态项目的目录结构:-- 项目的根目录-- WEB-INF目录:-- web.xml:web项目的核心配置文件-- class目录:防止字节码文件的目录-- lib目录:放置依赖的jar包* 将Tomcat集成到IDEA中,并且创建JavaEE的项目,部署项目

Servlet: server applet

* 概念:运行在服务器端的小程序* Servlet就是一个接口,定义了Java类被浏览器访问到(tomcat识别)的规则* 将来我们自定义一个类,实现Servlet接口,复写方法* 快速入门:1. 创建JavaEE的项目2. 定义一个类,实现Servlet接口3. 实现接口中的抽象方法4. 配置Servlet在web.xml中配置<servlet><servlet-name>demo1</servlet-name><servlet-class>web.servlet.day11.ServletDemo1</servlet-class></servlet><servlet-mapping><servlet-name>demo1</servlet-name><url-pattern>/demo1</url-pattern></servlet-mapping>* 执行原理1. 当服务器接收到客户端浏览器的请求后,会解析请求URL路径,获取访问的Servlet的资源路径2. 查找web.xml文件,是否有对应的<url-pattern>标签体内容3. 如果有,则找到对应的<servlet-class>全类名4. tomcat会将字节码文件加载进内容,并且创建其对象5. 调用其方法
* Servlet的生命周期1. 被创建:执行init方法,只执行一次* Servlet什么时候被创建?* 默认情况下,第一次被访问时,Servlet被创建* 可以配置指定Servlet的创建时机* 在<servlet>标签下配置1. 第一次被访问时创建* <load-on-startup> 值为负数2. 在服务器启动时创建* <load-on-startup> 值为0或正整数* Servlet的init方法,只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的* 多个用户同时访问时,可能存在线程安全问题* 解决:尽量不要在Servlet中定义成员变量。即使定义了成员变量,也不要对其修改值2. 提供服务:执行service方法,执行多次* 每次访问Servlet时,Service方法都会被调用一次3. 被销毁:执行destroy方法,只执行一次* Servlet被销毁时执行。服务器关闭时,Servlet被销毁。* 只有服务器正常关闭时,才会执行destroy方法。* destroy方法在Servlet被销毁之前之前,一般用于释放资源。* Servlet3.0:* 好处:* 支持注解配置。可以不需要web.xml了。* 步骤:1. 创建JavaEE项目,选择Servlet的版本3.0以上,可以不创建web.xml2. 定义一个类,实现Servlet接口3. 复写方法4. 在类上使用@WebServlet注解,进行配置* @WebServlet("资源路径")### IDEA与tomcat相关配置1. IDEA会为每一个tomcat部署的项目建立一份配置文件* 查看控制台的log:C:\Users\xxx\AppData\Local\JetBrains\IntelliJIdea2020.1\tomcat\_idea_JavaWeb2. 工作空间项目    和     tomcat部署的web项目* tomcat真正访问的是"tomcat部署的web项目","tomcat部署的web项目"对应着"工作空间项目"中web目录的资源* WEB-INF目录下的资源无法被浏览器直接访问3. 断点调试:使用"小虫子"启动debug启动

Day 13 内容:

1. Servlet
2. HTTP协议
3. Request

Servlet:

1. 概念
2. 步骤
3. 执行原理
4. 生命周期
5. Servlet3.0注解配置
6. Servlet的体系结构Servlet -- 接口|GenericServlet -- 抽象类|HttpServlet -- 抽象类* GenericServlet:将Servlet接口中其他的方法做了默认空实现,只将service()方法作为抽象* 将来定义Servlet类时,可以继承GenericServlet,实现service()方法即可* HttpServlet:对HTTP协议的一种封装,简化操作1. 定义类继承HttpServlet2. 复写doGet/doPost()方法7. Servlet相关配置1. urlpartten:Servlet访问路径* 一个Servlet可以定义多个访问路径 @WebServlet({"/x","/xx"})* 路径定义规则1. /xxx2. /xxx/xxx 多层路径3. *.do 必须在后面加.do才能访问

HTTP:

* 概念:Hyper Text Transfer Protocol 超文本传输协议* 传输协议:定义了,客户端和服务器端通信时,发送数据的格式* 特点:1. 基于TCP/IP的高级协议2. 默认端口号:803. 基于请求/响应模型的:一次请求对应一次响应4. 无状态的:每次请求之间相互独立,不能交互数据* 历史版本:* 1.0:每次请求响应都会建立新的连接* 1.1:复用连接* 请求消息数据格式1. 请求行请求方式 请求url 请求协议/版本GET /login.html HTTP/1.1* 请求方式:* HTTP协议有7种请求方式,常用的有两种* GET1. 请求参数在请求行中,在url后。2. 请求的url长度有限制的3. 不太安全* POST1. 请求参数在请求体中2. 请求的url长度是没有限制的3. 相对安全2. 请求头:客户端浏览器告诉服务器一些信息请求头名称: 请求头值* 常见的请求头1. User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息* 可以在服务器端获取该头的信息,解决浏览器的兼容性问题2. Refer:* 告诉服务器,我(当前请求)从哪里来?* 作用:1. 防盗链2. 统计工作3. 请求空行空行,就是用于分割POST请求的请求头和请求体的4. 请求体(正文)* 封装POST请求消息的请求参数的* 字符串格式GET /login.html HTTP/1.1Host: localhost...: ...username=zhangsan* 响应消息数据格式

Request:

1. request对象和response对象的原理1. request和response两个对象是由服务器创建的,我们来使用它们2. request对象是来获取请求消息,response对象是来设置响应消息2. request对象继承体系结构ServletRequest   -- 接口| 继承HttpServletRequest -- 接口| 实现org.apache.catalina.connector.RequestFacade 类(tomcat)3. request功能:获取请求消息1. 获取请求消息数据1. 获取请求行数据* GET /day14/demo1?name=zhangsan HTTP/1.1* 方法:1. 获取请求方式:GET* String getMethod()2. (*)获取虚拟目录: /day14* String getContextPath()3. 获取Servlet路径:/demo1* String getServletPath()4. 获取get方式请求参数:name=zhangsan* String getQueryString()5. (*)获取请求URI:/day14/demo1* String getRequestURI() :/day14/demo1* StringBuffer getRequestURL() :http://localhost/day14/demo1* URL:统一资源定位符* URI:统一资源标识符6. 获取协议及版本:HTTP/1.1* String getProtocol()7. 获取客户机ip地址* String getRemoteAddr()2. 获取请求头数据* 方法:* (*)String getHeader(String name):通过请求头名称获取请求头的值* Enumeration<String> getHeaderName():获取所有的请求头名称3. 获取请求体数据* 请求体:只有POST请求方式,菜有请求体,在请求体中封装了POST请求的请求参数* 步骤:1. 获取流对象* BufferReader getReader() :获取字符输入流,只能操作字符数据* ServletInputStream getInputStream() :获取字节输入流,可以操作所有数据* 在文件上传知识点后讲解2. 再从流对象中拿数据2. 其他功能:1. 获取请求参数通用方式:不论get还是post请求方式都可以使用下列方法获取请求参数1. String getParameter(String name): 根据参数名称获取参数值2. String[] getParameterValues(String name): 根据参数名称获取参数值的数组3. Enumeration<String> getParameterValueNames(): 获取所有的参数名称4. Map<String, String[]> getParameterMap(): 获取所有参数的键值对集合* 中文乱码问题:* get方式:tomcat 8 已经将get方式乱码问题解决了* post方式:会乱码* 解决:在设置参数前,设置request的编码request.setCharacterEncoding("utf-8");2. 请求转发:一种在服务器内部的资源跳转方式1. 步骤:1. 通过request对象来获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)2. 使用RequestDispatcher对象进行转发:forward(ServletRequest request, ServletResponse response)2. 特点:1. 浏览器地址栏路径不发生变化2. 只能转发到当前的服务器内部资源中3. 转发是一次请求3. 共享数据:* 域对象:一个有作用范围的对象,可以在范围内共享数据* request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据* 方法:1. void setAttribute(String name, Object obj): 存储数据2. Object getAttribute(String name): 通过键获取值3. void removeAttribute(): 通过键移除键值对4. 获取ServletContext:* ServletContext getServletContext()

案例:用户登录

* 用户登录案例需求1. 编写login.html登录界面username & password 两个输入框2. 使用Druid数据库连接池技术,操作mysql,day14数据库中user表3. 使用JdbcTemplate技术封装JDBC4. 登录成功跳转到SuccessServlet展示:登录成功!用户名,欢迎您5. 登录失败跳转到FailServlet展示:登录失败!用户名或密码错误* 分析* 开发1. 创建项目,导入jar包,配置文件,创建html页面2. 创建数据库环境3. 创建包domain,创建类User4. 创建包dao,创建类UserDao,提供login方法5. 创建包util,创建类JDBCUtils,使用Druid连接池6. 创建包web.servlet,创建类LoginServlet,完成登录具体逻辑7. login.html中form表单的action路径写法* 虚拟目录+Servlet的路径8. BeanUtils工具类,简化数据封装* 用于封装JavaBean1. JavaBean:标准的Java类1. 要求:1. 类必须被public修饰2. 必须提供空参的构造器3. 成员变量必须使用private修饰4. 提供公共的getter/setter方法2. 功能:封装数据2. 概念:成员变量:属性:setter/getter方法截取后的产物例如:getUsername() --> Username --> username3. 方法:1. setProperty()2. getProperty()3. populate(Object obj, Map map):将map集合的键值对信息,封装到对应的JavaBean对象中

Day 14 内容:

1. HTTP协议:响应消息
2. Response对象
3. ServletContext对象

HTTP协议:

1. 请求消息:客户端发送给服务器端的数据* 数据格式:1. 请求行2. 请求头3. 请求空行4. 请求体
2. 响应消息:服务器端发送给客户端的数据* 数据格式1. 响应行1. 组成:协议/版本 响应状态码 状态码描述2. 响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态1. 状态码都是3位数字2. 分类:1. 1xx:服务器接收客户端消息,但没有接收完成,等待一段时间后,发送1xx状态码2. 2xx:成功。代表:2003. 3xx:重定向。代表:302(重定向),304(访问缓存)4. 4xx:客户端错误。* 代表:* 404(路径没有对应的资源),* 405(请求方式没有对应的doXxx方法)5. 5xx:服务器端错误。代表:500(服务器内部出现异常)2. 响应头1. 格式:头名称: 值2. 常见的响应头:1. Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式2. Content-disposition:服务器告诉客户端以什么格式打开响应体数据* 值:* in-line:默认值在当前页面内打开* attachment;filename=xxx:以附件形式打开响应体。文件下载3. 响应空行4. 响应体:传输的数据* 响应字符串格式xxx

Response对象

* 功能:设置响应消息1. 设置响应行1. 格式:HTTP/1.1 200 ok2. 设置状态码:setStatus(int sc)2. 设置响应头:setHeader(String name, String value)3. 设置响应体:* 使用步骤:1. 获取输出流* 字符输出流:PrintWriter getWriter()* 字节输出流:ServletOutputStream getOutputStream()2. 使用输出流,将数据输出到客户端浏览器中* 案例1. 完成重定向* 重定向:资源跳转的方式* 代码实现:response.sendRedirect("重定向的地址");* 重定向的特点1. 地址栏发生变化2. 重定向可以访问其他站点(服务器)的资源3. 重定向是两次请求,不能使用request对象来共享数据* 转发的特点:1. 转发地址栏路径不变2. 转发只能访问当前服务器下的资源3. 转发是一次请求,可以使用requset对象来共享数据* forward 和 redirect 区别* 路径写法1. 路径分类1. 相对路径:通过相对路径不能确定唯一资源* 如 ./index.html* 不以/开头,以.开头* 规则:找到当前资源和目标资源之间的相对位置关系* ./:当前目录* ../:后退一级目录2. 绝对路径:通过绝对路径可以确定唯一资源* 如 http://localhost/...* 以/开头的路径* 规则:判断定义的路径是给谁用的?判断请求将来从哪发出* 给客户端浏览器使用:需要加虚拟目录(项目的访问路径)* 建议虚拟目录动态获取:request.getContextPath()* <a>,重定向* 给服务器使用:不需要加虚拟目录* 转发路径2. 服务器输出字符数据到浏览器* 步骤:1. 获取字符输出流2. 输出数据* 注意* 乱码问题1. 获取的流的默认编码为ISO-8859-12. 设置该流的默认编码3. 告诉浏览器响应体使用的编码// 在获取流之前设置response.setContentType("text/html;charset=utf-8");3. 服务器输出字节数据到浏览器* 步骤:1. 获取字节输出流2. 输出数据4. 验证码1. 本质:图片2. 目的:防止恶意表单注册

ServletContext对象

1. 概念:代表整个web应用,可以和程序的容器(服务器)通信
2. 获取:1. 通过request的对象获取request.getServletContext();2. 通过HttpServlet获取this.getServletContext();
3. 功能:1. 获取MIME类型:* MINE类型:在互联网通信过程中定义的一种文件数据类型* 格式:大类型/小类型 image/jpeg* 获取:String * getMimeType(String file)2. 域对象:共享数据1. setAttribute()2. getAttribute()3. removeAttribute()* ServletContext对象范围:所有用户所有请求的数据3. 获取文件的真实(服务器)路径 1. 方法:String getRealPath(String path)* web目录 -- /xxx.xxx* WEB-INF目录 -- /WEB-INF/xxx.xxx* src目录 -- /WEB-INF/classes/xxx.xxx

案例

* 文件下载雪球1. 页面显示超链接2. 点击超链接弹出下载提示框3. 完成图片文件下载* 分析:1. 超链接指向的资源如果能够被浏览器解析,则在浏览器中展示,如果不能解析,则弹出下载2. 任何资源都必须弹出下载提示框3. 使用响应头设置资源的打开方式:* content-disposition:attachment;filename=xxx* 步骤1. 定义页面,编写href属性,指向Servlet,传递资源名称filename2. 定义Servlet1. 获取文件名称2. 使用字节输入流加载文件进内存3. 指定response的响应头 content-disposition:attachment;filename=xxx4. 将数据写出到response输出流* 问题:* 中文文件名* 解决思路:1. 获取客户端使用的浏览器版本信息2. 根据不同的版本信息,设置filename编码方式不同

Day 15 内容:

1. 会话技术1. Cookie2. Session
2. JSP:入门学习

会话技术

1. 会话:一次会话中包含多次请求和响应。* 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止
2. 功能:在一次会话的范围内的多次请求间,共享数据
3. 方式:1. 客户端会话技术:Cookie2. 服务器端会话技术:Session

Cookie

1. 概念:客户端会话技术,将数据保存在客户端
2. 快速入门:* 使用步骤1. 创建Cookie对象,绑定数据* new Cookie(String name, String name)2. 发送Cookie对象* response.addCookie(Cookie cookie)3. 获取Cookie,拿到数据* Cookie[] request.getCookies()3. 实现原理* 基于响应头set-cookie和请求头cookie实现
4. cookie的细节1. 一次可不可以发送多个cookie* 可以* 可以创建多个cookie对象,使用response调用多次addCookie方法发送cookie即可2. cookie在浏览器中保存多长时间1. 默认情况,当浏览器关闭后,Cookie数据被销毁2. 持久化存储:* setMaxAge(int second)1. 正数:将Cookie数据写到硬盘的文件中。持久化存储。cookie存活时间2. 负数:默认值3. 零:删除cookie信息3. cookie能不能存中文* 在tomcat8之前,cookie中不能直接存储中文数据。* 需要将中文数据转码 -- 一般采用url编码* 在tomcat8之后,cookie中支持存储中文数据。但还是不支持特殊字符,建议使用url编码。4. cookie共享问题1. 假设在一个tomcat服务器中部署了多个web项目,那么在这些项目中,cookie能不能共享* 默认情况cookie不能共享* setPath(String path) : 设置cookie的共享范围,默认情况下设置当前的虚拟目录* 如果要共享,则可以将path设置为"/"2. 不同的tomcat服务器cookie共享问题* setDomain(String path):如果设置一级域名相同,那么多个服务器之间cookie可以共享* setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com中cookie可以共享5. cookie的特点和作用1. cookie存储数据在客户端浏览器2. 浏览器对于单个cookie的大小有限制(4kb),以及对同一个域名下的总cookie的数量也有限制(20)* 作用:1. cookie一般用于存储少量的不太敏感的数据2. 在不登录的情况下,完成服务器对客户端的身份识别6. 案例:记住上一次访问时间1. 需求:1. 访问一个Servlet,如果是第一次访问,则提示:您好,欢迎你首次访问。2. 如果不是第一次访问,则提示:欢迎回来,您上次访问时间为:显示时间字符串。2. 分析:1. 可以采用cookie来完成2. 在服务器中的Servlet判断是否有一个名为lastTime的cookie1. 有,不是第一次访问1. 响应数据:欢迎回来,您上次访问时间为...2. 写回cookie:lastTime=...2. 没有,是第一次访问1. 响应数据:您好,欢迎您首次访问2. 写回cookie:lastTime=...3. 代码/*** cookie实现访问时间显示*/@WebServlet("/CookieServlet")public class CookieServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");Cookie[] cookies = request.getCookies();boolean flag = false;for (Cookie cookie : cookies) {if("lastTime".equals(cookie.getName())){flag = true;String decode = cookie.getValue();String time = URLDecoder.decode(decode, "utf-8");response.getWriter().write("您好,您上次访问时间为" + time);Date date = new Date();SimpleDateFormat s = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");time = s.format(date);String encode = URLEncoder.encode(time, "utf-8");System.out.println(time);System.out.println(encode);cookie.setValue(encode);response.addCookie(cookie);break;}}if(cookies.length == 0 || cookies == null || !flag){Date date = new Date();SimpleDateFormat s = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");String time = s.format(date);String encode = URLEncoder.encode(time, "utf-8");System.out.println(time);Cookie c = new Cookie("lastTime", encode);response.addCookie(c);response.getWriter().write("您好,欢迎您首次访问!");}}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}}

JSP:入门学习

1. 概念:* Java Server Pages:java服务器端页面* 可以理解为:一个特殊的页面,其中既可以指定定义html标签,又可以定义java代码* 用于简化书写!!!2. 原理:* JSP本质上就是一个Servlet3. JSP的脚本:JSP定义Java代码的方式1. <% 代码 %>:定义的Java代码,在service方法中。service可以定义什么,该脚本中就可以定义什么。2. <%! 代码 %>:定义的Java代码,在jsp转换后的java类的成员位置。3. <%= 代码 %>:定义的Java代码,会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么。
4. JSP的内置对象* 在jsp页面中不需要获取和创建就可以使用的对象* jsp一共有9个内置对象* 今天学习3个:* request* response* out:字符输出流对象。可以将数据输出到页面上。和response.getWriter().write()类似* response.getWriter().write()和out.write()的区别:* 在tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据。* response.getWriter().write()数据输出永远在out.write()之前

Session

1. 概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。HttpSession
2. 快速入门:1. 获取HttpSession对象* request.getSession()2. 使用HttpSession对象getAttribute()setAttribute()removeAttribute()
3. 原理* Session的实现是依赖于Cookie的。JSESSIONID
4. 细节1. 当客户端关闭后,服务器不关闭,两次获取的session是否是同一个* 默认情况下不是。* 如果需要相同,则可以创建cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存。2. 客户端不关闭,服务器关闭后,两次获取的session是同一个吗* 不是同一个,但是要确保数据不丢失* session的钝化:* 服务器正常关闭之前,将session对象序列化到硬盘上* session的活化:* 在服务器正常启动后,将session文件转化为内存中的session对象即可。3. session什么时候被销毁1. 服务器关闭2. session对象调用invalidate()3. session默认失效时间 30分钟选择性配置修改web.xml -- <session-config>5. session的特点1. session用于存储一次会话的多次请求的数据,存在服务器端2. session可以存储任意类型,任意大小的数据* session和cookie的区别1. session存储数据在服务器端,而cookie在客户端2. session没有数据大小限制,cookie有3. session数据安全,cookie相对于不安全

案例:验证码

1. 案例需求1. 访问带有验证码的登陆页面index.jsp2. 用户输入用户名,密码以及验证码。* 如果用户名和密码输入有误,跳转登录页面,提示:用户名或密码错误* 如果验证码输入有误,则跳转登录页面,提示:验证码错误* 如果全部输入正确,则跳转到success.jsp,显示:用户名,欢迎您2. 分析

Day 16 内容:

1. JSP:1. 指令2. 注释3. 内置对象2. MVC开发模式
3. EL表达式
4. JSTL标签
5. 三层架构

JSP:

1. 指令* 作用:用于配置JSP页面,导入资源文件* 格式:<%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ... %>* 分类1. page      :配置JSP页面的* contentType:等同于response.setContentType()1. 设置响应体的mime类型以及字符集2. 设置当前jsp页面的编码(只能是高级的IDE才能生效,如果使用低级工具,则需要配置pageEncoding设置当前页面的字符集)* import:导包* erroePage:当前页面发生异常后,会自动跳转到指定的错误页面* isErrorPage:标识当前页面是否是错误页面。* true:是,可以使用内置对象exception。* false:否。默认值,不能使用exception对象。2. include  :页面包含的。导入页面的资源文件* <%@inlcude file="top.jsp" %>3. taglib :导入资源* <%@ tablib prefix="c" uri="..." %>* prefix:前缀
2. 注释1. html注释:<!-- -->:只能注释html代码片段2. jsp注释:推荐使用<%-- --%>:可以注释所有
3. 内置对象* 在jsp页面中不需要创建,直接使用的对象* 一共有9个:变量名                  真实类型                    作用* pageContext         PageContext                 当前页面共享数据,可以获取其他8个对象* request             HttpRequest                 一次请求访问的多个资源(转发)* session                HttpSession                 一次会话的多个请求间* application         ServletContext              所有用户间共享数据* response             HttpResponse                响应对象* page                  Object                      当前页面(Servlet)的对象* out                   JspWriter                   输出对象,数据输出到页面上* config                ServletConfig               异常对象    Servlet的配置对象* exception             Throwable

MVC:开发模式

1. jsp演变历史1. 早期只有Servlet,只能使用response输出标签数据,非常麻烦2. 后来有了jsp,简化了Servlet的开发,如果过度使用jsp,在jsp中既写大量java代码,又写html,造成难以维护,难以分工协作。3. 再后来,java的web开发借鉴mvc开发模式,使得程序的设计更加合理2. MVC:1. M:model,模型。JavaBean* 完成具体的业务操作,如:查询数据库,封装对象2. V:view,视图。JSP* 展示数据3. C:Controller,控制器。Servlet* 获取用户的输入* 调用模型* 将数据交给视图进行展示* 优缺点1. 优点:1. 耦合性低,方便维护,可以利于分工协作2. 重用性高2. 缺点:1. 使得项目架构变得复杂,对开发人员要求高

EL表达式

1. 概念:Expression Language 表达式语言
2. 作用:替换和简化jsp页面中java代码的编写
3. 语法:${表达式}
4. 注意:* jsp默认是支持EL表达式的。如果要忽略EL表达式1. 设置jsp中page指令中:isELIgnored=“true” 忽略所有的el表达式2. \${表达式}:忽略当前这个el表达式
5. 使用1. 运算* 运算符:1. 算数运算符: + - * /(div) %(mod)2. 比较运算符: > < >= <= == !=3. 逻辑运算符:&&(and) ||(or) !(not)4. 空运算符:empty* 功能:用于判断字符串、集合、数组对象是否为null或者长度是否为0* ${empty list}:判断字符串、集合、数组对象是否为null或者长度是否为0* ${not empty list}:判断字符串、集合、数组对象是否不为null,且长度大于02. 获取值1. el表达式只能从域对象中获取值2. 语法:1. ${域名称.键名}:从指定域中获取指定键的值* 域名称:1. pageScope     -->  pageContext2. requestScope      -->  request3. sessionScope      -->  session4. applicationScope  -->  application (ServletContext)* 举例:在requset域中存储了name=张三* 获取:${requestScope.name}2. ${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止。3. 获取对象、list集合、Map集合的值1. 对象:${域名称.键名.属性名}* 本质上会去调用对象的getter方法2. List集合:${域名称.键名[索引]}3. Map集合:* ${域名称.键名.key名称}* ${域名称.键名["key名称"]}3. 隐式对象:* el表达式中有11个隐式对象* pageContext:* 获取jsp其他8个内置对象* ${pageContext.request.contextPath}:动态获取虚拟目录

JSTL

1. 概念:JavaServer Pages Tag Library JSP标准标签库* 是由Apache组织提供的开源的免费的jsp标签2. 作用:用于简化和替换jsp页面上的java代码3. 使用步骤:1. 导入JSTL相关jar包2. 引入标签库:taglib指令  <%@ taglib %>3. 使用标签4. 常用的JSTL标签1. if            相当于Java代码的if语句1. 属性:* test 必须属性,接收boolean表达式* 如果表达式为true,则显示if标签体内内容* 如果为false则不展示* 一般情况下,test属性会结合el表达式一起使用2. 注意:c:if标签没有else情况,若需要,可以再定义一个c:if标签2. choose        相当于Java代码的switch语句1. 使用choose标签声明                       相当于switch声明2. 使用when标签做判断                       相当于case3. 使用otherwise标签做其他情况的声明     相当于default3. foreach        相当于Java代码的for语句1. for(int i=0; i<5; i++)* 属性:* begin、end、step、var* varStatus* index:索引* count:循环次数2. for(User user : list)* 属性:* items --> list* var --> user* varStatus* 同上5. 练习:* 需求:再request域中有一个存User对象的List集合。需要使用jstl和el将list集合数据展示到jsp页面的表格table中。

三层架构:软件设计架构

1. 界面层(表示层):用户看到的界面。用户可以通过界面上的组件和服务器进行交互
2. 业务逻辑层:处理业务逻辑的。
3. 数据访问层:操作数据存储文件的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ToA7r8pu-1601224866545)(https://i.loli.net/2020/07/26/OnQ9LogXNdtaIjB.png)]

案例:用户信息列表展示

1. 需求:用户信息的增删改查操作
2. 设计:1. 技术选型:Servlet + JSP + Mysql + JDBCTemplate + Druid + BeanUtils + Tomcat2. 数据库设计:create database day17;   -- 创建数据库use day17;  -- 使用数据库create table user(  -- 创建表id int primary key auto_increment,name varchar(32) not null,gender varchar(5),age int,address varchar(32),qq varchar(20),email varchar(50),);3. 开发:1. 环境搭建1. 创建数据库环境2. 创建项目,导入需要的jar包2. 编码4. 测试
5. 部署运维

Day 17 内容:

1. 综合练习1. 简单功能1. 列表查询2. 登录3. 添加4. 删除5. 修改2. 复杂功能1. 删除选中2. 分页查询* 好处:1. 减轻服务器内存的开销2. 提升用户体验3. 复杂条件查询

2. 登录

1. 调整页面,加入验证码功能
2. 代码实现

Day 18 内容:

1. Filter:过滤器
2. Listener:监听器

Filter:过滤器

1. 概念:* 生活中的过滤器:净水器、空气净化器、土匪* web中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊功能。* 过滤器的作用:* 一般用于完成通用的操作。如:登录验证、统一编码处理、敏感字符过滤...
2. 快速入门:1. 步骤:1. 定义一个类,实现接口Filter2. 复写方法3. 配置拦截路径1. web.xml2. 注解
3. 过滤器细节:1. web.xml配置* 和Servlet配置相似2. 过滤器执行流程1. 执行过滤器2. 执行放行后的资源3. 执行过滤器放行代码下方的代码3. 过滤器生命周期方法1. init:在服务器启动后,创建filter对象,调用该方法,只调用一次2. doFilter:每一次请求被拦截都会执行,执行很多次3. 在服务器关闭后,Filter对象被销毁,正常关闭的前提下,会执行一次4. 过滤器配置详解* 拦截路径配置:1. 具体资源路径:/index.jsp2. 目录拦截:/user/* 访问/user下的所有资源时,过滤器都会被执行3. 后缀名拦截:*.jsp 访问所有后缀名为jsp资源时,过滤器都会被执行4. 拦截所有资源:/** 拦截方式配置:资源被访问的方式* 注解配置:* 设置dispatcherTypes属性1. REQUEST:默认值。浏览器直接请求资源2. FORWARD:转发访问资源3. INCLUDE:包含访问资源4. ERROR:错误跳转资源5. ASYNC:异步访问资源* web.xml配置* 设置dispatcher标签即可5. 过滤器链(配置多个过滤器)* 执行顺序:如果有两个过滤器——过滤器1和过滤器21. 过滤器12. 过滤器23. 资源4. 过滤器25. 过滤器1* 过滤器先后顺序:1. 注解配置:按照类名的字符串比较规则比较,值小的先执行如:AFilter 和 BFilter,AFilter先执行2. web.xml配置:谁定义在上谁先执行4. 案例1. 案例1_登录验证* 需求1. 访问day17_case案例的资源,验证其是否登录2. 如果登录,则放行3. 否则,跳转到登录界面,提示“您尚未登录,请先登录”2. 案例2_过滤敏感词汇* 需求:1. 对day17_case案例录入的数据进行敏感词汇过滤2. 敏感词汇参考《敏感词汇.txt》3. 如果时敏感词汇,替换为 **** 分析:1. 对request对象进行增强。增强获取参数相关方法即可2. 放行。传递代理对象* 增强对象的功能:* 设计模式:一些通用的解决固定问题的方式1. 装饰模式2. 代理模式* 概念:1. 真实对象:被代理的对象2. 代理对象3. 代理模式:代理对象代理真实对象,达到增强真实对象功能的目的* 实现方式:1. 静态代理:有一个类文件描述代理模式2. 动态代理:在内存中形成代理类* 实现步骤:1. 代理对象和真实对象实现相同的接口2. 代理对象 = Proxy.newProxyInstance();3. 使用代理对象调用方法4. 增强方法* 增强方式:1. 增强参数列表2. 增强返回值类型3. 增强方法体执行逻辑

Listener:监听器:

* 概念:web的三大组件之一。* 事件监听机制* 事件:一件事* 事件源:事件发生的地方* 监听器:一个对象* 注册监听:将事件、事件源、监听器绑定在一起。当事件源上发生一个事件后,执行监听器代码* ServletContextListener:监听ServletContext对象的创建和销毁* 方法* void contextDestroyed(ServletContextEvent sce) :对象被销毁前调用* void contextInitialized(ServletContextEvent sce) :对象被创建后调用* 步骤:1. 定义一个类,实现ServletContextListener接口2. 复写方法3. 配置1. web.xml:<listener>标签* 指定初始化参数   <context-param>标签2. 注解:@WebListener

Day 19 内容:

1. JQuery 基础:1. 基本概念:一个JavaScript框架。简化JS开发* jQuery是一个快速、简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架)。jQuery设计的宗旨是“write Less,Do More”,即倡导写更少的代码,做更多的事情。它封装JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,优化HTML文档操作、事件处理、动画设计和Ajax交互。* JavaScript框架:本质上就是一些js文件,封装了js的原生代码而已。2. 快速入门1. 步骤:1. 下载JQuery* 目前三大版本:* 1.xx——使用广泛,功能不再新增* 2.xx——很少人使用* 3.xx——支持最新浏览器* jquery-xxx.js 和 jquery-xxx.min.js区别:1. jquery-xxx.js:开发版本。有良好的缩进和注释2. jquery-xxx.min.js:生产版本。没有缩进,体积小。2. 导入JQuery的js文件:导入min.js文件3. 使用var div1 = $("#div1")3. JQuery对象和JS对象的区别和转换1. JQuery对象在操作时更加方便2. JQuery对象和js对象方法不通用3. 两者相互转换* js --> jq : jq对象[索引] 或者 jq对象.get(索引)* jq --> js : $(js对象)4. 选择器:筛选具有相似特征的元素(标签)1. 基本语法学习:1. 事件绑定2. 入口函数* window.onload() = func 和 $(func) 的区别* 前者只能定义一次,如果定义多次,后边的会将前边定义的覆盖* 后者则可以定义多次3. 样式控制2. 分类1. 基本选择器1. 标签选择器(元素选择器)* $("html便签名")2. id选择器* $("#id值")3. 类选择器* $(".class值")4. 并集选择器* $("选择器1,选择器2...")2. 层级选择器1. 后代选择器* $("A B") 选择A元素内部的所有B元素2. 子选择器* $("A > B") 选择A元素下内部的所有B子元素3. 属性选择器1. 属性名称选择器* $("A[属性名]") 包含指定属性的选择器2. 属性选择器* $("A[属性名='值']") 包含指定属性等于指定值的选择器* $("A[属性名^='值']") 属性值为指定值开头的选择器* $("A[属性名$='值']") 属性值为指定值结尾的选择器* $("A[属性名!='值']") 属性值不为指定值或者不存在该属性的选择器* $("A[属性名*='值']") 属性值包含指定值选择器3. 复合属性选择器* $("A[属性名='值'][]...")4. 过滤选择器1. 首元素选择器* :first2. 尾元素选择器* :last3. 非元素选择器* :not(selector)4. 偶数选择器* :even5. 奇数选择器* :odd6. 等于索引选择器* :eq(index)7. 大于索引选择器* :gt(index)8. 小于索引选择器* :lt(index)9. 标题选择器* :header 获取标题元素(h1~h6)5. 表单过滤选择器1. 可用元素选择器* :enabled2. 不可用元素选择器* :disabled3. 选中选择器* :checked  单选/多选框4. 选中选择器* :selected 下拉列表5. DOM操作1. 内容操作1. html():获取/设置元素的标签体内容 <a><font>xxx</font></a> -->  <font>xxx</font>2. text():获取/设置元素的标签体纯文本内容   <a><font>xxx</font></a> -->  xxx3. val():获取/设置元素的value属性值2. 属性操作1. 通用属性操作1. attr():获取/设置元素的属性2. removeAttr():删除属性3. prop():获取/设置元素的属性4. removeProp():删除属性* attr和prop区别:1. 如果操作的是元素的固有属性,则建议使用prop2. 如果操作的是元素自定义的属性,则建议使用attr2. 对class属性的操作1. addClass():添加class属性值2. removeClass():删除class属性值3. toggleClass():切换class属性值* toggleClass("one"): 如果存在class="one"则将属性值one删除,如果不存在,则添加。4. css()3. CRUD操作:1. append():父元素将子元素追加到末尾* 对象1.append(对象2):将对象2添加到对象1元素内部,并且在末尾2. prepend():父元素将子元素追加到开头* 对象1.prepend(对象2):将对象2添加到对象1元素内部,并且在开头3. appendTo():* 对象1.append(对象2):将对象1添加到对象2元素内部,并且在末尾4. prependTo():* 对象1.prepend(对象2):将对象1添加到对象2元素内部,并且在开头5. after():添加元素到对应元素后边* 对象1.after(对象2):将对象2添加到对象1后边。对象1和对象2是兄弟关系6. before():添加元素到对应元素前边* 对象1.after(对象2):将对象2添加到对象1前边。对象1和对象2是兄弟关系7. insertAfter():* 对象1.after(对象2):将对象1添加到对象2后边。对象1和对象2是兄弟关系8. insertBefore():* 对象1.after(对象2):将对象1添加到对象2前边。对象1和对象2是兄弟关系9. remove():移除元素* 对象.remove():将对象删除掉10. empty():清空元素的所有后代元素* 对象.empty():将对象的后代元素全部清空,但是保留当前对象以及其属性节点6. 案例重要案例 需要时进行查看p383-386

Day 20 内容

1. Jquery 高级1. 动画1. 默认显示和隐藏方式1. show([speed, [easing], [fn]])1. 参数1. speed:动画速度。三个预定义的值("slow","normal","fast")或表示动画时长的毫秒值2. easing:用来指定切换效果,默认是"swing",可用参数"linear"* swing:动画执行时效果是先慢,中间快,最后又慢* linear:动画执行时速度匀速3. fn:在动画完成时执行的函数,每个元素执行一次2. hide([speed, [easing], [fn]])3. toggle([speed, [easing], [fn]])2. 滑动显示和隐藏方式1. slidDown([speed, [easing], [fn]])2. slideUp([speed, [easing], [fn]])3. slideToggle([speed, [easing], [fn]])3. 淡入淡出显示和隐藏方式1. fadeIn([speed, [easing], [fn]])2. fadeOut([speed, [easing], [fn]])3. fadeToggle([speed, [easing], [fn]])2. 遍历1. js的遍历方式* for(初始化值;循环结束条件;步长)2. jq的遍历方式1. jq对象.each(callback)1. 语法:jquery对象.each(function(index, element){});* index:索引* element:元素对象* this:每一个元素对象2. 回调函数返回值:* true:结束循环-break* false:结束本次循环,继续下次循环-continue2. $.each(object, [callback])* object可以为jq对象也可为js对象3. for..of3. 事件绑定1. jquery标准的绑定方式jq对象.事件方法(回调函数);* 注:如果调用事件方法,不传递回调函数,则会触发浏览器默认行为* 表单对象.submit();//表单提交2. on绑定事件/off解除绑定jq对象.on("事件名称", 回调函数);jq对象.off("事件名称");* 如果off方法不传递任何参数,则将组件上所有事件解绑3. 事件切换:toggle* jq对象.toggle(fn1, fn2, ...)* 当单击jq对象对应的组件后,会执行fn1,第二次点击执行fn2....* 注意该方法在1.9及以上的高版本被移除,需要使用jquery-migrate插件才能生效4. 案例抽奖小案例5. 插件:增强jquery的功能1. 实现方式:1. $.fn.extend(object)* 增强通过JQuery获取的对象的功能   $("#id")2. $.extend(object)* 增强JQuery对象自身的功能 $/JQuery

Day 21 内容:

1. AJAX
2. JSON

AJAX:

1. 概念:Asynchronous JavaScript And XML 异步的JavaScript和XML1. 异步和同步:客户端和服务器端相互通信的基础上* 同步:客户端必须等待服务器端的响应,不能进行其他操作* 异步:客户端不必须等待服务器端的响应,可以进行其他操作提升用户的体验,不需要重新加载整个页面实现部分页面的更新
2. 实现方式:1. 原生的JS实现方式(了解)* 参考w3school手册2. JQuery实现方式1. $.ajax()* 语法:$.ajax({键值对});$.ajax({url: "",data: {xx: "",yy: ""},success: function(){},error: function(){},dataType: ""});2. $.get():发送GET请求* 语法:$.get(url, [data], [callback], [type])3. $.post():发送POST请求* 同上

JSON:

1. 概念:JavaScript Object Notation  JavaScript对象表示法* json现在多用于存储和交换文本信息的语法* 进行数据的传输* 比XML更小更快更方便
2. 语法:1. 基本规则* 数据在名称/值对中:json由键值对构成* 键用引号引起来,也可以不使用引号* 键的取值类型:1. 数字(整数或浮点数)2. 字符串(双引号)3. 布尔值4. 数组(方括号)5. null6. 对象(花括号)* 数据由逗号分隔:多个键值对由逗号分隔* 花括号保存对象:使用{}定义json格式* 方括号保存数组:[]2. 获取数据:1. json对象.键名2. json对象["键名"]3. 数组对象[索引]3. JSON数据和Java对象的相互转换* JSON解析器:* 常见的解析器:Jsonlib、Gson、fastjson、jackson1. JSON转为Java对象1. 导入jackson相关jar包2. 创建Jackson核心对象 ObjectMapper3. 调用ObjectMapper的相关方法进行转换1. readValue(json数据, Class)2. Java对象转为JSON1. 使用步骤:1. 导入jackson相关jar包2. 创建Jackson核心对象 ObjectMapper3. 调用ObjectMapper的相关方法进行转换1. 转换方法:* writeValue(参数1, obj)参数1:File:将obj对象转为json字符串,并保存到对应的文件中Writer:将obj对象转为json字符串,并将json数据填充到字符输出流中OutputStream:将obj对象转为json字符串,并将json数据填充到字节输出流中* writeValueAsString(obj): 将对象转为json字符串2. 注解1. @JsonIgnore:排除属性2. @JsonFormat:属性值的格式化* @JsonFormat(pattern = "yyyy-MM-dd")3. 复杂Java对象1. List:数组2. Map:和对象格式一致

案例

* 校验用户名是否存在1. 服务器响应的数据,在客户端使用时,需要转为json的格式来使用1. $get(type):将最后一个参数指定为json2. 在服务器端设置MIME类型,response.setContentType("application/json;charset=utf-8")

Day 22 内容:

1. redis1. 概念2. 下载安装3. 命令操作1. 数据结构4. 持久化操作5. 使用Java客户端操作redis

Redis

JavaWeb笔记 黑马程序员课程相关推荐

  1. [学习笔记]黑马程序员-Hadoop入门视频教程

    文章目录 参考资料 第一章:大数据导论与Linux基础(p1-p17) 1.1 大数据导论 1.1.1 企业数据分析方向 1.1.2 数据分析基本流程步骤 明确分析的目的和思路 数据收集 数据处理 数 ...

  2. [学习笔记]黑马程序员Spark全套视频教程,4天spark3.2快速入门到精通,基于Python语言的spark教程

    文章目录 视频资料: 思维导图 一.Spark基础入门(环境搭建.入门概念) 第二章:Spark环境搭建-Local 2.1 课程服务器环境 2.2 Local模式基本原理 2.3 安装包下载 2.4 ...

  3. [学习笔记]黑马程序员python教程

    文章目录 思维导图 Python基础知识图谱 面向对象 SQL入门和实战 Python高阶技巧 第一阶段 第九章:Python异常.模块与包 1.9.1异常的捕获 1.9.1.1 为什么要捕获异常 1 ...

  4. 黑马程序员课程-Vue项目实战-Element-UI——电商后台管理系统主页制作

    黑马程序员视频_主页制作 目录 一.主页布局 1.整体布局:先上下划分,再左右划分 2.主页header布局 3.左侧菜单布局:菜单分为两级,并且可以折叠 二. 通过接口获取菜单数据 1.请求预处理 ...

  5. 零基础学C++——黑马程序员课程笔记(C++核心编程篇)

    封面来自互联网侵删 视频地址:点击访问 (我这里开发工具选用VSstudio) 此笔记有三个系列: C++基础语法入门篇 点击查看 C++核心编程篇 C++提高编程篇 本阶段主要针对C++面向对象编程 ...

  6. c语言笔记——黑马程序员上课笔记

    C语言概述 1.1 什么是C语言 一提到语言这个词语,自然会想到的是像英语.汉语等这样的自然语言,因为它是人和人交换信息不可缺少的工具. 而今天计算机遍布了我们生活的每一个角落,除了人和人的相互交流之 ...

  7. Node.js学习笔记 [黑马程序员]——day34

    文章目录 初识 Express 简介 Express 的基本使用 托管静态资源 nodemon Express 路由 路由的概念 :dog:什么是路由 :dog:Express 中的路由 :dog: ...

  8. Node.js学习笔记 [黑马程序员]——day2

    文章目录 模块化的基本概念 模块化规范 Node.js 中模块的分类 Node.js 中模块的分类 加载模块 Node.js 中的模块作用域 向外共享模块作用域中的成员 `module` 对象 `mo ...

  9. JavaWeb——黑马程序员课程笔记

    视频地址:点击跳转 全程使用开发工具:IDEA Mysql 此篇几乎所有需要的配置文件都可以区黑马公众号找到 目录 JavaWeb介绍 数据库 数据库相关概念 关系型数据库 SQL SQL简介 SQL ...

  10. 零基础学C++——黑马程序员课程笔记(C++基础语法入门篇)

    封面来自互联网侵删 视频地址:点击访问 (我这里开发工具选用VSstudio) 此笔记有三个系列: C++基础语法入门篇 C++核心编程篇 点击查看 C++提高编程篇 文章目录 C++初识 变量 常量 ...

最新文章

  1. linux系统下添加新硬盘的方法详解
  2. 皮一皮:当群聊被封,大家是如何聊天的...
  3. JVM 调优 —— 新生代 Survivor 空间不足
  4. python可视化爬虫框架_8个最高效的Python爬虫框架
  5. 研究:低智商男人易出轨
  6. 一个游戏美术写给策划的快速入门
  7. Swift 语言快速入门
  8. kinect v1原理_Kinect原理及介绍.ppt
  9. 接口jdk1.8与jdk1.9新特性
  10. BG.Hive - part3
  11. 关于element el-button使用$attrs的一个注意要点
  12. PPT达人速成记 WPS三步打造演示母版
  13. 解决 appcompat 1.1.0 导致 webview crash 的问题
  14. Photoshop插件-证件照-白红蓝底-PS插件-脚本开发
  15. Wpa_supplicant 调试故障原因分析
  16. 计算机运行慢 卡是什么原因是什么原因,电脑反应慢是怎么回事?五招让你的电脑快得飞起!...
  17. 我的挨踢人生(16)——往事如云烟
  18. 微信小程序成语小秀才,成语接龙超详细搭建教程
  19. 2022-2027年中国知识产权代理行业发展前景及投资战略咨询报告
  20. Java 16 新特性:record类

热门文章

  1. UI自动化测试之元素定位
  2. 2019年泰迪杯技能赛A题心得
  3. webstorm2019汉化详细教程,小白专用
  4. android 电脑 手柄游戏排行榜,各类吃鸡安卓模拟器测评排行,电脑玩手机游戏哪家强?...
  5. Spring Boot菜鸟示例——Hello World
  6. 2012浙江大学光华法学院毕业典礼教师发言之高艳东
  7. 1.4.1用空间向量研究直线、平面的位置关系教学设计
  8. c语言链表移动北理工,北京理工大学c语言网络教室 链表
  9. Unity基础知识学习四,UI框架设计
  10. 2021年还能用的13款完全免费的Office插件整理(含功能详细介绍)