关系型数据库、非关系型数据库
底层以二维表的形式保存数据的库就是关系型数据库
数据库服务器就是一个软件如: 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程序(六个步骤)
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()....");
}
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(数据源),因此连接池也被叫做数据源
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 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方法改为了还连接到连接池中
*/
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>
网页中的空格:可以使用
或
做空格
属性设置可以放在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>
通过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;
}
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: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)
block:块级元素的默认值 默认情况下独占一行 可以设置宽高
inline:行内元素的默认值 默认情况下多个行内元素可以处在同一行 一般不能设置宽高
inline-block:行内块元素 多个元素既可以显示在同一行, 也可以设置宽和高
none:表示隐藏元素
特点:
(1)JS是一门直译式的语言(边解释边执行,没有编译的过程)
(2)JS是一门基于对象的语言(JS中没有类的概念)
(3)JS是一门弱类型的语言(Java:强类型)
在java中: 变量一旦声明, 就属于固定的数据类型, 不能被改变
String s = "abc";
在JS中: 变量是不区分类型的, 可以指向任意的数据类型
var s = 100;
s = "abc";
s = true;
s = [];
s = function(){}
在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() )"/>
(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是严格区分大小写的!
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( "您输入的运算符有误, 请重新输入!" );
}
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 函数名称([参数列表]){
函数体
}
或者:
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文档对象
}
电灯开关
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"); // \\
//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
}
}
document.getElementById( id值 )
document.getElementsByTagName( 元素名/标签名 ) --返回的是一个数组
document.body – 获取当前文档中的body元素
元素名.parentNode – 获取当前元素的父元素。element表示当前元素
document.createElement( 元素名称 )
parent.appendChild( child )
parent.removeChild( child )
元素名.innerHTML --获取当前元素的html内容(从开始标签到结束标签之间的所有内容),还可以设置当前元素的html内容(如果元素内部有内容,将会覆盖原有内容)
div{ css属性... } //css中选择器
jQuery("#div1")
$(".s1")
$("div")
$("div").css("border", "2px solid red");
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>
基本选择器
(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 = $("
"); //js创建document.createElement("table")
for(var j=0;j<rows;j++){ //外层循环:控制行数
//2.创建一个tr元素
var $tr = $(" ");
for(var i=0;i<cols;i++){ //内层循环:控制列数
//3.创建一个td元素, 并为td添加内容
var $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 = $(" ");
//>>创建5个td元素,并将员工信息添加到td中
var $td1 = $(" "); //复选框
var $td2 = $(""+id+" "); //ID
var $td3 = $(""+name+" "); //name
var $td4 = $(""+email+" "); //email
var $td5 = $(""+salary+" "); //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()一个参数时为返回属性的值,两个参数时为设置属性的值 --属性为标签元素里面的属性
1 创建元素
$("") -- 创建一个div元素,返回的是一个jQuery对象,表示创建的div元素
$("xxxx") -- 创建一个包含内容的div元素,返回的是一个jQuery对象,表示创建的div元素
2 添加子元素
$parent.append( $child ) -- 父元素调用方法添加子元素
$("body").append( "我是新来的..." ); -- 往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("我是来替换的…
")
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值
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响应
状态码
200: 表示请求处理成功
302: 表示请求重定向(即需要再进一步请求才可以获取到相应的资源)
304/307: 表示通知浏览器使用缓存 --浏览器访问一次一般都会缓存,再次请求时服务器发送304–相当于告诉浏览器缓存未更新过,用你自己的缓存即可
404: 表示浏览器请求的资源不存在(浏览器的问题, 请求路径错误)
500: 表示服务器在处理请求的过程中抛出了异常。 --servlet程序抛异常…
响应实体内容 --就是浏览器所请求文件的内容。例如:浏览器向服务器请求一个hello.html文件,服务器会找到hello.html文件,将文件的内容作为响应实体发送给浏览器。
只有当使用表单(form),并且在表单上明确的通过method指定提交方式为POST时,请求方式才是POST提交,其他方式都是GET提交(AJAX除外)
Servlet本质上是一段Java程序,和之前的Java程序不同的是,Servlet程序无法独立运行,需要将Servlet程序放在服务器中(比如tomcat服务器),由服务器调用才可以执行。服务器端的Java程序
其***作用是对服务器接收过来的请求进行处理***(作用为处理请求)
第一步:创建一个动态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是代表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提交有效!
请求转发是服务器内部资源的一种跳转方式
(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方法有什么区别?
向客户端发送数据
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( "你好" );
当浏览器向服务器发请求访问某一个资源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看起来像一个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中的html内容
<%= 常量、变量、表达式 %>
<%= "Hello JSP..." %>
<% String name = "林青霞"; %> //这个是脚本片段
<%= name %>
<%= 100+123 %>
<%= Math.random() %>
<% 若干Java语句 %>
<%-- JSP注释内容 --%>
<%@ 指令名称 若干属性声明… %>
指令的作用:用于指挥JSP解析引擎如何将一个JSP翻译成一个Servlet程序
1、page指令
<%@ page language="java"%>
<%@ page import="java.util.Date"%>
<%@ page pageEncoding="UTF-8"%>
2、taglib指令
用于引入JSTL标签库或者其他的自定义标签库
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(taglib指令)
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
1
(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
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
//(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的配置三点:
1 配置本地仓库
2 配置镜像
3 配置jdk版本
测试是否配置成功:window—> show view —> other中搜索"maven",点击下面的选框中的选项
配置完成之后直接new Maven Project项目即可
注意:当创建web工程时,即打war包,创建完成后pom.xml文件会报错,找不到web.xml文件
创建Servlet程序时,必须把tomcat加进来
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>
会话:当浏览器发请求访问服务器,一直到访问服务器结束,浏览器关闭为止,这期间产生所有请求和响应,就称之为浏览器和服务器之间的一次会话。
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信息。
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元...." );
}
}
HttpSession session = request.getSession();
session.setAttribute(String attrName, Object attrValue);
session.getAttribute(String attrName); //返回值是一个Object类型
Session域对象的三大特征:
(1)生命周期:
**创建session:**第一次调用request.getSession()方法时,会创建一个session对象。
销毁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元~~~~" );
}
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中的数据进行URL编码
Cookie cookie = new Cookie("pord", URLEncoder.encode(prod,"utf-8")); //直接将存入的数据进行编码即可
取数据时取到数据后,再添加一步解码即可!!
pord = URLDecoder.decode(prod,"utf-8");
事务及四大特性
原子性,一致性,隔离性,持久性
在默认情况下,MySQL每执行一条SQL语句,都是一个单独的事务。–底层自动完成
手动开启事务和结束事务。
事务并发读问题
其中有三类是读问题,分别是:脏读(读取到事务未提交的数据)、不可重复读(两次读取结果不一致–针对修改操作)、幻读(两次查询结果不一致–针对插入或删除操作)。
设置事务隔离级别
set tx_isolation='read-uncommitted'; //--允许脏读、不可重复读、幻读
set tx_isolation='read-committed'; //--不允许脏读
set tx_isolation='repeatable-read'; //--不允许脏读、防止不可重复读
set tx_isolation='serializable'; //--不允许脏读、防止不可重复读,防止幻读
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执行即可.
#{}占位符
当#{}占位符是为字符串或者日期类型的值进行占位时,在参数值传过来替换占位符的同时,会进行转义处理(在字符串或日期类型的值的两边加上单引号)
${}占位符
是为SQL片段(字符串)进行占位,将传过来的SQL片段直接拼接在 ${} 占位符所在的位置,不会进行任何的转义处理。
需要注意的是:使用 ${} 占位符为SQL语句中的片段占位时,即使只有一个占位符,需要传的也只有一个参数,也需要将参数先封装再传递!
标签:是根据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 <= #{maxSal}
</if>
</where>
</select>
可以使用 < 代替 <
可以对传过来的参数数组或集合进行遍历
属性
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文件的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);
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>
所谓的依赖注入其实就是,在创建对象的同时或之后,如何给对象的属性赋值。
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>
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>/*
servlet中
request.setCharacterEncoding("utf-8");
@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属性指明日期的格式-->