15-2.1 面试核心部分要点(基础部分给新手看的,祝莘莘学子早日学业有成) --不要害怕Java难,这两章掌握了,Java基础就掌握了

数据库

关系型数据库、非关系型数据库
底层以二维表的形式保存数据的库就是关系型数据库
数据库服务器就是一个软件如: MySQL,将数据库软件安装在电脑上,当前电脑就是一个数据库服务器。
一个数据库服务器中可以创建多个数据库(dataBases),每一个数据库都是一个单独的仓库。
mysql数据库命令及sql常用语句,详见15-2.2
1、连接mysql服务器:

mysql -uroot -p密码   

**-u:**后面的root是用户名,这里使用的是超级管理员root;
**-p:(小写的p)**后面的root是密码,这是在安装MySQL时就已经指定的密码;
2、连接mysql服务器并指定IP和端口:

mysql -uroot -proot -h127.0.0.1 -P3306
mysql -uroot -p -h127.0.0.1 -P3306

**-h:**后面给出的127.0.0.1是服务器主机名或ip地址,可以省略的,默认连接本机;
**-P:(大写的P)**后面的3306是连接端口,可以省略,默认连接3306端口;
3、退出客户端命令:quit或exit或 \q
在cmd中连接mysql服务器之后,在书写SQL语句时,可以通过 \c 取消当前语句的执行。

//在select之后、列名之前,使用DISTINCT 剔除重复的记录
select distinct dept,job from emp;

JDBC --Java 数据库连接技术

创建类并实现JDBC程序(六个步骤)

public static void main(String[] args) throws Exception {
    //1.注册数据库驱动
    Class.forName("com.mysql.jdbc.Driver");
    //2.获取数据库连接
    Connection conn = DriverManager.getConnection(
        "jdbc:mysql://localhost:3306/jt_db?characterEncoding=utf-8",
        "root", "root");
    //3.获取传输器
    Statement stat = conn.createStatement();
    //4.发送SQL到服务器执行并返回执行结果
    String sql = "select * from account";
    ResultSet rs = stat.executeQuery( sql );  //executeUpdate(String sql)发送更新(增加、删除、修改)类型的sql语句
    //5.处理结果
    while( rs.next() ) {  //遍历数据行的方法next() – 使指向数据行的箭头向下移动一行,并返回一个布尔类型的结果
        int id = rs.getInt("id");
        String name = rs.getString("name");
        double money = rs.getDouble("money");
        System.out.println(id+" : "+name+" : "+money);
    }
    //6.释放资源
    rs.close();
    stat.close();
    conn.close();
    System.out.println("TestJdbc.main()....");
}
PreparedStatement相对于Statement传输器对象效率更高且数据更安全 --防止sql注入攻击(另一种方式正则表达式对参数校验也可以)
private static void login(String user, String pwd) {
	Connection conn = null;
	PreparedStatement ps = null;
	ResultSet rs = null;
	try {
		//1.注册驱动并获取连接
		conn = JdbcUtil.getConn();
		//2.获取传输器,执行sql并返回执行结果
		String sql = "select * from user where username=? and password=?";
		ps = conn.prepareStatement( sql );  //获取传输器时将sql骨架传入进去了,而statement是获取传输器后,再执行sql时传入整条组合好的sql语句
		//设置SQL语句中的参数
		ps.setString( 1 , user );
		ps.setString( 2 , pwd );
		//执行SQL语句
		rs = ps.executeQuery();//这里不要再传输SQL语句	
		//3.处理结果
		if( rs.next() ) { //有数据 -- 用户名密码都正确
			System.out.println("恭喜您登录成功!");
		}else { //没数据 -- 用户名或密码不正确
			System.out.println("登录失败, 用户名或密码不正确!");
		}
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		//4.释放资源
		JdbcUtil.close(conn, ps, rs);
	}
}
连接池

池:指内存中的一片空间(容器,比如数组、集合)–常量池/线程池/连接池
所有的连接池都要实现一个接口——DataSource(数据源),因此连接池也被叫做数据源

C3P0连接池

1 导入c3p0的jar包 --官网下载即可放入项目的一个文件夹目录即可
2 创建数据库连接池(对象)

ComboPooledDataSource cpds = new ComboPooledDataSource();  --这一步连接池里还没有连接 --经过配置连接信息后才有

3 设置连接数据库的基本信息 --将连接参数提取到properties文件中(推荐)
在类目录下(开发时可以放在src或者类似的源码目录下),添加一个c3p0.properties文件,配置内容如下

c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcUrl=jdbc:mysql:///jt_db?characterEncoding=utf-8
c3p0.user=root
c3p0.password=root

这种方式由于是c3p0到指定的位置下寻找指定名称的properties文件,所以文件的位置必须是放在src或其他源码根目录下,文件名必须是c3p0.properties。
另一种推荐方式
将连接参数提取到xml文件中(推荐)
文件必须放在src(源码根目录)目录下 !
文件名必须叫做 c3p0-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql:///jt_db?characterEncoding=utf-8</property>
        <property name="user">root</property>
        <property name="password">root</property>
    </default-config>
</c3p0-config>

这种方式由于是c3p0到指定的位置下寻找指定名称的xml文件,所以文件的位置必须是放在src或其他源码根目录下,文件名必须是c3p0-config.xml。
4 从连接池中获取一个连接对象并进行使用

Connection conn = pool.getConnection();

5 用完连接后将连接还回连接池中

JdbcUtil.close(conn, ps, rs);
//conn.close()
/* 如果是自己创建的连接对象,这个连接对象没有经过任何的改动,调用
* conn.close方法,是将连接对象关闭
* 如果是从连接池中获取的连接对象,该连接对象在返回时就已经被连接池
* 改造了,将连接对象的close方法改为了还连接到连接池中
*/
切换新的工作空间,设置工作空间编码为utf-8

在这里插入图片描述
若使用JSP就设置 --设置JSP文件的编码为utf-8
在这里插入图片描述

最快乐的前端开发HTML、CSS

HTML: 用于开发网页的一门技术 --超文本标记语言(标记:也叫标签、元素、节点等,就是用尖括号(<>)括起来的一组内容) --使用HTML开发的网页文件由浏览器负责解析并显示,浏览器就是一个html解析器
CSS: 层叠样式表 , 用于修饰、渲染网页的一门技术
1 html标签
自闭标签

<br/> <hr/> <input/> <img/> <link/>等
 写全应该是 --<img></img>

其他常用标签

1 图像标签和script脚本都用src  --jsonP底层可以使用的
<!-- 
	./: 表示当前目录(当前文件所在的目录),由于当前html在WebContent目录下
	因此 ./叫表示WebContent目录, 另外 ./ 可以省略!
	../: 表示当前目录的上一级目录里(也就是当前目录的父目录)
	../../: 表示当前目录的上一级目录的上一级目录(也就是当前目录的父目录的父目录)
 -->
<img src="./imgs/meinv.jpg" width="50%"/>
2 超链接标签  --使用href
<!-- 跳转到本地的一个网页 -->
<a href="01-第一个网页.html">01-第一个网页</a>
<a href="http://www.baidu.com">百度一下,你就不知道</a>
<a target="_blank" href="http://www.tmooc.cn">
	<img alt="tmooc" src="imgs/tmooc.png" />
</a>
3 表单标签
<form action="url地址" method="提交方式"></form>
<!--其中action属性用于指定表单的提交地址-->
  表单里面的表单项标签  --表单项上必须添加name属性才能向服务器提交数据
  # input元素  --通过value属性为单选框或复选框设置提交的值(如果不设置默认值都是on)
<input type="text" name="username"/>
<input type="password" name="pwd"/>
<input type="radio" name="gender" value="male"/><input type="checkbox"  checked="checked" name="like"/>
<input type="button" value="换一张"/>  --普通按钮本身没有功能,但我们可以通过js为按钮添加功能或添加行为
<input type="submit" value="提交/注册/登录"/>  --提交按钮(比如:提交/注册/登录)
  ## select、option下拉选项标签
  <select name="city">
  <!--如果某一个选项被选中,该选项上添加了value属性,在提交表单时,将会提交value属性的值。没有添加value属性,在提交表单时,将会提交标签中的内容-->
    <option value="beijing">北京</option>
    <option value="shanghai">上海</option>
    <option selected="selected">广州</option>
    <option>深圳</option>
  </select>
  ### textarea多行文本输入区域
  <textarea name="description" cols="30" rows="5" placeholder="请输入描述信息..."></textarea>

2 html属性
标签上声明属性(属性不能独立存在,必须声明在开始标签上 – 属性名 = 属性值 单引号或双引号都行,可以声明多个属性,多个属性之间用空格分隔)

<div id="d1" class="c1" style="color:red;">这是一个div元素</div>

网页中的空格:可以使用&nbsp;&emsp;做空格
属性设置可以放在style标签或单独的脚本文件中

<style>
    /* style标签内只能书写css注释和css代码 */
    table{
        border:*2px solid red; /* 为表格添加边框 */
        border-collapse: collapse; /* 设置边框合并 */
        background-color: pink; /* 为表格设置背景颜色 */
        width: 70%; /* 为表格设置宽度 */
        /* margin-left: 15%; */
        /* 设置表格的左外边距和右外边距自适应(保证两者始终相等) */
        margin-left: auto;
        margin-right: auto;
    }
    td,th{
        border:2px solid red; /* 为单元格添加边框 */
        border-collapse: *collapse*; /* 设置边框合并 */
        padding: 5px; /* 设置单元格边框和内容的距离(内边距) */
    }
    h1{
        /* border: 2px solid blue; */
        text-align: *center*; /* 设置元素中的内容水平居中 */
    }
</style>
HTML中引入CSS

通过style标签引入css

<head>
<meta charset="utf-8">
<style type="text/css">
	/* ****** CSS样式 ****** */
	span{ /* 为当前html中的所有span标签设置样式 */
		border:2px solid green;
		font-size:30px;
		font-weight:bolder; /* bold/bolder */
	}
</style>
</head>

通过link链接引入外部的css文件

<link rel="stylesheet"  href="demo.css"  />

demo.css文件

@charset "UTF-8";
p{
	border: 2px solid blue;
	color: red;
	font-family: "华文琥珀";
	text-indent: 50px;
}
CSS选择器

1 标签名选择器

span{
	background-color:#efbdef; 
	font-size: 22px;
	font-weight: bolder;
}

2 class选择器
.class值{ css样式… }
3 id选择器
#id值{ css样式 }
4 后代选择器

p span{ /* 匹配所有p元素内部的所有span元素 */
	font-size:18px;
	color: red;
	background: pink;
}

5 属性选择器
选择器[属性条件]{ css样式 }

input[type='text']{
	background: #FF7CCC;
	font-size: 22px;
	text-indent: 15px;
}
input[type='text'][name='email']{ 
	background : yellow;
}

常用属性总结

文本属性

1 text-align:设置元素内的文本水平对齐方式,其常用取值为:
left: 默认值。左对齐
right: 右对齐
center: 居中对齐
justify: 两端对齐
2 text-decoration:设置文本的下划线样式,其常用取值为:
underline: 有下划线
none: 没有下划线
3 text-indent:设置文本首行缩进,单位: 像素/百分比
4 letter-spacing :设置字符间隔/间距,其常用取值为:
normal
像素值
5、text-shadow:设置字体阴影,其取值为:
像素值 像素值 像素值 颜色值
第一个值为阴影水平位移,第二个值为阴影垂直位移,第三个值为阴影扩散值,第四个值为阴影颜色

字体属性

font-size:设置字体大小
font-weight:设置字体粗细 normal、bold、bolder 100/200/300…/900
font-family:设置字体,比如微软雅黑、黑体、楷体等
color:设置字体颜色

背景属性

background-color:设置背景颜色
background-image:设置背景图片,url(‘图片的路径’);
background-repeat:设置或检索对象的背景图片是否及如何排列,常用取值:
repeat(默认值,重复排列)
repeat-x(横向重复排列,但纵向不重复)
repaet-y(纵向重复排列,但横向不重复)
no-repeat(不重复)
background-position:设置或检索对象的背景图片位置
background: 背景颜色 背景图片 背景图片是否重复 背景图片的位置

边框(border)

border:2px solid red; – 设置元素的边框(可以同时设置边框的宽度、样式、颜色)
border属性可以拆分为如下设置:
border-width: 2px; – 设置元素边框的宽度
border-style: solid; – 设置元素边框的样式
border-color: red; – 设置元素边框的颜色
其中border-width、border-style、border-color也可以按照上右下左方向进行拆分,以border-width为例:
border-top-width: 2px; – 设置上边框的宽度
border-left-width: 2px; – 设置左边框的宽度
border-right-width: 2px; – 设置右边框的宽度
border-bottom-width: 2px; – 设置下边框的宽度

其他属性

width:设置元素的宽度
height:设置元素的高
margin: 设置元素的外边距

颜色设置

red #FF0000 rgb(255,0,0)

display属性 --用来设置元素的类型

block:块级元素的默认值 默认情况下独占一行 可以设置宽高
inline:行内元素的默认值 默认情况下多个行内元素可以处在同一行 一般不能设置宽高
inline-block:行内块元素 多个元素既可以显示在同一行, 也可以设置宽和高
none:表示隐藏元素

JavaScript --JS(负责实现网页中的动画效果/表单校验等功能)

特点:
(1)JS是一门直译式的语言(边解释边执行,没有编译的过程)
(2)JS是一门基于对象的语言(JS中没有类的概念)
(3)JS是一门弱类型的语言(Java:强类型)

在java中: 变量一旦声明, 就属于固定的数据类型, 不能被改变
String s = "abc";
在JS中: 变量是不区分类型的, 可以指向任意的数据类型
var s = 100;
s = "abc";
s = true;
s = [];
s = function(){}
HTML书写JS的方式

在script标签内部可以书写JS代码
通过script标签引入外部的JS文件

<script src="demo.js"></script>

也可以直接在元素上书写JS代码 --如点击事件等

<input type="button" value="点我~" onclick="alert('真敢点啊!')"/>
<input type="button" value="别点我"  onclick="console.log( new Date() )"/>

JavaScript语法

1 数据类型

(1)数值类型(number) --在JS中,所有的数值在底层都是浮点型,但是在处理和显示的过程中会自动的和整型进行转换
(2)字符串类型(string) --在JS中,字符串常量可以使用单引号或者使用双引号引起来
JS中字符串类型有对应的包装对象(String),在需要时会自动的和包装对象进行转换

var s1 = "Hello JS"; //基本数据类型, string
console.log( typeof s1 ); //string
var s2 = new String("Hello JS"); //复杂数据类型, object
console.log( typeof s2 ); //object
//不管是基本数据类型s1, 还是对象类型s2, 都可以当作对象来用
console.log( s1.valueOf() ); //s1是基本数据类型, 会转成对象, 调用valueOf函数
console.log( s2.valueOf() );

(3)布尔类型(boolean)
(4)undefined类型 --undefined类型的值只有一个,就是undefined,表示变量未定义,指声明了变量,但没有为变量赋值,该变量的值就是undefined。
(5)null类型 --null类型的值也只有一个,就是null,表示空值
注意:null和undefined类型的变量是不能调用函数或属性的,会抛异常!

复杂数据类型

主要指对象(JS的内置对象、自定义的对象、函数、数组)

变量声明 --JS中是通过var关键字声明变量,声明的变量是不区分类型,可以指向任意的数据

JS是严格区分大小写的!
JS运算符,JS语句(if分支,for循环等)与java基本类似
代码示例:

//1.接收用户输入的数值和运算符, 中间用空格分隔
var str = prompt("请输入数值1、运算符、数值2,中间用空格分隔:"); //"10 + 5"
//2.对用户输入的内容进行切割(以空格作为分隔符切割)
var arr = str.split(" "); // ["10", "+", "5"]
var num1 = arr[0] - 0;  //将字符串转为数字,底层自动转了
var opt = arr[1];
var num2 = arr[2] - 0;
//3.通过switch分支实现计算器
switch( opt ){
	case "+":
		alert( "两个数的和为: "+( num1+num2 ) );
		break;
	case "-":
		alert( "两个数的差为: "+( num1-num2 ) );
		break;
	case "*":
		alert( "两个数的乘积为: "+( num1*num2 ) );
		break;
	case "/":
		alert( "两个数的商为: "+( num1/num2 ) );
		break;
	default:
		alert( "您输入的运算符有误, 请重新输入!" );
}
JS数组

Array 对象用于在单个的变量中存储多个值
JS数组的声明方式:
//声明一个空数组,长度为零
var arr1 = [];
var arr3 = new Array(); // java中int[] a = new int[5]; int[] a =new int[]{1,2,3,4,5}; int[] a ={1,2,3,4,5,6,7,8};
//声明一个数组,并为数组设置初始值
var arr2 = [“Hello”, 111, false, new Object() ];
var arr4 = new Array(“Hello”, 111, false, new Object());
数组中的细节问题:
(1)JS中的数组可以存储任意类型的数据
(2)JS中的数组长度是可以被任意改变的

var arr1 = [];
console.log("此处数组的长度为: "+arr1.length ); // 0
arr1.length = 5;
console.log("此处数组的长度为: "+arr1.length ); // 5
arr1[9] = "a";
console.log("此处数组的长度为: "+arr1.length ); // 10
JS函数 --就是包裹在花括号中的代码块,前面使用了关键词 function

JS中声明函数的方式为:
function 函数名称([参数列表]){
函数体
}
或者:
var 变量名/函数名 = function([参数列表]){
函数体
}
示例:

function fn(x,y){
    var arr = [];
    for(var i=x,j=0;i<y;i++){
        if(i%3==0){
        	arr[j] = i;
        	j++;
    	}
    }
    return arr;   //js函数中没有返回值类型,可以任意返回..
}
var arr = fn(1,100);
for(var i=0;i<arr.length;i++){
	document.write(arr[i]+" ");  //document文档对象
}

DOM操作 --Document Object Model,文档对象模型,其实就是JS专门为访问html元素提供的一套API

电灯开关

var flag = "off"; //标记灯的状态, off表示灯是关闭的!
function changeImg(){
	//获取img元素,返回的是一个JS对象
	var oImg = document.getElementById("img1");
	if( flag == "off" ){ //表示灯之前是关闭状态,点击之后则需要打开
		oImg.src = "imgs/on.gif"; //灯打开了
		flag = "on"; //更新灯的状态为on,表示灯打开了
	}else{ //on,表示灯之前是打开状态,点击之后则需要关闭
		oImg.src = "imgs/off.gif"; //灯关闭了
		flag = "off"; //更新灯的状态为off,表示灯关闭了
	}
}

增删改元素

function addNode(){
    //1.创建一个新的div元素(返回的是一个JS对象, 表示新创建的div元素)
    var newDivObj = document.createElement("div"); // \<div\>\</div\>
    //var dateStr = new Date().toLocaleString();
    //newDivObj.innerHTML = dateStr;
    newDivObj.innerHTML = "我是新来的....";
    //2.获取body元素(body是父元素)
    var bodyObj = document.body;
    //var parent = newDivObj .parentNode;
    //3.通过父元素(body)添加子元素(newDivObj)
    bodyObj.appendChild( newDivObj );
    //parent.removeChild( newDivObj );
}

网页换肤

/** 练习1:执行下面的函数,切换字体大小 */
function resize( selector ){
	var div = document.getElementById("newstext");
	//将id为newstext元素的class属性值设置为 selector
	div.className = selector;
}
//定义数组,存放不同的皮肤(css文件的路径)
var styleArr = ["css/red.css", "css/green.css", "css/blue.css"];
var index = 0;
function changeStyle(){
	//获取head中的link标签(id=link)
	var link = document.getElementById("link");
	//将link标签的href属性值指向css文件的路径
	link.href = styleArr[index];
	index++;
	if( index == styleArr.length ){ //如果下标等于数组长度
		index = 0; //则将下标重置为0
	}
}

js常用API总结

document.getElementById( id值 )
document.getElementsByTagName( 元素名/标签名 ) --返回的是一个数组
document.body – 获取当前文档中的body元素
元素名.parentNode – 获取当前元素的父元素。element表示当前元素
document.createElement( 元素名称 )
parent.appendChild( child )
parent.removeChild( child )
元素名.innerHTML --获取当前元素的html内容(从开始标签到结束标签之间的所有内容),还可以设置当前元素的html内容(如果元素内部有内容,将会覆盖原有内容)

jQuery – JS查询(JS函数库)

div{ css属性... }  //css中选择器
jQuery("#div1")
$(".s1")
$("div")

$("div").css("border", "2px solid red");

jQuery引入

jQuery的函数库文件就是一个普通的JS文件,引入jQuery和引入JS文件的方式一样。

<!-- 在使用jQuery之前,必须先引入jQuery的函数库文件 -->
<script src="js/jquery-1.8.3.js"></script>

在引入jQuery函数库文件时,如果文件引入路径错误,则会导致文件引入失败

文档就绪事件函数

将获取元素的代码放在文档就绪事件函数中,文档就绪事件函数会在浏览器加载完所有的html元素后(也就是加载完最后一个html元素时)立即执行。

<script>
	$(function(){
		var h1 = document.getElementById( "demo" );
		alert( h1.innerHTML );
	});
</script>
<script>
	window.onload = function(){
		//在浏览器加载完整个html网页后立即执行  --这是JS也为我们提供的文档就绪事件函数
	}
</script>

jQuery选择器(重点)

基本选择器

(1)元素名选择器
$("div") -- 选中所有的div元素
$("span") -- 选中所有的span元素
(2)class/类选择器
$(".s1") -- 选中所有class值为s1的元素(class值为s1的元素可能是任何元素)
$("span.s1") -- 选中所有class值为s1的span元素
(3)id选择器
$("#one") -- 选中id为one的元素
(4)多元素选择器
$("div,span,.s1,#one") -- 选中所有的div元素,以及所有的span元素,以及所有class值为s1的元素,以及id为one的元素

层级选择器

$("div span") -- 选中所有div内部的所有span元素
$("#two+span") -- 选中id为two的元素后面紧邻的span兄弟元素
$("#two").next("span") -- 选中id为two的元素后面紧邻的span兄弟元素
$("#two").prev("span") -- 选中id为two的元素前面紧邻的span兄弟元素
$("#two~span") -- 选中id为two的元素后面所有的span兄弟元素
$("#two").nextAll("span") -- 选中id为two的元素后面所有的span兄弟元素
$("#two").prevAll("span") -- 选中id为two的元素前面所有的span兄弟元素
$("#two").siblings("span") -- 选中id为two的元素前、后所有的span兄弟元素

基本过滤选择器

(1) 选中第一个div元素
$("div:first")
$("div:eq(0)")
$("div").eq(0)
(2) 选中最后一个div元素
$("div:last")
$("div:eq(-1)")
$("div").eq(-1)
(3) 选中第n+1个div元素(n从零开始)
$("div:eq(n)")
$("div").eq(n)

代码示例:

//创建指定行和列的表格
function createTable3(){
	//获取用户输入的行数和列数(js方式)
	//var rows = document.getElementById("rows").value;
	//var cols = document.getElementById("cols").value;
	var rows = $("#rows").val();
	var cols = $("#cols").val();
	console.log(rows+" : "+cols);
	//1.创建一个table元素
	var $tab = $("<table></table>");  //js创建document.createElement("table")
	for(var j=0;j<rows;j++){ //外层循环:控制行数
		//2.创建一个tr元素
		var $tr = $("<tr></tr>");
		for(var i=0;i<cols;i++){ //内层循环:控制列数
			//3.创建一个td元素, 并为td添加内容
			var $td = $("<td></td>");
			$td.html("Hello TD~~");
			//4.将td添加到tr元素内部
			$tr.append( $td );
		}
		//5.将tr添加到table元素内部
		$tab.append( $tr );
	}
	//6.将table添加到body元素内部
	$("body").append( $tab ); 
}

仿QQ好友列表

/** 通过jQuery实现仿QQ列表好友列表 */
function openDiv(thisobj){ //thisobj是一个js对象 --转成--> jQuery对象
	//先将其他三个分组关闭( 将其他三个分组内的div设置为隐藏 )
	$("table span").not(thisobj).next("div").hide(); //css("display", "none")
	//根据被点击的分组找到分组内的好友列表, 切换好友列表的展示状态
	$(thisobj).next("div").toggle(); //如果元素显示则切换为隐藏, 如果隐藏则切换为显示
}

模拟员工信息管理系统

function addEmp(){
	//1.获取要添加的员工信息(id, name, email, salary)
	var id = $("#box1 input[name='id']").val().trim();
	var name = $("#box1 input[name='name']").val().trim();
	var email = $("#box1 input[name='email']").val().trim();
	var salary = $("#box1 input[name='salary']").val().trim();
	console.log(id+" : "+name+" : "+email+" : "+salary);	
	//2.校验员工信息
	//2.1.添加的员工信息不能为空!
	if( id == "" || name == "" || email == "" || salary == "" ){
		alert( "添加的员工信息不能为空!" );
		return;
	}	
	//2.2.添加的员工id不能重复! (id=3)
	//获取所有的tr元素, 并遍历所有的tr元素
	var flag = false; //false表示id是不存在的!!!
	$("table tr").each(function(){
		// this --转换为jQuery对象--> $( this )  //this(JS对象)表示当前被遍历的元素 
		var _id = $(this).find("td:eq(1)").text();
		//拿着用户输入的id和当前员工的id进行比较
		if( id == _id ){ //只要有一个相等,就说明id已存在,则停止添加
			alert("您输入的员工ID已存在, 请重新添加!");
			flag = true; //true表示id已存在!!
			//return; 放在这里的return不能终止程序的执行
		}
	});
	if( flag ){ //true表示id已存在!!
		return;
	}
	//3.将员工信息添加到页面上(添加到table中)
	//>>创建一个tr元素
	var $tr = $("<tr></tr>");
	//>>创建5个td元素,并将员工信息添加到td中
	var $td1 = $("<td><input type='checkbox'/></td>"); //复选框
	var $td2 = $("<td>"+id+"</td>"); //ID
	var $td3 = $("<td>"+name+"</td>"); //name
	var $td4 = $("<td>"+email+"</td>"); //email
	var $td5 = $("<td>"+salary+"</td>"); //email
	//>>将td元素添加到tr中
	$tr.append( $td1 ).append( $td2 ).append( $td3 ).append( $td4 ).append( $td5 );		
	//>>将tr元素添加到table中
	$("table").append( $tr );
}

//删除员工信息
function delEmp(){
	//1.获取所选中员工所在的tr行 (获取所有被选中的复选框)
	//$("input:checked").parents("tr").remove(); //会连接表头一起删除
	$("input:checked").parent("td").parent("tr").remove();
}

//实现全选或全不选
function checkAll(){
	//1.获取全选复选框的选中状态( 选中(true)?  没选中(false)? )
	var isCheck = $("#all").prop("checked"); //true|false
	//2.获取所有普通复选框, 将全选框的是否选中状态设置给所有普通复选框
	$("input[type='checkbox'][id!='all']").prop("checked",isCheck);
}

prop()一个参数时为返回属性的值,两个参数时为设置属性的值 --属性为标签元素里面的属性

jQuery总结 --可以直接只看总结即可

html元素操作

1 创建元素

$("<div></div>") -- 创建一个div元素,返回的是一个jQuery对象,表示创建的div元素
$("<div>xxxx</div>") -- 创建一个包含内容的div元素,返回的是一个jQuery对象,表示创建的div元素

2 添加子元素

$parent.append( $child ) -- 父元素调用方法添加子元素
$("body").append( "<div>我是新来的...</div>" ); -- 往body元素内部追加一个div子元素

3 删除元素

$("div").remove() -- 删除所有的div元素

// JS删除所有div元素:
//获取所有的div元素(返回的是所有div组成的数组)
var divArr = document.getElementsByTagName("div"); //div数组
//遍历div数组,依次删除每一个div元素
var len = divArr.length;
for(var i=0;i<len;i++){
    //通过当前元素的父元素删除当前元素(始终删除第一个)
    divArr[0].parentNode.removeChild( divArr[0] );
}

4 替换元素

$("div").replaceWith("<p>我是来替换的…</p>")

html元素内容和值(如input 中text文本框内的输入值/按钮就是value值)的操作

1 html()函数 (类似于js中的innerHTML属性)
– 用于获取或设置元素的内容,比如为div、span、p、h1~h6、table、tr、td、form等元素设置内容

$("div").html() -- 获取所有div中的第一个div的里的所有内容包括里面的文本内容及其他元素标签等
$("div").html("xxxx") -- 为所有div设置内容

2 text()函数 (类似于js中的innerText属性,innerText在部分浏览器中不兼容)
– 用于获取或设置元素的文本内容

$("div").text() -- 获取所有div中的所有文本内容  --只获取文本内容其他的在该div里面包含的其他元素标签不获取
$("div").text("xxxx") -- 为所有div设置文本内容

3 val()函数 (类似于js中的value属性)
– 获取或设置表单项元素的value值(input/select/option/textarea)

$("input").val() -- 获取所有input元素中的第一个input元素的value值
$("input").val() -- 为所有的input元素设置value值

元素属性和css属性操作

1 prop()函数 – 用于获取或设置元素的属性值
在jQuery1.6版本之后才有这个函数,1.6之前版本的jQuery可以使用attr()函数

$("input[type='checkbox']").prop("checked")
// 获取input复选框的选中状态, 返回true表示复选框为选中状态,返回false表示复选框为取消选中状态
$("input[type='checkbox']").prop("checked", true)
// 设置所匹配的复选框元素为选中状态
$("#inp").prop("name"); //获取id为inp元素的name属性值, 返回useranme
$("#inp").prop("name","user"); //为id为inp的元素设置name属性值, name属性值就会变成user

2 css()函数 – 用于获取或设置元素的css属性值

$("#div1").css("width") -- 获取id为div1元素的宽度
$("#div1").css("width","200px") -- 设置id为div1元素的宽度为200px
$("#div1").css({
	"width" : "200px",
	"height" : "150px",
	"border" : "5px solid red",
	"background" : "pink"
}); // 为id为div1的元素设置宽度为200px、高度为150px、边框以及背景颜色等样式

其他函数

1 each() 函数

$(selector).each(function( index,element ){})
// each()函数可以遍历$(selector)选择器选中的所有元素(即每次都选择器选中的元素中获取一个元素,并执行function 函数)
// function中的index -- 表示遍历的元素的下标
// function中的element -- 表示当前正在遍历的元素(也可以通过this获取)

示例:

$("table tr").each(function(){
	//从当前行中获取第二个单元格的内容(当前行的id值)
	var tempId = $(this).find("td").eq(1).html();
	//拿着用户输入的id 和 每一行中的id值进行比较
	if( id == tempId ){
		alert("添加失败,id已存在!");
		flag = true; //id存在,更新flag的值,true表示已存在!
	}
});

2 show()/hide() 函数
show() – 设置元素由隐藏变为显示

$("div").show() -- 设置所有的div元素为显示

等价于:

$("div").css("display", "block");

hide() – 设置元素由显示变为隐藏

$("div").hide() -- 设置所有的div元素为隐藏

等价于:

$("div").css("display", "none")

3 toggle()/slideToggle()
toggle() – 切换元素的显示状态, 如果元素是显示的, 则切换为隐藏, 否则切换为显示
slidToggle() --切换元素的显示状态, 如果元素是显示的, 则切换为隐藏,否则切换为显示,切换为显示为下拉状态,隐藏为收缩状态。

为元素绑定点击事件

方式1(js版):

<script>
  function fn(){
    alert("input按钮被点击了...");
  }
</script>
<body>
	<input onclick="fn()" type="button" value="点我~!" />
	<input id="btn" type="button" value="点我~!" />
</body>
<!--第二种方式 -->
<script>
	window.onload = function(){
		var btn = document.getElementById("btn");
		btn.onclick = function(){
			alert("input按钮被点击了...");
		}
	}
</script>

方式3(jQuery版):

<script>
$(function(){
    //当点击btn按钮时,触发点击事件执行其中的函数
    $("#btn").click( function(){
        alert("input按钮被点击了...");
    });
});
</script>
<body>
	<input id="btn" type="button" value="点我~!" />
</body>

js对象和jQuery对象的互相转换
js对象 --转为jQuery对象 --> $(js对象)
jQuery对象 --转为js对象 -->jQuery对象[下标]

服务器

tomcat服务器的安装及应用

HTTP协议详解

HTTP请求
在这里插入图片描述
HTTP响应
在这里插入图片描述
状态码
200: 表示请求处理成功
302: 表示请求重定向(即需要再进一步请求才可以获取到相应的资源)
304/307: 表示通知浏览器使用缓存 --浏览器访问一次一般都会缓存,再次请求时服务器发送304–相当于告诉浏览器缓存未更新过,用你自己的缓存即可
404: 表示浏览器请求的资源不存在(浏览器的问题, 请求路径错误)
500: 表示服务器在处理请求的过程中抛出了异常。 --servlet程序抛异常…
响应实体内容 --就是浏览器所请求文件的内容。例如:浏览器向服务器请求一个hello.html文件,服务器会找到hello.html文件,将文件的内容作为响应实体发送给浏览器。
只有当使用表单(form),并且在表单上明确的通过method指定提交方式为POST时,请求方式才是POST提交,其他方式都是GET提交(AJAX除外)

Servlet --一门动态Web资源开发技术

Servlet本质上是一段Java程序,和之前的Java程序不同的是,Servlet程序无法独立运行,需要将Servlet程序放在服务器中(比如tomcat服务器),由服务器调用才可以执行。服务器端的Java程序
其***作用是对服务器接收过来的请求进行处理***(作用为处理请求)

开发Servlet程序的步骤

第一步:创建一个动态WEB项目,new Dynamic Web Project后写一个类src–new–servlet,实现一个Servlet接口或者继承Servlet接口的子类 --默认继承HttpServlet 重写doGet(),doPost()方法

Servlet接口
	|-- GenericServlet类(抽象类)
				|-- HttpServlet类

第二步: 在web应用的web.xml文件中配置Servlet程序对外访问的路径。
Eclipse在创建一个Servlet时,会在web.xml文件中生成Servlet配置,所以不需要我们手动配置
(注意:如果是复制Servlet类文件,但配置信息不会跟着复制,需要自己手动添加配置,否则复制的Servlet将无法访问!)

<servlet>
    <servlet-name>HelloServlet</servlet-name>
    <servlet-class>com.tedu.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>HelloServlet</servlet-name>
    <url-pattern>/HelloServlet</url-pattern>
</servlet-mapping>

1、在3.0以上版本的动态Web项目中创建一个Servlet–没有web.xml配置文件,使用注解配置

@WebServlet("/HelloServlet")
//@WebServlet(value={"/HelloServlet", "/hello01", "/hello02"})
//@WebServlet(urlPatterns={"/HelloServlet", "/hello01", "/hello02"})
public class HelloServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		PrintWriter out = response.getWriter();
		out.write( "Hello Servlet3.0.."+new Date() );
	}
}

@WebServlet("/HelloServlet")这个注解的作用就是配置当前Servlet的访问路径为/HelloServlet,完善doGet方法中的代码,直接运行Servlet。
可配置多个访问路径
可以将value属性替换为urlPattern属性

request和response介绍

request是代表HTTP请求信息的对象,response是代表HTTP响应信息的对象。
当浏览器发请求访问服务器中的某一个Servlet时,服务器将会调用Servlet中的service方法来处理请求。在调用service方法之前会创建出request和response对象
其中request对象中封装了浏览器发送给服务器的请求信息(请求行、请求头、请求实体等),response对象中将会封装服务器要发送给浏览器的响应信息(状态行、响应头、响应实体),在service方法执行完后,服务器再将response中的数据取出,按照HTTP协议的格式发送给浏览器。
每次浏览器访问服务器,服务器在调用service方法处理请求之前都会创建request和response对象。(即,服务器每次处理请求都会创建request和response对象)
在请求处理完,响应结束时,服务器会销毁request和response对象。

获取请求参数
(1)request.getParameter(String paramName) //返回值是一个字符串;
(2)request.getParameterValues(String paramName) //返回值是一个字符串数组
解决获取请求参数时的中文乱码问题
解决方法是:通知服务器在接收POST提交(默认iso8859-1)的参数时,使用utf-8编码来接收!

request.setCharacterEncoding("utf-8");

注意:这行代码不会影响GET提交,只对POST提交有效!

请求转发(forward)

请求转发是服务器内部资源的一种跳转方式
(1)转发是一次请求,一次响应
(2)请求转发前后,浏览器的地址栏地址不会发生变化
(3)请求转发前后的request对象是同一个
(4)请求转发前后的两个资源必须属于同一个Web应用,否则将无法进行转发

//request.getRequestDispatcher(url地址/转发到资源的地址).forward(req, res);
request.getRequestDispatcher("index.jsp").forward(request, response);

request在实现转发时,通过request.setAttribute方法和request.getAttribute方法带数据到目的地时,就是通过request对象中的map集合带数据,这个request对象上的map集合以及request对象所在的范围即称之为是一个域对象。
如果一个对象具备可以被访问的范围通过这个对象上的map集合可以在整个范围内实现数据的共享。这样的对象就叫做域对象

request.setAttribute(String attrName, Object attrValue);
request.getAttribute(String attrName);

request域对象所具备的三大特征:
**生命周期:**在服务器调用Servlet程序的service方法之前,会创建代表请求的request对象,在请求处理完,响应结束时,会销毁request对象。
**作用范围:**在一次请求范围内,都可以获取到同一个request对象。
**主要功能:**和请求转发配合使用,从Servlet带数据到JSP(带数据到目的地)
request对象的getParameter和getAttribute方法有什么区别?

  • getParameter()方法是用于获取(从浏览器发送过来的)请求参数的,请求参数不能设置,只能是浏览器发送给服务器,在服务器端再通过getParameter方法获取请求中的参数
  • getAttribute()方法是用于从request域中或者session域中获取域属性时用的,域属性得先存入到域中(即得先通过setAttribute方法将数据存入request域中),再通过getAttribute()方法从域中获取。
response对象 --代表HTTP响应信息的对象。

向客户端发送数据
PrintWriter out = response.getWriter();
由于服务器在通过response获取的流发送数据时,默认使用iso8859-1编码,而这个编码中没有中文字符,所以在通过response获取的流发送中文数据时,会出现乱码问题。
解决方法是:在响应数据之前,通知服务器使用utf-8发送数据。

/* 通知服务器在响应数据时,使用utf-8编码
 * 也能通知浏览器使用utf-8接收服务器发送的数据 */
response.setContentType( "text/html;charset=utf-8" );
PrintWriter out = response.getWriter();
out.write( "你好" );
实现重定向(redirect)

当浏览器向服务器发请求访问某一个资源A,资源A在响应时通知浏览器需要再进一步请求才能获取到对应的资源,浏览器再次发请求访问服务器中的资源B,最终由资源B响应浏览器要获取的资源,这个过程叫做重定向
重定向的特点:
(1)重定向是两次请求、两次响应
(2)重定向前后,浏览器的地址栏地址会发生变化
(3)重定向前后的request对象不是同一个
(4)重定向前后的两个资源可以是来自不同的web应用,甚至可以是来自不同的服务器。

response.sendRedirect(所重定向到资源的URL地址);
response.sendRedirect( "http://localhost/day10/index.jsp" );
response.sendRedirect( "/index.jsp" ); //错误路径
response.sendRedirect( "index.jsp" ); //正确路径

JSP、EL、JSTL

JSP(全称Java Server Pages)

JSP看起来像一个HTML,但和HTML不同的是,JSP中可以书写Java代码
JSP本质上是一个Servlet程序 --Servle本质上是java程序
Servlet是一段Java程序,适合处理业务逻辑(如判断注册名是否重复…),但是Servlet不适合向浏览器输出一个html网页。
html可以作为页面返回,但是html是一个静态Web资源,无法展示动态数据 - html+AJAX可以实现动态展示
而JSP也是页面的开发技术,也可以作为页面返回,并且JSP中可以书写Java代码,可以通过Java代码展示动态的数据。
因此,JSP的出现即解决了Servlet不适合输出页面的问题,也解决了HTML无法展示动态数据的问题!
JSP翻译引擎会将JSP翻译成一个Servlet程序,再编译成.class,然后Servlet程序再执行(JSP----> xxx.java----> xxx.class),执行的结果是向浏览器输出一个HTML网页

JSP语法

模版元素

模板元素是指写在JSP中的html内容

JSP表达式 --表达式中可以书写符合Java语法的代码,但是不能写Java语句(内部也不能写分号 ; )

<%= 常量、变量、表达式 %>

<%= "Hello JSP..." %>
<% String name = "林青霞"; %>  //这个是脚本片段
<%= name %>
<%= 100+123 %>
<%= Math.random() %>
JSP脚本片段 --直接写java语句即可与JSP表达式相比只是没有=

<% 若干Java语句 %>

JSP注释

<%-- JSP注释内容 --%>

JSP指令

<%@ 指令名称 若干属性声明… %>
指令的作用:用于指挥JSP解析引擎如何将一个JSP翻译成一个Servlet程序
1、page指令

<%@ page language="java"%>
<%@ page import="java.util.Date"%>
<%@ page pageEncoding="UTF-8"%>

2、taglib指令
用于引入JSTL标签库或者其他的自定义标签库

JSP标签技术 --EL表达式

1 获取常量、表达式、变量的值
${ 常量 / 表达式 / 变量 } --放在EL中的变量得先存入域中,才可以获取变量的值 --不能写带分号的函数,语句等
域对象:pageContext、request、session、application

${ "hello el" } 
hello el	<br/>
${ 100+123 }
${ 12*12 > 143 ? "yes" : "no" } <br/>
<% 
	String name = "马云";
	request.setAttribute( "name123" , name );
%>
${ name123 }

2 获取作用域中数组或集合中的元素
Servlet中的代码

String[] names = {"刘德华", "郭富城", "张学友", "黎明" };
request.setAttribute( "names", names );
request.getRequestDispatcher( "/02-el.jsp" ).forward(request, response);

JSP中的代码

${ names[0] } <%-- 刘德华 --%>
${ names[1] } <%-- 郭富城  --%>
${ names[2] } <%-- 张学友 --%>
${ names[3] } <%-- 黎明 --%>

3 获取作用域中map集合中的元素
Servlet中的代码:

Map map = new HashMap();
map.put( "name" , "尼古拉斯赵四" );
map.put( "age" ,  28 );
map.put( "addr", "中国" );
request.setAttribute( "map1", map );
request.getRequestDispatcher( "/02-el.jsp" ).forward(request, response);

JSP中的代码:

${ map1.name } <%-- 尼古拉斯赵四 --%>
${ map1.age } <%-- 28 --%>
${ map1.addr } <%-- 中国 --%>

4 获取作用域中JavaBean对象的属性值
Servlet中的代码:

User u1 = new User();
u1.setName( "刘德华" );
u1.setAge( 18 );
u1.setAddr( "中国香港" );
request.setAttribute( "user" , u1 );
request.getRequestDispatcher( "/02-el.jsp" ).forward(request, response);

JSP中的代码

<%-- 
${ user.getName() }
${ user.getAge() }
${ user.getAddr() } --%>
<hr/>
<%-- user.name 底层调用的仍然是 getName()方法--%>
${ user.name }
${ user.age }
${ user.addr }

JSTL标签库 --(JSP标准标签库)

在使用JSTL标签库的JSP中引入JSTL(taglib指令)

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
常用的标签 --标签里面的属性值都被引号包裹,包括EL表达式!!!

1 <c:set> </c:set> – 用于往域中添加属性,或者修改域中已有的属性值
(1)var – 指定存入作用域中的属性名称
(2)value – 指定存入作用域中属性的值
(3)scope – 指定将属性存入哪一个作用域中,默认值是page,表示pageContext域 --自小范围域找起,找到即不往后找了
可取值: a)page表示pageContext域 b)request表示request域 c)session表示session域 d)application表示ServletContext域

<%-- request.setAttribute("name", "张三"); --%>
<c:set var="name" value="张三" scope="request"/>
${ name }

2 <c:if></c:if> – 构造简单的 if…else…结构语句
test属性 – 指定一个布尔表达式,当表达式的结果为true时,将会执行(输出)c:if标签中的内容,如果表达式结果为false,将不会输出c:if标签中的内容

<!-- 根据成绩判断成绩所属的等级 -->
<c:set var="score" value="-35"/>
<c:if test="${ score>=80 and score<=100 }">您的成绩属于: 优秀!</c:if>
<c:if test="${ score>=60 and score<80 }">您的成绩属于: 中等!</c:if>
<c:if test="${ score>=0 and score<60 }">您的成绩属于: 不及格!</c:if>
<c:if test="${ score<0 or score>100 }">您的成绩有误!</c:if>

3 <c:forEach></c:forEach> – 对集合或数组等中元素进行循环遍历或者是执行指定次数的循环.

//(1) 遍历域中数组或集合中的元素
<%
	String[] name = {"王海涛","刘沛霞","陈子枢","齐雷"};
	request.setAttribute( "names", name );
%>
<c:forEach items="${ names }" var="name" varStatus="vs">
	${ vs.count }, ${ vs.first }, ${ vs.last }, ${ name } <br/>
</c:forEach>

//(2) 遍历域中map集合中的元素
<%
	Map<Object,Object> map = new HashMap<Object,Object>();
	map.put( "name" , "尼古拉斯.赵四" );
	map.put( "age" , 35 );
	map.put( "addr" , "中国" );
	request.setAttribute( "map1", map );
%>
<c:forEach items="${ map1 }" var="entry">
	${ entry } <br/>
</c:forEach>

//(3) 遍历0\~100之间的整数,将是3的倍数的数值输出到浏览器中
<c:forEach begin="1" end="100" var="i" step="1">
	${ i%3==0 ? i:""}
</c:forEach>
<c:forEach begin="1" end="100" var="i" step="1">
	<c:if test="${ i%3==0 }">
		${ i }
	</c:if>
</c:forEach>

c:forEach 标签属性总结:
(1)items: 指定需要遍历的集合或数组
(2)var: 指定用于接收遍历过程中的每一个元素
(3)begin: 指定循环从哪儿开始
(4)end: 指定循环到哪儿结束
(5)step: 指定循环时的步长, 默认值是1
(6)varStatus: 用于表示循环遍历状态信息的对象, 这个对象上有如下属性:
first属性: 表示当前遍历是否是第一次, 若是, 则返回true;
last属性: 表示当前遍历是否是最后一次, 若是, 则返回true;
count属性: 记录当前遍历是第几次

Maven

是一个项目管理工具,可以简化项目配置,统一项目结构
Maven的配置三点:
1 配置本地仓库
2 配置镜像
3 配置jdk版本

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
测试是否配置成功:window—> show view —> other中搜索"maven",点击下面的选框中的选项
在这里插入图片描述
配置完成之后直接new Maven Project项目即可
在这里插入图片描述
在这里插入图片描述
注意:当创建web工程时,即打war包,创建完成后pom.xml文件会报错,找不到web.xml文件
在这里插入图片描述
创建Servlet程序时,必须把tomcat加进来
在这里插入图片描述
在这里插入图片描述

重点:导入已有的Maven项目

1 自己创建maven项目
2 复制原文件的src目录到自己项目中
3 复制pom文件的依赖到自己pom文件中,一定不要整个pom文件直接复制会报错
依赖传递
依赖排除
如 A 依赖 B、S2.0,B 依赖C、S1.0,这样A就有了S1.0和S2.0两个依赖,这样某些情况下会造成冲突需要手动把B间接传递过来的依赖排除掉

<dependency>
  <groupId>org.testgroupId>
  <artifactId>B</artifactId>
  <version>1.0</version>
  <!-- 排除B传递过来的S依赖 -->
  <exclusions>
    <exclusion>
      <groupId>com.test</groupId>
      <artifactId>S</artifactId>
      </exclusion>
    </exclusions>
</dependency>

或者直接设置 排除所有间接依赖:

<dependency>
	<groupId>org.testgroupId>
	<artifactId>B</artifactId>
	<version>1.0</version>
  <!-- 排除B传递过来的所有依赖 -->
	<exclusions>
		<exclusion>
			<groupId>*</groupId>
			<artifactId>*</artifactId>
		</exclusion>
	</exclusions>
</dependency>

会话:Cookie、Session

会话:当浏览器发请求访问服务器,一直到访问服务器结束,浏览器关闭为止,这期间产生所有请求和响应,就称之为浏览器和服务器之间的一次会话。

cookie的工作原理 --通过Servlet的request请求对象获得cookie的数组

  1. Cookie是将会话中产生的数据保存在客户端,是客户端技术。
  2. Cookie是基于两个头进行工作的:分别是Set-Cookie响应头和Cookie请求头
  3. 通过Set-Cookie响应头将cookie从服务器端发送给浏览器让浏览器保存到内部;而浏览器一旦保存了cookie,以后浏览器每次访问服务器时,都会通过cookie请求头,将cookie信息再带回服务器中在需要时,在服务器端可以获取请求中的cookie中的数据,从而实现某些功能。

cookie的API及应用

1、创建Cookie对象

Cookie c = new Cookie(String name, String value);

2、将Cookie添加到response响应中

response.addCookie( Cookie c );

3、获取请求中的所有cookie对象组成的数组

Cookie[] cs = request.getCookies();

4、删除浏览器中的Cookie

// 删除名称为cart的cookie:可以向浏览器再发送一个同名的cookie(即名称也叫做cart),并设置cookie的最大生存时间为零,
Cookie c = new Cookie("cart", "");
c.setMaxAge( 60*60*0 );
response.addCookie( c );
out.write( "成功删除了名称为cart的cookie..." );

5、Cookie的常用方法

cookie.getName(); // 获取cookie的名字
cookie.getValue(); // 获取cookie中保存的值
cookie.setValue(); // 设置/修改cookie中保存的值(没有setName方法,因为cookie的名字无法修改)
cookie.setMaxAge(); //设置cookie的最大生存时间(如果不设置,cookie默认在一次会话结束时销毁!)

6、setMaxAge方法:设置cookie的最大生存时间

如果不设置该方法,cookie默认是会话级别的cookie,即生存时间是一次会话。当浏览器关闭,会话结束时,cookie也会被销毁(cookie默认存在浏览器的内存中,当浏览器关闭,内存释放,cookie也会随着内存的释放而销毁。)
如果设置了该方法,cookie将不会保存到浏览器的内存中,而是以文件形式保存到浏览器的临时文件夹中(也就是硬盘上),这样再关闭浏览器,内存释放,保存到硬盘上的cookie文件不会销毁,再次打开浏览器,还可以获取硬盘上的cookie信息。

案例:使用cookie模拟购物车

1.index.html – 点击这里只是为了给servlet传参prod属性及其值

<body>
	<h3>点击下面的商品链接, 可以将商品加入购物车</h3>
	<!-- 
	http://localhost/day13-cookie/CartServlet
	http://localhost/day13-cookie/index.html
	 -->
	<p><a href="CartServlet?prod=iphone11">iphone11</a></p>
	<p><a href="CartServlet?prod=vivonex3">vivonex3</a></p>
	<p><a href="CartServlet?prod=xiaomishouji">xiaomishouji</a></p>
	<p><a href="CartServlet?prod=huaweip30">huaweip30</a></p>
	<p><a href="CartServlet?prod=海尔洗衣机">海尔洗衣机</a></p>	
	<h3>点击下面的支付链接, 可以对购物车中的商品进行结算</h3>
	<a href="PayServlet">支付</a>
</body>

2.CartServlet --接收浏览器传来参数prod及其值存入cookie中

protected void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {
	response.setContentType("text/html;charset=utf-8");
	PrintWriter out = response.getWriter();
	String prod = request.getParameter( "prod" );
	Cookie cookie = new Cookie( "cart", prod  );
	cookie.setMaxAge( 60*60*24 );
	response.addCookie( cookie );
	out.write( "成功将"+prod+"加入了购物车....." );
}

3.PayServlet --接收浏览器传来的cookie,并取出值

protected void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {
	response.setContentType("text/html;charset=utf-8");
	PrintWriter out = response.getWriter();
	Cookie[] cs = request.getCookies();
	String prod = null;
	if( cs != null ) {
		for (Cookie c : cs) {
			if( "cart".equals( c.getName() ) ) {  //"cart"是服务器存入cookie中的cookie的名字
				prod = c.getValue();
			}
		}
	}
	//模拟为商品进行结算
	if( prod == null ) {
		out.write( "您还没有将商品加入购物车...." );
	}else {
		out.write( "成功为"+prod+"支付了1000.00元...." );
	}
}

session的工作原理 --通过session域对象getAttribute()方法将数据从session中取出

  1. Session是将会话中产生的数据保存在服务器端,是服务器端技术
  2. Session是一个域对象,session中也保存了一个map集合,往session中存数据,其实就是将数据保存到session的map集合中。
  3. 通过session.setAttribute()方法可以将数据保存到session中,通过session.getAttribute()方法可以将数据从session中取出来。
    获取session对象:
HttpSession session = request.getSession();
session.setAttribute(String attrName, Object attrValue); 
session.getAttribute(String attrName);  //返回值是一个Object类型

Session域对象的三大特征:
(1)生命周期:

**创建session:**第一次调用request.getSession()方法时,会创建一个session对象。
销毁session:

  1. 超时销毁:默认情况下,当超过30分钟没有访问session,session就会超时销毁。
  2. 自杀:调用session的invalidate方法时,会立即销毁session。
  3. 意外身亡:当服务器非正常关闭时(硬件损坏,断电,内存溢出等导致服务器非正常关闭),session会随着服务器的关闭而销毁;
    当服务器正常关闭,在关闭之前,服务器会将内部的session对象序列化保存到服务器的work目录下,变为一个文件。这个过程叫做session的钝化(序列化);再次将服务器启动起来,钝化着的session会再次回到服务器,变为服务器中的对象,这个过程叫做session的活化(反序列化)。
    **(2)作用范围:**在一次会话范围内(获取到的都是同一个session对象)
    **(3)主要功能:**在整个会话范围内实现数据的共享

案例:使用session模拟购物车

1 CartServlet

protected void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {
	response.setContentType("text/html;charset=utf-8");
	PrintWriter out = response.getWriter();
	String prod = request.getParameter( "prod" );
	HttpSession session = request.getSession();
	session.setAttribute( "cart" , prod );
	out.write( "成功将 [ "+prod+" ] 加入了购物车~~~" );
}

2 PayServlet

protected void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException {
	response.setContentType("text/html;charset=utf-8");
	PrintWriter out = response.getWriter();
	HttpSession session = request.getSession();
	String prod = (String)session.getAttribute( "cart" );
	out.write( "成功为 [ "+prod+" ] 支付了2000.00元~~~~" );
}
总结cookie和session的用法:

1 cookie(客户端技术)在servlet中new Cookie(“名”,“值”);直接将name及值value存入了cookie中
并且需要用response响应对象手动添加cooike到服务器响应中让浏览器接收后保存到客户端.
(response.addCookie( cookie );

取值时需要通过request请求对象从浏览器请求中获取所有cookie, **request.getCookies();返回值是一个cookie数组,遍历后根据name属性取值即可!!
2 session(服务端技术))通过
request.getSession();获取session对象(若服务器已有该对象直接获取到了,若没有时执行该方法会直接创建出来,而获取到)setAttribute(“名”,“值”);直接就存入到session域中了,不需要额外的操作, 在需要从session中取数据时直接request.getSession();**获取session对象后,getAttribute(“名”);取值即可

当cookie中保存中文数据,将cookie添加到响应中时,会报一个500异常

解决方法是:
创建cookie对象存数据时,直接先将存入cookie中的数据进行URL编码

Cookie cookie = new Cookie("pord", URLEncoder.encode(prod,"utf-8"));  //直接将存入的数据进行编码即可

取数据时取到数据后,再添加一步解码即可!!

pord = URLDecoder.decode(prod,"utf-8");

MySQL数据库事务

事务及四大特性
原子性,一致性,隔离性,持久性
在默认情况下,MySQL每执行一条SQL语句,都是一个单独的事务。–底层自动完成

手动开启事务和结束事务。

  • 开启事务:start transaction;
  • 结束事务:commit(提交事务)或 rollback(回滚事务)

事务并发读问题
其中有三类是读问题,分别是:脏读(读取到事务未提交的数据)、不可重复读(两次读取结果不一致–针对修改操作)、幻读(两次查询结果不一致–针对插入或删除操作)。
设置事务隔离级别

set tx_isolation='read-uncommitted'; //--允许脏读、不可重复读、幻读
set tx_isolation='read-committed'; //--不允许脏读
set tx_isolation='repeatable-read'; //--不允许脏读、防止不可重复读
set tx_isolation='serializable'; //--不允许脏读、防止不可重复读,防止幻读

MyBatis优秀的持久层框架

Mybatis对JDBC访问数据库的过程进行了封装,简化了JDBC代码,解决JDBC将结果集封装为Java对象的麻烦(JDBC的sql是写在了java程序里面,结果集对象需要遍历取数据)。
Mybatis是将SQL配置在mapper文件中,修改SQL只是修改配置文件,类不需要重新编译。
对查询SQL执行后返回的ResultSet对象,Mybatis会帮我们处理,转换成Java对象

框架应用:

1 编辑mybatis-config.xml配置文件
配置事务管理方式及数据库数据源,导入Mapper.xml的sql映射文件
2 编辑Mapper文件执行sql语句
3 业务类里通过namespace+id定位执行哪一条sql执行即可.

mybatis中的占位符

#{}占位符
当#{}占位符是为字符串或者日期类型的值进行占位时,在参数值传过来替换占位符的同时,会进行转义处理(在字符串或日期类型的值的两边加上单引号)
${}占位符
是为SQL片段(字符串)进行占位,将传过来的SQL片段直接拼接在 ${} 占位符所在的位置,不会进行任何的转义处理。
需要注意的是:使用 ${} 占位符为SQL语句中的片段占位时,即使只有一个占位符,需要传的也只有一个参数,也需要将参数先封装再传递!

动态SQL标签

if、where标签

标签:是根据test属性中的布尔表达式的值,决定是否执行所包裹的sql语句
标签:用于对包含在其中的SQL片段进行检索,在需要时可以生成where关键字,并且在需要时会剔除多余的连接词(比如and或者or) --只能剔除,不能增加
Mapper映射文件中

<select id="findAllBySal2" resultType="com.tedu.pojo.Emp">
  select * from emp
  <where>
    <if test="minSal != null">
    	and salary>#{minSal}
    </if>
    <if test="maxSal != null">
    	and salary &lt;= #{maxSal}
    </if>
  </where>
</select>

可以使用 < 代替 <

foreach元素

可以对传过来的参数数组或集合进行遍历
属性
item open collection close separator
item必需,若collection为数组或List集合时,item表示其中的元素,若collection为map中的key,item表示map中value(集合或数组)中的元素
collection必需,值为遍历的集合类型,例如:如果参数只是一个数组或List集合,则collection的值为array或list;如果传的是多个参数,用map封装,collection则指定为map中的key

Mapper接口 --配合Mapper.xml文件执行sql语句与数据库交互

区别一:
不使用Mapper接口时,Mapper.xml文件的namespace是任意的只要全局唯一即可,调用时namespace+id定位sql
而使用了Mapper接口后,Mapper.xml文件的namespace必须是对应Mapper接口的全限定类名
接口中方法的名字要和映射的sql标签的id值保持一致
接口中方法的返回值类型resultType的类型要一致
区别二:
不使用Mapper接口时,直接通过SqlSession执行sql语句(namespace+id)

int rows = session.update("EmpMapper.update");
session.commit();

使用Mapper接口时,执行sql是先通过SqlSession对象获取Mapper对象,然后调用该对象的对应方法即可!!!

EmpMapper map = session.getMapper(EmpMapper.class);
Emp e = map.findById(2);

spring框架

IoC(Inverse Of Control:控制反转/反转控制)和AOP(Aspact Oriented Programming:面向切面编程)为核心,管理软件中的对象 (功能远不止于此),即创建对象维护对象之间的关系

工厂模式解耦介绍

负责读取配置文件根据配置文件创建并返回这些对象的类就是工厂
配置文件中是key=v形式存储,获取key后就得v,例如:config.properties配置文件

EmpService=com.tedu.service.EmpServiceImpl
EmpDao=com.tedu.dao.EmpDaoImpl

只需要将类提前配置在配置文件中就可以将对象的创建交给框架来做当需要对象时,不需要自己创建,而是通过框架直接获取即可,省去了new对象的过程,自然就降低类和类之间的依赖关系,也就是耦合性。

工厂模式核心类:BeanFactory类

package com.tedu.factory;
public class BeanFactory {
	//声明一个Properties对象,在静态代码块中对其进行初始化
	private static Properties prop;
	static {
		try {
			prop = new Properties();
			InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("config.properties");
			//将配置文件中的内容读取到Properties对象中
			prop.load( in );
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("初始化Properties对象失败!");
		}
	}	
	//根据config.xml文件中的key获取对应class类的实例
	public static Object getBean(String key) {
		Object bean = null;
		try {
			String className = prop.getProperty( key );
			bean = Class.forName(className).newInstance();  //根据反射创建实例
		} catch (Exception e) {
			e.printStackTrace();
		}
		return bean;  //返回实例即可
	}
}

解耦,直接通过BeanFactory工厂获取对象

private EmpDao dao = (EmpDao)BeanFactory.getBean( "EmpDao" );
框架应用:

1 创建spring核心配置文件—applicationContext.xml
将需要创建实例的接口及实例配置到该配置文件中

<!-- 将EmpService接口的实现类的实例交给spring创建 -->
<bean id="empService" class="com.tedu.service.EmpServiceImpl"></bean>

2 使用时直接在业务类里创建spring的核心容器对象即可

//加载核心配置文件,创建核心容器对象
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		//通过spring的核心容器对象获取EmpService接口的子类实例
		EmpService service = (EmpService) ac.getBean("empService"); //获取到了接口的实现类对象

scope属性
设置单例和多例:最常用是singleton(单例)或prototype(多例)
用单例和多例的标准只有一个:当对象含有可改变的状态时(更精确的说就是在实际应用中该状态会改变),使用多实例,否则单实例; --貌似就是例如设置了成员变量并赋值了,该对象创建实例时就是用多例,每次创建新的实例属性值都是初始值.若使用单例,多线程操作这一个实例该属性会被多线程反复多个的操作,容易引发线程安全(加同步锁解决…synchronized),且每个对象使用的该成员变量值已被修改过的值…

<bean id="user" scope="singleton" class="com.tedu.pojo.User"></bean>

Spring DI依赖注入

所谓的依赖注入其实就是,在创建对象的同时或之后,如何给对象的属性赋值。
1 普通注入
修改applicationContext.xml中User实例的声明,为User实例注入属性

<!-- 声明User类的bean实例 -->
<bean id="user" class="com.tedu.spring.User">
	<!-- 通过set方式为普通属性赋值 -->
	<property name="name" value="韩少云"></property>
	<property name="age" value="20"></property>
</bean>

2 对象属性注入
通过Spring创建User实例,并为User对象的userInfo属性(对象属性)赋值

<!-- 声明User类的bean实例 -->
<bean id="user" class="com.tedu.spring.User">
	<!-- 通过set方式为普通属性赋值 -->
	<property name="name" value="韩少云"></property>
	<property name="age" value="20"></property>
	<!-- 通过set方式为对象属性赋值 -->
	<property name="userInfo" ref="userInfo"></property>
</bean>
<!-- 声明UserInfo类的bean实例 -->
<bean id="userInfo" class="com.tedu.spring.UserInfo"></bean>

3 构造方法注入
** 修改applicationContext.xml文件,将set方式修改为构造方法注入。**

<bean id="user" class="com.tedu.spring.User">
	<!-- 通过构造器中参数为属性赋值 -->
	<constructor-arg name="name" value="马云"></constructor-arg>
	<constructor-arg name="age" value="35"></constructor-arg>
	<constructor-arg name="userInfo" ref="userInfo"></constructor-arg>
</bean>
<bean id="userInfo" class="com.tedu.spring.UserInfo"></bean>

springmvc框架

1 用户发送请求至前端控制器(DispatcherServlet);
2 前端控制器(DispatcherServlet)收到请求后调用处理器映射器(HandlerMapping)找到具体的Controller,并将Controller返回给DispatcherServlet
3 前端控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)。处理器适配器经过适配调用具体的Controller;(Controller–> service --> Dao --> 数据库),返回ModelAndView
4 前端控制器(DispatcherServlet)将执行的结果(ModelAndView)传给视图解析器(ViewReslover),根据View(逻辑视图名)解析后返回具体JSP页面
5 前端控制器(DispatcherServlet)根据Model对View进行渲染(即将模型数据填充至视图中);
前端控制器(DispatcherServlet)将填充了数据的网页响应给用户

框架应用:

1 创建maven的web项目
2 pom文件引入springMVC的jar包及其他需要的jar包
3 创建web.xml配置文件 --配置前端控制器(将所有请求交给springmvc处理),配置拦截机制(/表示所有请求JSP除外,都要经过springmvc前端控制器)
4 创建springmvc-config.xml 配置文件(配置前端控制器放行静态资源,配置注解驱动,配置需要扫描的包,配置内部资源视图解析器加前后缀)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc
						http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
						http://www.springframework.org/schema/beans
						http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
						http://www.springframework.org/schema/context
          				http://www.springframework.org/schema/context/spring-context-4.0.xsd">
	
	<!-- 1.配置前端控制器放行静态资源(html/css/js等,否则静态资源将无法访问) -->
	<mvc:default-servlet-handler/>
	
	<!-- 2.配置注解驱动,用于识别注解(比如@Controller-->
	<mvc:annotation-driven></mvc:annotation-driven>
	
	<!-- 3.配置需要扫描的包:spring自动去扫描 base-package 下的类,
		如果扫描到的类上有 @Controller@Service@Component等注解,
		将会自动将类注册为bean 
	 -->
	<context:component-scan base-package="com.tedu.controller">
	</context:component-scan>
	
	<!-- 4.配置内部资源视图解析器
		prefix:配置路径前缀
		suffix:配置文件后缀
	 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/pages/"/>
		<property name="suffix" value=".jsp"/>
	</bean>	
	
</beans>

请求转发(forward)

@RequestMapping("testForward")
public String testForward(){
	System.out.println("测试请求转发(forward)...");
	return "forward:hello";
}

重定向(redirect)

@RequestMapping("testRedirect")
public String testRedirect(){
	System.out.println("测试请求重定向(redirect)...");
	return "redirect:hello";
}

乱码处理
在web.xml中加入如下代码(配置请求参数乱码过滤器),可以解决POST提交的中文参数乱码问题!

<filter>
	<filter-name>encodingFilter</filter-name>
	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
	<init-param>
		<param-name>encoding</param-name>
		<param-value>UTF8</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>encodingFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

servlet中

request.setCharacterEncoding("utf-8");
springmvc响应数据 --Model的使用
@RequestMapping("/testModel")
public String testModel(Model model){
	model.addAttribute("name", "马云");
	model.addAttribute("age", 20);
	return "home";
}

home.jsp中取出属性并显示

<body>
	<h1>hello springmvc~~~</h1>
	${ name } <br/>
	${ age }
</body>

addAttribute方法会将属性保存到request域中,再通过转发将属性数据带到相应的JSP中,通过${ } --EL表达式 取出并显示
标签里面的属性值必须用引号引起来!!!EL表达式也必须放入引号引起来!!!

<c:forEach items="${ dList }" var="door">
	<c:if test="${ door.id==order.doorId }">
		<td class="1111">${ door.name }</td>
	</c:if>
</c:forEach>
<td>${ order.orderNo }</td>
<td>${ order.orderType }</td>
<td>${ order.pnum }</td>
<td>${ order.cashier }</td>
<td>
	<fmt:formatDate value="${ order.orderTime }"  pattern="yyyy-MM-dd HH:mm:ss"/>
</td>
<!-- fmt标签时日期标签,pattern属性指明日期的格式-->
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值