笔记是大二的时候做的,今天也翻出来看了一下,当时竟然还不知道用md,还是很怀念当年的单纯啊,是在txt里面一个字一个字敲的,图片里面的数据都被一行行的敲出来了,现在翻出来干脆就上传到csdn吧,顺序大致是数据库,前端,后端,有jdbc,mybatis,request,response,cookie等等
数据库
JDBC
JDBC 就是使用Java语言操作关系型数据库的一套API
本质: 官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口
各个数据库厂商去实现这套接口,提供数据库驱动jar包
我们可以使用这套接口(JDBC)编程,真正执行的代码时驱动jar包中的实现类
好处:各数据库厂商使用相同的接口,Java代码不需要针对不同数据库分别开发
可随时替换底层数据库,访问数据库的Java代码基本不变
JDBC API详解
DriverManager(驱动管理类):
1、注册驱动
2、获取数据库连接
getConnection(String url,String user,String password)
Connection(数据库连接对象):
1、获取执行SQL的对象
普通执行sql对象
Statement createStatement()
预编译sql的执行sql对象:防止sql注入
preparedStatement prepareStatement(sql)
执行存储过程的对象
CallableStatement prepareCall(sql)
2、管理事务
Mysql事务管理
开启事务:BEGIN;/START TRANSACTION
提交事务:COMMIT;
回滚事务:ROLLBACK
MYSQL默认自动提交事务
JDBC事务管理:Connection接口中定义了3个对应的方法
开启事务:setAutoCommit(boolean autoCommit):true为自动提交事务;false为手动提交事务
提交事务:commit()
回滚事务:rollback()
Statement:
执行SQL语句
int executeUpdate(sql):执行DML、DDL语句
返回值:(1)DML语句影响的行数(2)DDL语句执行后,执行成功也可能返回0
ResultSet executeQuery(sql):执行DQL语句
返回值:ResultSet结果集对象
ResultSet(结果集对象):
封装DQL查询语句的结果
ResultSet stmt.executeQuery(sql):执行DQL语句,返回ResultSet对象
获取查询结果:
boolean next():(1)将光标从当前位置前移一行(2)判断当前行是否为有效行
返回值:true:有效行,当前行有数据
xxx getXxx(参数):获取数据
xxx:数据类型:int getInt(参数);String getString(参数)
参数:int:列的编号,从1开始
String:列的名称
使用步骤:
1、游标向下移动一行,并判断该行是否有数据
2、获取数据:getXxx(参数)
//循环判断游标是否是最后一行末尾
while(rs.next()){
//获取数据
rs.getXxx(参数);
}
PrepareStatement
作用:1、与便于SQL语句并执行:预防SQL注入问题
获取PreparedStatement对象
//SQL语句中的1参数值,用?占位符代替
String sql=“select * from user where username =? and password=?”
//通过Connection对象获取,并传入对应的sql语句
PreparedStatement pstmt=conn.prepareStatment(sql)
设置参数值
PreparedStatement对象:setXxx(参数1,参数2):给?赋值
Xxx:数据类型;如:setInt(参数1,参数2)
参数:
参数1:?的位置编号,从1开始
参数2:?的值
执行SQL
executeUpdate();/executeQuery();:不需要再传递sql
SQL注入:SQL注入式通过操作输入来修改事先定义号的SQL语句,用以达到执行代码对服务器进行攻击的方法
数据库语言
通过mysql -uroot -p1234 -h127.0.0.1 -P3306进去mysql
单行注释#
多行注释/**/
DDL 操作数据库,表
show databases;查询
create database 数据库名称;创建数据库 create database if not exists 数据库名称;创建数据库(判断,如果不存在则创建)
drop database 数据库名称;删除数据库 drop database if not exists 数据库名称;删除数据库(判断,如果存在则删除)
select database();查看当卡使用的数据库
use 数据库名称;使用数据库
查询表
show tables;查询当前数据库下所有表名称
desc 表名称;查询表结构
创建表
create table 表名(
字段名1 数据类型1,
字段名2 数据类型2,
...... ......
字段名n 数据类型n
);
注意:最后一行末尾不能加逗号
删除表
drop table 表名;删除选中的表
drop table if exists 表名;删除表时判断表是否存在
修改表
alter table 表名 rename to 新的表名;修改表名
alter table 表名 add 列名 数据类型;添加一列
alter table 表名 modify 列名 新数据类型;修改数据类型
alter table 表名 change 列名 新列名 新数据类型;修改列名和数据类型
alter table 表名 drop 列名;删除列
DML 对表中的数据进行增删改
添加数据
insert into 表名(列1,列2,···)values(值1,值2,···);给指定列添加数据
insert into 表名 values(值1,值2,···);给全部列添加数据
insert into 表名 (列1,列2,···) values(值1,值2,···),(值1,值2,···),(值1,值2,···)···;批量添加数据
insert into 表名 values(值1,值2,···),(值1,值2,···),(值1,值2,···)···;批量添加数据
修改数据
update 表名 set 列1=值1,列2=值2,···[where 条件];修改表数据
例如:update stu set sex=‘女’ where name =‘张三’;
删除数据
delete from 表名 [where 条件];删除表数据
DQL 对表中的数据进行查询
基础查询
select 字段列表 from 表名; 查询多个字段
selec*from 表名;--查询所有数据 查询多个字段
select distinct 字段列表 from 表名; 去除重复记录
as: as可以省略 起别名 例如 select name,math as 数学成绩,english as 英语成绩 from stu;
条件查询
select 字段列表 from 表名 where 条件列表; 条件查询语法
条件:
符号 功能
> 大于
< 小于
>= 大于等于
<= 小于等于
= 等于
<>或!= 不等于
between...and... 在某个范围之内(都包含)
in(...) 多选一
like占位符 模糊查询 _单个任意字符 %多个任意字符
is null 是null
is not null 不是null
and或&& 并且
or或|| 或者
not或! 非,不是
排序查询
select 字段列表 from 表名 order by 排序字段名1[排序方式1],排序字段2[排序方式2]...; 排序查询语法
例如:select *from stu order by age asc;
排序方式:ASC:升序排列(默认值)DESC:降序排列
注意:如果有多个排序条件,当前边的条件值一样时,才会根据第二条件进行排序
聚合函数
概念:将一列数据作为一个整体,进行纵向计算
聚合函数分类:
函数名 功能
count(列名) 统计数量(一般选用不为null的列)
max(列名) 最大值
min(列名) 最小值
sum(列名) 求和
avg(列名) 平均值
聚合函数语法:select 聚合函数(列名) from 表;
注意:null值不参与所有聚合函数运算
分组查询
select 字段列表 from 表名 [where 分组前条件限定] group by 分组字段名[having 分组后条件过滤];分组查询语法
注意:分组之后,查询的字段为聚合函数和分组字段,查询其他文字无任何意义
where和having的区别:
执行时机不一样:where是分组之前进行限定,不满足where条件则不参与分组,而having是分组之后对结果进行过滤
可判断的条件不一样:where不能对聚合函数进行判定,having可以
执行顺序:where>聚合函数>having
分页查询
select 字段列表 from 表名 limit 起始索引,查询条目数
起始索引:从0开始
计算公式:起始索引=(当前页码-1)*每页显示的条数
分页查询limit是MySQL数据库的方言
Oracle分页查询使用rownumber
SQL Server分页查询使用top
DCL 数据控制语言
用来管理数据库用户、控制数据库的访问权限
管理用户
1、查询用户
use mysql;
select * from user;
2、创建用户
create user '用户名'@'主机名' identified by '密码';
3、修改用户密码
alter user '用户名'@'主机名' identified with mysql_native_password by'新密码';
4、删除用户
drop user ‘用户名’@‘主机名’;
注意:
主机名可以用%通配
权限控制
ALL,ALL PRIVILEGES 所有权限
SELECT 查询数据
INSERT 插入数据
UPDATA 修改数据
DELETE 删除数据
ALTER 修改表
DROP 删除数据库/表/视图
CREATE 创建数据库/表
1、查询权限
show grants for '用户名'@‘主机名’;
2、授予权限
grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';
3、撤销权限
revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';
注意:
多个权限之间用逗号进行分隔,授权时数据库和表名可以用*通配,代表所有
eg:
-- 创建用户alen,只能在当前主机访问,密码123456
create user 'alen'@'localhost' identified by '123456';
-- 创建用户bob,可以在任意主机访问该数据库,密码123456
create user 'Bob'@'%' identified by '123456';
-- 修改用户alen的密码为1234
alter user 'alen'@'localhost' identified with mysql_native_password by '1234';
-- 删除用户alen
drop user 'alen'@'localhost';
show grants for 'Bob'@'%';
grant all on stu.* to 'Bob'@'%';
revoke all on stu.* from 'Bob'@'%';
视图
介绍:视图时一种虚拟存在的表,视图中的数据并不在数据库中实际存在,行和列数据来定义视图的查询中使用的值,并且是在使用视图时动态生成的
通俗的讲,视图只保存了查询的SQL逻辑,不保存查询结果,所以我们在创建视图的时候,主要的工作就落在创建这条SQL查询语句上
创建:
create [OR REPLACE] VIEW 视图名称[(列名列表)] AS SELECT语句 [WITH [CASCADED | LOCAL] CHECK OPTION]
查询:
查看创建视图语句:SHOW CREATE VIEW 视图名称;
查看视图数据:select * from 视图名称......;
修改:
方式一:CREATE [OR REOKACE] VIEW 视图名称[(列名列表)] AS SELECT语句 [WITH[CASCADED | LOCAL]CHECK OPTION]
方式二:ALTER VIEW 视图名称[(列名列表)] AS SELECT语句 [WITH[CASCADED | LOCAL]CHECK OPTION]
删除:DROP VIEW [IF EXISTS] 视图名称[,视图名称]······
视图检查选项
当使用[WITH[CASCADED | LOCAL]CHECK OPTION]子句创建视图时,MYSQL会通过视图检查正在更改的每个行,例如插入,更新,删除,以使其符合视图的定义。MYSQL允许基于另一个视图创建视图,它还会检查依赖视图中的规则保持一致性,为了确定检查的范围,mysql提供了两个选项CASCADED 和LOCAL,默认值是CASCADED
视图的更新:
要使得视图可更新,视图中的行与基础表中的行之间必须存在一对一的关系,如果视图包含以下任何一项,则该视图不可更新:
1、聚合函数或窗口函数(SUM()、MIN()、MAX()、COUNT())
2、DISTINCT
3、GROUP BY
4、HAVING
5、UNION 或者UNION ALL
作用:
视图不仅可以简化用户对数据的理解,也可以简化他们的操作,那些经常使用的查询可以被定义成视图,从而使得用户不必为以后的操作指定全部的条件
安全:数据库可以授权,但不能授权到数据库特定行和特定列上。通过视图用户只能查询和修改他们所能见到的数据
数据独立:视图可以帮助用户屏蔽真实表结构变化带来的影响
总结:视图可以看成表,然后增删改查
约束-多表查询-事务
约束
概念:约束是作用与表中列上的规则,用于限制加入表的数据
约束的存在保证了数据库中数据的正确性、有效性、完整性
MYSQL不支持检查约束
约束分类:
约束名称 描述 关键字
非空约束 保证列中所有数据不能有null值 not null
唯一约束 保证列中所有数据各不相同 unique
主键约束 主键是一行数据的唯一标识,要求非空且唯一 primary key
检查约束 保证列中的值满足某一条件 check
默认约束 保存数据时,未指定值则采用默认值 default
外键约束 外键用来让两个表的数据之间建立链接,保证数据的一致性和完整性 foreign key
eg:id INT PRIMARY KEY auto—increment,--id,主键且自增长
ename VARCHAR(50) NOT NULL UNIQUE,--姓名,非空且唯一
auto-increment:当列是数字类型并且唯一约束
外键约束
1、添加约束
create table 表名(
列名 数据类型,
...
[constraint][外键名称]foreign key(外键列名)reference 主表(主表列名)
);
-- 建完表后添加外键约束
alter table 表名 add constraint 外键名称 foreign key(外键字段名称)references 主表名称(主表列名称)
--先创建主表再创建副表才能添加外键约束
--删除时,要先删除从表的数据再删除主表的数据才可以,否则会报错
2、删除约束
alter table 表名 drop foreign key 外键名称;
数据库设计
1、软件的研发步骤
需求分析>设计>编码>测试>安装部署
2、数据库设计概念
数据库设计就是根据业务系统的具体需求,结合我们所选用的DBMS,为这个业务系统构造出最优的数据存储模型
建立数据库中的表结构以及表与表之间的关联关系的过程
3、数据库设计的步骤
1、需求分析(数据是什么?数据具有哪些属性?数据与属性的特点是什么?)
2、逻辑分析(通过ER图对数据库进行逻辑建模,不需要考虑我们所选用的数据库管理系统)
3、物理设计(根据数据库自身的特点把逻辑设计转换为物理设计)
4、维护设计(1、对新的需求进行建表;2、表的优化)
表关系之一对多
一对多(多对一):在多的一方建立外键,指向一的一方的主键
多对多:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
一对一:在任意一方加入外键,关联另一方主键,并且设置外键为唯一(unique)
多表查询
笛卡尔积:取A,B集合所有组合情况
多表查询:从多张表查询数据
连接查询:
内连接:相当于查询A B交集数据
隐式内连接
select 字段列表 from 表1,表2...where 条件;
显示内连接
select 字段列表 from 表1 [inner] join 表2 on 条件;
外连接:
左外连接:相当于查询A表所有数据和交集部分数据
select 字段列表 from 表1 left[outer]join 表2 on 条件;
右外连接:相当于查询B表所有数据和交集部分数据
select 字段列表 from 表1 right[outer]join 表2 on 条件 ;
子查询:查询中嵌套查询,称嵌套查询为子查询
子查询根据查询结果不同,作用不同
单行单列 作为条件值,使用= != ><等进行条件判断
select 字段列表 from 表 where 字段名 = (子查询)
多行单列 作为条件值,使用in等关键字进行条件判断
where 字段列表 from 表 where 字段名 in (子查询)
多行多列 作为虚拟表
select 字段列表 from (子查询)where 条件;
事务
事务简介
数据库的事务是一种机制、一个操作序列,包含了一组数据库操作命令
事务把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么同时成功,要么同时失败
事物是一个不可分割的工作逻辑单元
事务操作
开启事务 start transaction;或BEGIN;
提交事务 COMMIT;
回滚事务 ROLLBACK;
事务四大特征ACID
原子性(A):事务是不可分割的最小操作单位,要么同时成功,要么同时失败
一致性(C):事务完成时,必须使所有的数据都保持一致状态
隔离性(I):多个事务之间,操作的可见性
持久性(D):事务一旦提交或者回滚,它对数据库中的数据的改变就是永久的
前端
html和css太简单了,当时就没认真记,只写了一点js
JS
输出语句
Window.alert()写入警告框 window.alert(”“);
document.write()写入HTML输出 document.write(”“);
console.log()写入浏览器控制台 console.log(”“);
变量
JavaScript用var关键词来表明变量 var test=20;test=”张三“;
JS是一门弱语言,变量可以存放不同类型的值
组成字符可以是任何字母、数字、下划线或美元符号
数字不能开头
建议使用驼峰命名
let关键词定义变量类似于var,但所声明的变量,只在let关键字所在的代码块内有效,且不允许重复声明
const关键词,用来声明一个只读的常量。一旦声明,常量值不可改变
数据类型
JS中分为原始类型和引用类型
5种原始类型:
number:数字(整数、小数、NaN(Not a Number))
string:字符、字符串、单双引皆可
Boolean:布尔、true,false
null:对象为空
underfined:当声明的变量未初始化时,该变量的默认值是underfined
使用typeof运算符可以获取数据类型:alert(typeof age);
运算符
==判断类型是否一样,如果不一样,则进行类型转换,再去判断比值
===判断类型是否一样,如果不一样,直接返回false,再去判断比值
1、其他类型转为number:
1、string:按照字符串的字面值,转为数字,如果字面值不是数字,则转为NaN
var str=”20“;
alert(parseInt(str)+1);
2、Boolean:true转为1,false转为0
2、其他类型转为boolean:
1、number:0和NaN转为false,其他值都是true
2、string:空字符转为false,其他的字符串转为true
3、null:false;
4、undefined:false;
流程控制语句
if:
switch:
for:
while:
do...while:
函数
函数(方法)是被设计为执行特定任务的代码块
定义:JS的函数通过function关键字定义,语法为:
function functionName(参数1,参数2..){
要执行的代码
}
注意:形式参数不需要类型。因为JS是弱语言
返回值也不需要定义类型,可以在函数内部直接使用return返回即可
function add(a,b){
return a+b;
}
调用:函数名称(实际参数列表);
let result=add(1,2);
定义方式2:
var functionName=function(参数列表){
要执行的代码
}
var add=function(a,b){
return a+b;
}
调用:JS种,函数调用可以传递任意个参数
let result=add(1,2,3);
JS对象
Array
JS Array对象用于定义数组
定义:
var 变量名=new Array(元素列表);//方式一 var arr=new Array(1,2,3);
var 变量名=[元素列表];//方式二 var arr=[1,2,3];
访问:
arr[索引]=值;
arr[0]=1;
注意:JS数组类似于Java集合,长度,类型都可变
属性:length:数组中元素的个数
var arr=[1,2,3];
for(let i=0;i<arr.length;i++){
alert(arr[i];
}
push:添加元素
var arr=[1,2,3];
arr.push(10);
alert(arr);
splice:删除元素
var arr=[1,2,3];
arr.splice(0,1);//从零位开始删,删除一个
alert(arr);
String
定义
var 变量名=new String(s);//方式一
var 变量名=s;//方式二
属性
length 字符串的长度
方法
charAt()返回在指定位置的字符
indexOf()检索字符串
自定义对象
var 对象名称={
属性名称1:属性值,
属性名称2:属性值,
...
函数名称:function(形参列表){}
...
};
示例:
var person={
name:“zhangsan”,
age:23,
eat:function(){
alert(”干饭~”)
}
};
BOM对象:浏览器对象模型
JS将浏览器的各个组成部分封装为对象
组成:
Window:浏览器窗口对象
获取:直接使用window,其中window可以省略
window.alert(“abc”);
方法:
alert() 显示带有一段消息和一个确认按钮的警告框
confirm() 显示带有一段消息以及确认按钮和取消按钮的对话框
点击确定按钮会返回true 点击取消按钮会返回false
setInterval()按照指定的周期(以毫秒计)来调用函数或计算表达式
setTimeout()在指定的毫秒数后调用函数或计算表达式
Navigator:浏览器对象
Screen:屏幕对象
History:历史记录对象
获取:使用window.history获取,其中window可以省略
window.history.方法();
history.方法();
方法:
back()加载history列表中的前一个URL
forward()加载history列表中的下一个URL
Location:地址栏对象
获取:使用window.location获取,其中window可以省略
window.location.方法();
location.方法();
属性
href 设置或返回完整的URL
DOM:文档对象模型
将标记语言的各个组成部分封装成对象
Document:整个文档对象
Element:元素对象
Attribute:属性对象
Text:文本对象
Comment:注释对象
JS通过DOM,能够对HTML进行操作
改变HTML元素内容
改变HTML元素样式
对HTML DOM事件做出反应
添加和删除HTML元素
获取Element
Element:元素对象
获取:使用Document对象的方法来获取
1、getElementById:根据id属性值获取,返回一个Element对象
2、getElementsByTagName:根据标签名称获取,返回Element对象数组
3、getElementsByName:根据name属性值获取,返回Element对象数组
4、getElementsByClassName:根据class属性值获取,返回Element对象数组
事件监听
事件:HTML事件是发生在HTML元素上的事情
按钮被点击
鼠标移动到元素上
按下键盘按键
事件监听:JS可以在事件被侦测到时执行代码
事件绑定有两种方式
方式一通过HTML标签中的事件属性进行绑定例如
<input type="button" οnclick='on()'>
function on(){
alert("aaa");
}
方式二通过DOM元素属性绑定
<input type="button" id="btn">
document.getElementById("btn").οnclick=function(){
alert("aaa");
}
JSP
Java Server Pages,Java服务端页面
一种动态的网页技术,其中既可以定义HTML、JS、CSS等静态内容,还可以定义Java代码的动态内容
JSP=HTML+Java
JSP作用:简化开发,避免了在Servlet中直接输出HTML标签
原理:本质上就是一个Servlet
JSP被访问时,由JSP容器(Tomcat)将其转化为Java文件(Servlet),在由JSP容器(Tomcat)将其编译,最终对外提供服务的其实就是这个字节码文件
JSP脚本
JSP脚本用于在JSP页面内定义Java代码
JSP脚本分类:
<%...%>:内容直接放到_jspService()方法之中
<%=...%>:内容会放到out.pinrt()中,作为out.print()的参数
<%!...%>:内容会放到_jspService()方法之外,被类直接包含
JSP缺点
由于JSP页面内,既可以定义HTML标签,又可以定义Java代码,造成了以下问题
1、书写麻烦:特别是复杂页面
2、阅读麻烦
3、复杂度高:运行需要依赖各种环境,JRE,JSP容器,JavaEE...
4、占内存和磁盘:JSP会自动生成.Java和.class文件占磁盘
5、调试困难:出错后,需要找到自动生成的.Java文件进行调试
6.不利于团队协作:前端人员不会Java,后端人员不精HTML
解决方式:
不要直接在JSP里面写Java代码:
Servlet逻辑处理,封装数据
JSP获取数据并遍历展现
EL表达式
表达式语言,用于简化JSP的Java代码
主要功能:获取数据
语法:${expression}
${brand}:获取域中存储的key为brands的数据
JavaWeb中的四大域对象
page:当前页面有效
request:当前请求有效
session:当前会话有效
application:当前应用有效
el表达式获取数据,会依次从这四个域中寻找,直到找到为止
<c:test="">
<c:forEach items="${brands}" var="brand">
JSTL标签
JSP标准标签库,使用标签取代JSP页面上的Java代码
1、导入依赖
2、在JSP页面上引入JSTL标签库
3、使用
MVC模式
MVC时一种分层开发的模式
M:Model,业务模型,处理业务 JSP
V:View,视图,界面展示 JavaBean
C:Controller,控制器,处理请求,调用模型和视图 Servlet
好处:
职责单一,互不影响
有利于分工协作
有利于组件重用
三层架构
表现层:接收请求,封装数据,调用业务逻辑层,响应数据
业务逻辑层:对业务逻辑进行封装,组合数据访问层层中基本功能,形成复杂的业务逻辑功能
数据访问层(持久层):对数据库的CRUD基本操作
会话跟踪技术
会话:用户打开浏览器,访问web服务器的资源,会话建立,直到一方断开连接,会话结束。在一次会话中可以包含多次请求和响应
会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据
HTTP协议是无状态的,每次浏览器向服务器请求时,服务器都会将该请求视为新的请求,因此我们需要会话跟踪技术来实现会话内数据共享
实现方式:1、客户端会话跟踪技术:Cookie
2、服务端会话跟踪技术:Session
Cookie基本使用
Cookie:客户端会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问
发送cookie:
1、创建Cookie对象,设置数据
Cookie cookie=new Cookie(“key","value");
2、发送Cookie到客户端:使用response对象
response.addCookie(cookie);
获取Cookie:
1、获取客户端携带的所以Cookie,使用request.getCookies();
2、遍历数组,获取每一个Cookie对象:for
3、使用Cookie对象方法获取数据
cookie.getName();
cookie.getValue();
Cookie原理
Cookie的实现是基于HTTP协议的
响应头:set-cookie
请求头:cookie
Cookie使用细节
Cookie存活时间:
默认情况下,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁
setMaxAge(int seconds):设置Cookie存活时间
正数:将Cookie写入浏览器所在电脑的硬盘,持久化存储,到时间自动删除
负数:默认值,Cookie在当前浏览器的内存中,当浏览器关闭,则·Cookie被销毁
零:删除对应Cookie
Cookie存储中文
如需要存储,则需要转码:URL编码
Session基本使用
服务端的会话跟踪技术:将数据保存到服务器
JavaEE提供的HttpSession接口,来实现一次绘画的多次请求间数据共享功能
使用:1、获取Session对象
HttpSession session=request.getSession()
2、Session对象功能
Void setAttribute(String name,Object o):存储数据到session中
Object getAttribute(String name):根据key,获取值
Void removeAttribute(Stringname):根据key,删除该键值对
Session原理
Session是基于Cookie实现的
Session的细节
Session的钝化,活化:
服务器重启之后,Session的数据依然存在
钝化:在服务器正常关闭之后,Tomcat会自动将Session数据写入硬盘的文件中
活化:再次启动服务器后,从文件中加载数据到Session中
Session销毁:
默认情况下:无操作,30分钟之后自动销毁
<session-config>
<session-timeout>30</session-timeout>
</session-config>
调用Session对象的invalidate()方法
Cooike和Session都是来完成一次会话内多次请求间数据共享的
区别:
存储位置:Cookie是将数据存储在客户端,Session是将数据存储在服务端
安全性:cookie不安全,Session安全
数据大小:Cooike最大3kb,Session无大小限制
存储时间:Cooike可以长期储存,Session默认30分钟
服务器性能:Cooike不占服务器资源,Session占用服务器资源
Filter-AJAX-JSON-Vue
Filter
概念:Filter表示过滤器,是Javaweb三大组件(Servlet、Filter、Listener)之一
过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能
过滤器一般完成一些通用的操作:权限控制、统一编码处理、敏感字符处理等等...
Filter快速入门
1、定义类,实现Filter接口,并重写其所有方法
2、配置Fileter拦截资源的路径:在类上定义@WebFilter注解
3、在doFilter方法中输出一句话,并放行
Filter执行流程
放行后访问对应资源,资源访问完成后,会回到Filter中
回到Filter中之后会执行放行后的逻辑
Filter使用细节
拦截路径配置
Filter可以根据需求,配置不同的拦截资源路径
@WebFilter(“/*”)
拦截具体资源:/index.jsp:只有访问index.jsp时才会被拦截
目录拦截:/user/*:访问/user下的所有资源都会被拦截
后缀名拦截:*.jsp:访问后缀名为JSp的资源都会被拦截
拦截所有:/*:访问所有资源都会被拦截
过滤器链
一个Web应用,可以配置多个过滤器,这多个过滤器成为过滤器链
注解配置的Filter优先级按照过滤器类名(字符串)的自然排序
Listener
概念:Lisener表示监听器,时JavaWeb三大组件之一
监听器可以监听就是在application,session,request三个对象创建、销毁或者往其中添加修改删除属性时自动执行代码的功能组件
AJAX
概念:异步的JavaScript和XML
AJAX作用:
1、与服务器进行数据交换:通过AJAX可以给服务器发送请求,并获取服务器响应的数据
使用了AJAX和服务器进行通信,就可以使用HTML+AJAX来替换JSP页面了
2、异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联系、用户名是否可用校验
AJAX快速入门
1、编写AjaxServlet,并使用response输出字符串
2、创建XMLHTTPRequest对象:用于和服务器交换数据
3、向服务器发送请求
4、获取服务器响应数据
AJAX案例
使用AJAX验证用户名是否存在
需求:在完成用户注册时,当用户名输入框失去焦点时,校验用户名是否在数据库已经存在
Axios异步框架
Axious对原生的AJAX进行封装,简化书写
Axios快速入门
1、引入axios的js文件
2、使用axios发送请求并获得响应结果
Axios请求方式别名
axios.get(url,config)
axios.post(url,data,config)
JSON
概念:JavaScript对象表示法
由于语法简单,层次结构鲜明,现多用于作为数据载体,在网络中进行数据传输
JSON基础语法
定义
value的数据类型为:
数字(整数或浮点数)
字符串(在双引号中)
逻辑值(true或false)
数组(在方括号中)
对象(在花括号中)
null
var 变量名={
“key” :value1,
“key”:valu2,
...
}
获取数据:
变量名:key
json.key
JSON数据和Java对象转换
请求数据:JSON字符串转为Java对象
响应数据:Java对象转为JSON字符串
Fastjson
使用:导入坐标
Java对象转JSON
String jsonStr=JSON.toJSONString(obj);
JSON字符串转Java对象
User user=JSON.parseObject(jsonStr,User.class);
Vue
Vue是一套前端框架,免除原生JS中的DOM操作,简化书写
基于MVVM思想,实现了数据的双向绑定,将编程的关注点放在数据上
MVC只能实现模型到视图的单向展示
MVVM可以实现数据的双向绑定
Vue快速入门
新建HTML页面,引入Vue.js文件
在js代码区域,创建Vue核心对象,进行数据绑定
new Vue({
el:“#app”,
data(){
return{
username:""
}
}
});
编写视图
<div id="app>
<input name="username" v-model="username">
{{username}}
<!--插值表达式-->
</div>
Vue常用指令
指令:HTML标签上带有v-前缀的特殊属性,不同指令具有不同含义
常用指令:
v-bind为html标签绑定属性值,如设置href,css样式等
v-model在表单元素上创建双向数据绑定
v-on为HTML标签绑定事件
v-if
v-else
v-else-if条件性的渲染某元素,判定为true时渲染,否则不渲染
v-show根据条件展示某元素,区别在于切换的是display属性的至
v-for列表渲染,遍历容器的元素或者对象的属性
Element
一套基于VUE的网站组件库,用于快速构建网页
组件:组成网页的部件,例如 超链接、按钮、图片、表格等等~
后端
概览
Web:全球广域网,也称为万维网(www),能通过浏览器访问的网站
javaWeb:是用Java技术来解决相关的web互联网领域的技术栈
JavaWeb技术栈:B/S架构:Browser/Server,浏览器/服务器 架构模式,它的特点是,客户端只需要浏览器,应用程序的逻辑和数据都存在在服务器端。浏览器只需要请求服务器,获取Web资源,服务器将Web资源发送给浏览器即可
好处:易于维护升级:服务器端升级后,客户端无需任何部署就可以使用到新的版本
静态资源:HTML、CSS、JavaScript、图片等。负责页面展现
动态资源:Servlet、JSP等。负责逻辑处理
数据库:负责存储数据
HTTP协议:定义通信规则
Web服务器:负责解析HTTP协议,解析请求数据,并发送响应数据
HTTP:概念:超文本传输协议,规定了浏览器与服务器之间数据传输的guize
特点:基于TCP协议:面向连接,安全
基于请求-响应模式的:一次请求对应一次响应
HTTP协议是无状态的协议:对于事务处理没有记忆能力。每次请求-响应都是独立的
缺点:多次请求间不能共享数据 Java中使用会话技术(Cookie、Session)来解决这个问题
优点:速度快
请求数据格式:
请求数据分为3部分:
1、请求行:请求数据的第一行,其中GET表示请求方式,/表示请求资源路径,HTTP/.1表示协议版本
2、请求头:第二行开始,格式为key:value形式
3、请求体:POST请求的最后一部分,存放请求参数
GET/HTTP/1.1
Host:www.itcast.cn
Connection:keep-alive
Cache-Control:max-age=0 Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 Chrome/91.0.4472.106
常见请求头:
Host:表示请求的主机名
User-Agent:浏览器版本,例如Chrome浏览器的表示类似Mozilla/5.0...
Chrome/79,IE浏览器的标识类似Mozilla/5.0(Windows NT...)like Gecko;
Accept:表示浏览器能接受的资源类型,如text/*,image/*或者*/*表示所有
Accept-Language:表示浏览器偏好的语言,服务器可以据此返回不同语言的类型
Accept-Ending:表示浏览器可以支持的压缩类型,例如gzip,deflate
Post特有的:username=superbaby&password=123456
GET和POST请求区别:
1、GET请求请求参数在请求行中,没有请求体。POST请求请求参数在请求体中
2、GET请求请求参数大小有限制,POST没有
响应数据格式:
响应数据分为3部分:
1、响应行:响应数据的第一行。其中HTTP/1.1表示协议版本,200表示响应状态码,OK表示状态码描述
2、响应头:第二行开始,格式为key:value形式
3、响应体:最后一部分。存放响应数据
HTTP/1.1 200 OK
Server:Tergine
Content-Type:text/html
Transfer-Encoding:chunked...
<html>
<head>
<title></title>
</head>
<body></body>
</html>
请求响应
Request(请求)和Response(响应)
Request:获取请求数据
Response:设置响应数据
Request的继承体系
ServletRequest-->Java提供的请求对象根接口
HttpServletRequest-->Java提供的对Http协议进行封装的请求对象接口
RequestFacede-->Tomcat提供的实现类
Tomcat需要解析请求数据,封装为request对象,并且创建request对象传递到service方法中
Request获取请求数据
请求数据分为3部分:
1、请求行 GET(请求方式)/request-demo/reg1?username=张三(请求路径和请求参数) HTTP/1.1(请求的协议以及版本号)
String getMethod():获取请求方式:GET!
String getContextPath():获取虚拟目录(项目访问路径):/request-demo
StringBuffer getRequestURL():获取URL:http://localhost:8080/request-demo/req1
String getRequestURL():获取URI(统一资源标识符):/request-demo/req1
String getQueryString():获取请求参数(GET方式):username=张三&password=123
2、请求头User-Agent:Mozilla/5.0 Chrome/91.0.4472.106
String getHeader(String name):根据请求头名称,获取值
3、请求体username=superbaby&password=123
ServletInputStream getInputStream():获取字节输入流
BufferedReader getReader():获取字符输入流
Request通用方式获取请求参数
请求参数获取方式:
GET方式:
String getQueryString()
Post方式
BufferedReader getReader()
方法:
Map<String,String[]>getParameterMap():获取所有参数Map集合
String[] getParameterValues(String name):根据名称获取参数值(数组)
String getParameter(String name):根据名称获取参数值(单个值)
Request请求参数中文乱码处理
请求参数如果存在中文数据,会乱码
解决方案:POST:设置输入流的编码
req.serCharacterEncoding("UTF-8");
GET,获取参数的方式:getQueryString
乱码原因:tomcat进行URL解码,默认的字符集为ISO-8859-1
先对乱码数据进行编码,转化为字节数组
byte[] bytes=username.getBytes(StandardCharsets.ISO_8859_1);
username=new String(bytes,StandardCharsets.UTF_8);
System.out.println(username);
也可以用
username=new String(username.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);
Request对象请求转发
请求转发:一种在服务器内部的资源跳转方式
实现方式:req.getRequestDispatcher("资源B路径").forword(req.resp);
请求转发资源间共享数据:使用request对象
void setAttribute(String name,Object o):存储数据到request域中
Object getAttribute(String name):根据key,获取值
void removeAttribute(String name):根据key,删除该键值对
Response
ServletResponse-->Java提供的请求对象根接口
HttpServletResponse-->Java提供的对Http协议封装的请求对象
ResponseFacade-->Tomcat定义的实现类
Response设置响应数据功能介绍
响应数据分为3部分:
1、响应行:HTTP/1.1 200 OK
void setStatus(int sc):设置响应状态码
2、响应头:Content-Type:text/html
void setHeader(String name,String value):设置响应头键值对
3、响应体:<html><head></head<body></body></html>
Mybatis
Mybatis是一款优秀的持久层框架,用于简化JDBC开发
持久层:负责将数据保存到数据库的那一层代码
JavaEE三层架构:表现层、业务层、持久层
表现层:页面展示
业务层:逻辑处理
持久层:对数据持久化
框架:就是一个半成品软件,是一套可重用的、通用的、软件基础代码模型
在框架的基础上构建软件编写更加高效、规范、通用、可扩展
JDBC缺点:
1、硬编码
1)注册驱动、获取连接
2)SQL语句
2、操作繁琐
1)手动设置参数
2)手动封装结果集
Mybatis免除了几乎所有的JDBC代码,以及设置参数和获取结果集的工作
快速入门:
1、创建数据库的表
2、创建模块,在maven导入坐标
3、编写Mybatis核心配置文件-->替换连接信息 解决硬编码问题
4、编写SQL映射文件-->统一管理sql语句,解决硬编码问题
5、编码
1、定义POJO类
2、加载核心配置文件,获取SqlSessionFactory对象
3、获取SqlSession对象,执行Sql语句
4、释放资源
Mapper
使用Mapper代理方式完成入门案例
1、定义与Sql映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放置在同一目录下
2、设置SQL映射文件的namespace属性为Mapper接口全限定名
3、在Mapper接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致
4、编码
1、通过SqlSession的getMapper方法获取Mapper接口的代理对象
2、调用对应方法完成sql的执行
细节:如果mapper接口名称和Sql映射文件名称相同,并在同一目录下,则可以使用包扫描的方式简化SQL映射文件的加载
运用方法
查询-查询所有数据
1、编写接口方法:Mapper接口
参数:无
结果:List<Brand>
2、编写SQL语句:SQL映射文件
3、执行方法,测试
查询-查看详情
1、编写接口方法:Mapper接口 Brand selectById(int id);
参数:id
结果:Brand
2、编写SQL语句:SQL映射文件
<select id="selectById" parameterType="int" resultType="brand"
select*from tb_brand where id=#{id};
</select>
参数占位符:
1、#{}:将其替换成?为了防止SQL注入
2、${}:拼SQL,会存在SQL注入问题
3、使用时机
参数传递的时候:用#{}
表名或列名不固定的情况下:用${}
特殊字符处理:
1、转义字符:<;<
2、CDATA区:<![CDATA[
<
]]>
3、执行方法,测试
查询-条件查询
多条件查询
1、编写接口方法:Mapper接口
参数:所有查询条件
结果:List<Brand>
List<Brand> selectByCondition(@Param("status")int stastus,@Param("companyName")String companyName,@Param("brandName")String brandName);
List<Brand>selectByCondition(Brand brand);
List<Brand>selectBycondition(Map map);
2、编写SQL语句:SQL映射文件
<select id="selectByCondition" resultMap="brandResultMap">
select*from tb_brand where status=#{status}
and company_name like#{companyName}
and brand_name like#{brandName}
</select>
3、执行方法,测试
查询-多条件-动态条件查询
SQL语句会随着用户的输入或外部条件的变化而变化,我们称之为动态SQL
<select id="selectByCondition"resultMap="brandResultMap">
select * from tb_brand where
status =#{statsus}
and company_name like #{companyName}
and brand_name like #{brandName}
</select>
Mybatis 对动态SQL有很强大的支撑:
if
完成条件判断的
test里面写逻辑表达式
问题:如果第一个值不存在,则where后面直接跟上了and
解决办法,在where后面加上一个恒等式,再给每个值加上一个and
使用<where></where>标签
choose(when,otherwise)
trim(where,set)
foreach
查询-单条件-动态条件查询
从多条件中选择一个
choose(when,otherwise):选择,类似于Java中的switch语句
<select id="selectByConditionSingle" resultMap="brandResultMap">
select * from tb_brand
where
<choose>
<when test="status !=null">
status=#{status}
</when>
<when test="companyName!=null and companyName!="">
company_name like#{companyName}
</when>
<when test="brandName!=null and brandName!="">
brand_name like #{brandName}
</when>
<otherwise><!--类似于default-->
1=1
</otherwise>
</choose>
</select>
添加
1、编写接口方法:Mapper接口 void add(Brand brand)
参数:除了id之外的所有数据
结果:void
2、编写SQL语句:SQL映射文件
<insert id="add">
insert into tb_brand(brand_name,company_name,ordered,description,status)
values(#{brandName},#companyName},#{ordered},#{status});
</insert>
3、执行方法,测试
Mybatis事务:
openSession():默认开启事务,进行增删改操作后需要使用sqlSession.commit();手动提交事务
openSession(true):可以设置为自动提交事务(关闭事务)
添加-主键返回
在数据添加成功后,需要获取插入数据库数据的主键
比如:添加订单和订单项
1、添加订单
2、添加订单项,订单项中需要设置所属订单的id
<insert id="addOrder"useGenaratedKeys="true"keyProperty="id">
insert into tb_order(payment,payment_type,status)
values(#{payment},#{paymentType},#{status});
</insert>
<insert id="addOrderItem">
insert into tb_order_item(goods_name,goods_price,count,order_id)
values(#{goodsName},#{goodsPrice},#{count},#{orderId});
</insert>
修改-修改全部字段
1、编写接口方法:Mapper接口
参数:所有数据
结果:void
void update(Brand brand);
2、编写SQL语句:SQL映射文件
<updata id="updata">
updata tb_brand
set brand_name=#{brandName},
company_name=#{companyName},
ordered=#{ordered}
description=#{description}
status=#{status}
where id=#{id};
</updata>
3、执行方法,测试
修改-修改动态字段
1、编写接口方法:Mapper接口
参数:部分参数,封装到对象中
结果:void
2、编写SQL语句:SQL映射文件
<updata id="updata">
updata tb_brand
<set>
<if test="brandName!=null and brandName!="">
brand_name=#{brandName},
</if>
<if test="companyName!=null and companyName!="">
company_name=#{companyName}
</if>
<if test="ordered!=null">
ordered=#{ordered}
</if>
<if test="description!=null and description!="">
description=#{description}
</if>
<if test="status!=null">
status=#{status},
</if>
</set>
where id=#{id}
</updata>
3、执行方法,测试
删除-删除一个
1、编写接口方法:Mapper接口
参数:id
结果:void
void deleteById(int id);
2、编写SQL语句:SQL映射文件
<delete id="deleteById">
delete from tb_brand where id=#{id}
</delete>
3、执行方法,测试
批量删除
1、编写接口方法:Mapper接口
参数:id数组
结果:void
void deleteByIds(@Param("ids")int[]ids);
2、编写SQL语句:SQL映射文件
<delete id="deleteByIds">
delete from tb_brand
where id in(?,?,?)
</delete>
<delete id="deleteByIds">
delete from tb_brand
where id in
<foreach collection="ids" item="id" separator=",",open="("colse=")">#{id}
</foreach>
</delete>
3、执行方法,测试
Mybatis接口方法中可接受各种各样的参数,Mybatis底层对这些参数进行不同的封装处理
单个参数:
1、POJO类型:直接使用,属性名和参数占位符名称一致
2、Map类型:直接使用,键名和参数占位符一致
3、Collection:
4:List:
5:Array:
6:其他类型:直接使用
多个参数:封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
User select(@Param("username")String username,@Param("password")String password);
Mybatis提供了ParamNameResolver类来进行参数封装
注解完成增删改查
使用注解开发会比配置文件开发更加方便
@Select("select *from tb_user where id=#{id}
public User selectById(int id);
查询:@Select
添加:@Insert
修改:@Updata
删除:@Delete
提示:注解完成简单功能
配置文件完成复杂功能
总结
有点杂乱,如果要读的话建议还是学完再来,这样能把知识连贯一下