Java简单知识点小结

1、AJAX

1. 概念: ASynchronous JavaScript And XML	异步的JavaScript 和 XML
	1. 异步和同步:客户端和服务器端相互通信的基础上
		* 客户端必须等待服务器端的响应。在等待的期间客户端不能做其他操作。
		* 客户端不需要等待服务器端的响应。在服务器处理请求的过程中,客户端可以进行其他的操作。
		Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。 [1] 
		通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
		传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面,提升用户的体验;
2. 实现方式
	1. 原生的JS实现方式
				 //1.创建核心对象
	            var xmlhttp;
	            if (window.XMLHttpRequest)
	            {// code for IE7+, Firefox, Chrome, Opera, Safari
	                xmlhttp=new XMLHttpRequest();
	            }
	            else
	            {// code for IE6, IE5
	                xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
	            }
	
	            //2. 建立连接
	            /*
	                参数:
	                    1. 请求方式:GET、POST
	                        * get方式,请求参数在URL后边拼接。send方法为空参
	                        * post方式,请求参数在send方法中定义
	                    2. 请求的URL:
	                    3. 同步或异步请求:true(异步)或 false(同步)
	
	             */
	            xmlhttp.open("GET","ajaxServlet?username=tom",true);
	            
	            //3.发送请求
	            xmlhttp.send();
	
	            //4.接受并处理来自服务器的响应结果
	            //获取方式 :xmlhttp.responseText
	            //什么时候获取?当服务器响应成功后再获取
	
	            //当xmlhttp对象的就绪状态改变时,触发事件onreadystatechange。
	            xmlhttp.onreadystatechange=function()
	            {
	                //判断readyState就绪状态是否为4,判断status响应状态码是否为200
	                if (xmlhttp.readyState==4 && xmlhttp.status==200)
	                {
	                   //获取服务器的响应结果
	                    var responseText = xmlhttp.responseText;
	                    alert(responseText);
	                }
	            }
	2. JQeury实现方式
		1. $.ajax()
			* 语法:$.ajax({键值对});
			 //使用$.ajax()发送异步请求
	            $.ajax({
	                url:"ajaxServlet1111" , // 请求路径
	                type:"POST" , //请求方式
	                //data: "username=jack&age=23",//请求参数
	                data:{"username":"jack","age":23},
	                success:function (data) {
	                    alert(data);
	                },//响应成功后的回调函数
	                error:function () {
	                    alert("出错啦...")
	                },//表示如果请求响应出现错误,会执行的回调函数
	
	                dataType:"text"//设置接受到的响应数据的格式
	            });
		2. $.get():发送get请求
			* 语法:$.get(url, [data], [callback], [type])
				* 参数:
					* url:请求路径
					* data:请求参数
					* callback:回调函数
					* type:响应结果的类型

		3. $.post():发送post请求
			* 语法:$.post(url, [data], [callback], [type])
				* 参数:
					* url:请求路径
					* data:请求参数
					* callback:回调函数
					* type:响应结果的类型

2、JSON

1. 概念: JavaScript Object Notation		JavaScript对象表示法
	Person p = new Person();
	p.setName("张三");
	p.setAge(3);
	p.setGender("男");

	var p = {"name":"张三","age":3,"gender":"男"};

	* json现在多用于存储和交换文本信息的语法
	* 进行数据的传输
	* JSON 比 XML 更小、更快,更易解析。

2. 语法:
	1. 基本规则
		* 数据在名称/值对中:json数据是由键值对构成的
			* 键用引号(单双都行)引起来,也可以不使用引号
			* 值得取值类型:
				1. 数字(整数或浮点数)
				2. 字符串(在双引号中)
				3. 逻辑值(true 或 false)
				4. 数组(在方括号中)	{"persons":[{},{}]}
				5. 对象(在花括号中) {"address":{"province":"陕西"....}}
				6. null
		* 数据由逗号分隔:多个键值对由逗号分隔
		* 花括号保存对象:使用{}定义json 格式
		* 方括号保存数组:[]
	2. 获取数据:
		1. json对象.键名
		2. json对象["键名"]
		3. 数组对象[索引]
		4. 遍历
				 //1.定义基本格式
		        var person = {"name": "张三", age: 3, 'gender': true};
		        var ps = [{"name": "张三", "age": 3, "gender": true},
		            {"name": "李四", "age": 4, "gender": true},
		            {"name": "王五", "age": 5, "gender": false}];
  //获取person对象中所有的键和值
		        //for in 循环
		       /* for(var key in person){
		            //这样的方式获取不行。因为相当于  person."name"
		            //alert(key + ":" + person.key);
		            alert(key+":"+person[key]);
		        }*/
		
		       //获取ps中的所有值
		        for (var i = 0; i < ps.length; i++) {
		            var p = ps[i];
		            for(var key in p){
		                alert(key+":"+p[key]);
		            }
		        }
3. JSON数据和Java对象的相互转换
	* JSON解析器:
		* 常见的解析器:Jsonlib,Gson,fastjson,jackson
	1. JSON转为Java对象
		1. 导入jackson的相关jar包
		2. 创建Jackson核心对象 ObjectMapper
		3. 调用ObjectMapper的相关方法进行转换
			1. readValue(json字符串数据,Class)
	2. Java对象转换JSON
		1. 使用步骤:
			1. 导入jackson的相关jar包
			2. 创建Jackson核心对象 ObjectMapper
			3. 调用ObjectMapper的相关方法进行转换
				1. 转换方法:
					* writeValue(参数1,obj):
	                    参数1:
	                        File:将obj对象转换为JSON字符串,并保存到指定的文件中
	                        Writer:将obj对象转换为JSON字符串,并将json数据填充到字符输出流中
	                        OutputStream:将obj对象转换为JSON字符串,并将json数据填充到字节输出流中
	                * writeValueAsString(obj):将对象转为json字符串

				2. 注解:
					1. @JsonIgnore:排除属性。
					2. @JsonFormat:属性值得格式化
						* @JsonFormat(pattern = "yyyy-MM-dd")

				3. 复杂java对象转换
					1. List:数组
					2. Map:对象格式一致

3、Bootstrap

1. 概念: 一个前端开发的框架,Bootstrap,来自 Twitter,是目前很受欢迎的前端框架。Bootstrap 是基于 HTML、CSS、JavaScript 的,它简洁灵活,使得 Web 开发更加快捷。
	* 框架:一个半成品软件,开发人员可以在框架基础上,在进行开发,简化编码。
	* 好处:
		1. 定义了很多的css样式和js插件。我们开发人员直接可以使用这些样式和插件得到丰富的页面效果。
		2. 响应式布局。
			* 同一套页面可以兼容不同分辨率的设备。
			
    2.小案例
	<!DOCTYPE html>
	<html lang="zh-CN">
	<head>
	    <meta charset="utf-8">
	    <meta http-equiv="X-UA-Compatible" content="IE=edge">
	    <meta name="viewport" content="width=device-width, initial-scale=1">
	    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
	    <title>Bootstrap HelloWorld</title>
	
	    <!-- Bootstrap -->
	    <link href="css/bootstrap.min.css" rel="stylesheet">
	    <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
	    <script src="js/jquery-3.2.1.min.js"></script>
	    <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
	    <script src="js/bootstrap.min.js"></script>
	</head>
	<body>
	<h1>案例</h1>
	
	</body>
	</html>

响应式布局

* 同一套页面可以兼容不同分辨率的设备。
* 实现:依赖于栅格系统:将一行平均分成12个格子,可以指定元素占几个格子
* 步骤:
	1. 定义容器。相当于之前的table、
		* 容器分类:
			1. container:两边留白
			2. container-fluid:每一种设备都是100%宽度
	2. 定义行。相当于之前的tr   样式:row
	3. 定义元素。指定该元素在不同的设备上,所占的格子数目。样式:col-设备代号-格子数目
		* 设备代号:
			1. xs:超小屏幕 手机 (<768px):col-xs-12
			2. sm:小屏幕 平板 (≥768px)
			3. md:中等屏幕 桌面显示器 (≥992px)
			4. lg:大屏幕 大桌面显示器 (≥1200px)

	* 注意:
		1. 一行中如果格子数目超过12,则超出部分自动换行。
		2. 栅格类属性可以向上兼容。栅格类适用于与屏幕宽度大于或等于分界点大小的设备。
		3. 如果真实设备宽度小于了设置栅格类属性的设备代码的最小值,会一个元素沾满一整行。

CSS样式和JS插件

1. 全局CSS样式:
	* 按钮:class="btn btn-default"
	* 图片:
		*  class="img-responsive":图片在任意尺寸都占100%
		*  图片形状
			*  <img src="..." alt="..." class="img-rounded">:方形
			*  <img src="..." alt="..." class="img-circle"> : 圆形
			*  <img src="..." alt="..." class="img-thumbnail"> :相框
	* 表格
		* table
		* table-bordered
		* table-hover
	* 表单
		* 给表单项添加:class="form-control" 
2. 组件:
	* 导航条
	* 分页条
3. 插件:
	* 轮播图

小示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>Bootstrap HelloWorld</title>

    <!-- Bootstrap -->
    <link href="css/bootstrap.min.css" rel="stylesheet">

    <!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
    <script src="js/jquery-3.2.1.min.js"></script>
    <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
    <script src="js/bootstrap.min.js"></script>
    <style>
        .paddtop{
            padding-top: 10px;
        }
        .search-btn{
            float: left;
            border:1px solid #ffc900;
            width: 90px;
            height: 35px;
            background-color:#ffc900 ;
            text-align: center;
            line-height: 35px;
            margin-top: 15px;
        }

        .search-input{
            float: left;
            border:2px solid #ffc900;
            width: 400px;
            height: 35px;
            padding-left: 5px;
            margin-top: 15px;
        }
        .jx{
            border-bottom: 2px solid #ffc900;
            padding: 5px;
        }
        .company{
            height: 40px;
            background-color: #ffc900;
            text-align: center;
            line-height:40px ;
            font-size: 8px;
        }
    </style>
</head>
<body>

   <!-- 1.页眉部分-->
   <header class="container-fluid">
       <div class="row">
           <img src="img/top_banner.jpg" class="img-responsive">
       </div>
       <div class="row paddtop">
           <div class="col-md-3">
               <img src="img/xxx.jpg" class="img-responsive">
           </div>
           <div class="col-md-5">
               <input class="search-input" placeholder="请输入名称">
               <a class="search-btn" href="#">搜索</a>
           </div>
           <div class="col-md-4">
               <img src="img/hotel_tel.png" class="img-responsive">
           </div>

       </div>
       <!--导航栏-->
       <div class="row">
           <nav class="navbar navbar-default">
               <div class="container-fluid">
                   <!-- Brand and toggle get grouped for better mobile display -->
                   <div class="navbar-header">
                       <!-- 定义汉堡按钮 -->
                       <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                           <span class="sr-only">Toggle navigation</span>
                           <span class="icon-bar"></span>
                           <span class="icon-bar"></span>
                           <span class="icon-bar"></span>
                       </button>
                       <a class="navbar-brand" href="#">首页</a>
                   </div>

                   <!-- Collect the nav links, forms, and other content for toggling -->
                   <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                       <ul class="nav navbar-nav">
                           <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
                           <li><a href="#">Link</a></li>
                           <li><a href="#">Link</a></li>
                           <li><a href="#">Link</a></li>
                           <li><a href="#">Link</a></li>
                           <li><a href="#">Link</a></li>

                       </ul>
                   </div><!-- /.navbar-collapse -->
               </div><!-- /.container-fluid -->
           </nav>

       </div>

       <!--轮播图-->
       <div class="row">
           <div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
               <!-- Indicators -->
               <ol class="carousel-indicators">
                   <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
                   <li data-target="#carousel-example-generic" data-slide-to="1"></li>
                   <li data-target="#carousel-example-generic" data-slide-to="2"></li>
               </ol>

               <!-- Wrapper for slides -->
               <div class="carousel-inner" role="listbox">
                   <div class="item active">
                       <img src="img/banner_1.jpg" alt="...">
                   </div>
                   <div class="item">
                       <img src="img/banner_2.jpg" alt="...">
                   </div>
                   <div class="item">
                       <img src="img/banner_3.jpg" alt="...">
                   </div>

               </div>

               <!-- Controls -->
               <a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
                   <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
                   <span class="sr-only">Previous</span>
               </a>
               <a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
                   <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
                   <span class="sr-only">Next</span>
               </a>
           </div>
       </div>

   </header>
   <!-- 2.主体部分-->
   <div class="container">
        <div class="row jx">
            <img src="img/icon_5.jpg">
            <span>选折</span>
        </div>

       <div class="row paddtop">
           <div class="col-md-3">
                <div class="thumbnail">
                    <img src="img/jiangxuan_3.jpg" alt="">
                    <p>上海直飞</p>
                    <font color="red">&yen; 699</font>
                </div>
           </div>
           <div class="col-md-3">
               <div class="thumbnail">
                   <img src="img/jiangxuan_3.jpg" alt="">
                   <p>上海直飞</p>
                   <font color="red">&yen; 699</font>
               </div>

           </div>
           <div class="col-md-3">

               <div class="thumbnail">
                   <img src="img/jiangxuan_3.jpg" alt="">
                   <p>上海直飞</p>
                   <font color="red">&yen; 699</font>
               </div>
           </div>
           <div class="col-md-3">

               <div class="thumbnail">
                   <img src="img/jiangxuan_3.jpg" alt="">
                   <p>上海直飞</p>
                   <font color="red">&yen; 699</font>
               </div>
           </div>
       </div>
       <div class="row jx">
           <img src="img/icon_6.jpg">
           <span>游</span>
       </div>
       <div class="row paddtop">
           <div class="col-md-4">
               <img src="img/guonei_1.jpg">
           </div>
           <div class="col-md-8">
               <div class="row">
                   <div class="col-md-4">
                       <div class="thumbnail">
                           <img src="img/jiangxuan_3.jpg" alt="">
                           <p>上海</p>
                           <font color="red">&yen; 699</font>
                       </div>
                   </div>
                   <div class="col-md-4">
                       <div class="thumbnail">
                           <img src="img/jiangxuan_3.jpg" alt="">
                           <p>上海</p>
                           <font color="red">&yen; 699</font>
                       </div>

                   </div>
                   <div class="col-md-4">

                       <div class="thumbnail">
                           <img src="img/jiangxuan_3.jpg" alt="">
                           <p>上海</p>
                           <font color="red">&yen; 699</font>
                       </div>
                   </div>

               </div>
               <div class="row">
                   <div class="col-md-4">
                       <div class="thumbnail">
                           <img src="img/jiangxuan_3.jpg" alt="">
                           <p>上海</p>
                           <font color="red">&yen; 699</font>
                       </div>
                   </div>
                   <div class="col-md-4">
                       <div class="thumbnail">
                           <img src="img/jiangxuan_3.jpg" alt="">
                           <p>上海</p>
                           <font color="red">&yen; 699</font>
                       </div>

                   </div>
                   <div class="col-md-4">
                   </div>
                </div>
           </div>
       </div>
     </div>

<!-- 3.页脚部分-->
   <footer class="container-fluid">
       <div class="row">
           <img src="img/foote.png" class="img-responsive">
       </div>
       <div class="row company">
          xxxxx
       </div>
   </footer>
   </body>
</html>

4、Cookie、Session

会话技术

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

Cookie

1. 概念:客户端会话技术,将数据保存到客户端

2. 快速入门:
	* 使用步骤:
		1. 创建Cookie对象,绑定数据
			* new Cookie(String name, String value) 
		2. 发送Cookie对象
			* response.addCookie(Cookie cookie) 
		3. 获取Cookie,拿到数据
			* Cookie[]  request.getCookies()  

3. 实现原理
	* 基于响应头set-cookie和请求头cookie实现

4. cookie的细节
	1. 一次可不可以发送多个cookie?
		* 可以
		* 可以创建多个Cookie对象,使用response调用多次addCookie方法发送cookie即可。
	2. cookie在浏览器中保存多长时间?
		1. 默认情况下,当浏览器关闭后,Cookie数据被销毁
		2. 持久化存储:
			* setMaxAge(int seconds)
				1. 正数:将Cookie数据写到硬盘的文件中。持久化存储。并指定cookie存活时间,时间到后,cookie文件自动失效
				2. 负数:默认值
				3. 零:删除cookie信息
	3. cookie能不能存中文?
		* 在tomcat 8 之前 cookie中不能直接存储中文数据。
			* 需要将中文数据转码---一般采用URL编码(%E3)
		* 在tomcat 8 之后,cookie支持中文数据。特殊字符还是不支持,建议使用URL编码存储,URL解码解析
	4. cookie共享问题?
		1. 假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享?
			* 默认情况下cookie不能共享

			* setPath(String path):设置cookie的获取范围。默认情况下,设置当前的虚拟目录
				* 如果要共享,则可以将path设置为"/"

		2. 不同的tomcat服务器间cookie共享问题?
			* setDomain(String path):如果设置一级域名相同,那么多个服务器之间cookie可以共享
				* setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com中cookie可以共享

5. Cookie的特点和作用
	1. cookie存储数据在客户端浏览器
	2. 浏览器对于单个cookie 的大小有限制(4kb) 以及 对同一个域名下的总cookie数量也有限制(20个)

	* 作用:
		1. cookie一般用于存出少量的不太敏感的数据
		2. 在不登录的情况下,完成服务器对客户端的身份识别

6. 案例
	1、实现记住上一次访问时间
	2. 分析:
		1. 可以采用Cookie来完成
		2. 在服务器中的Servlet判断是否有一个名为lastTime的cookie
			1. 有:不是第一次访问
				1. 响应数据:欢迎回来,您上次访问时间为:2018年6月10日11:50:20
				2. 写回Cookie:lastTime=2018年6月10日11:50:01
			2. 没有:是第一次访问
				1. 响应数据:您好,欢迎您首次访问
				2. 写回Cookie:lastTime=2018年6月10日11:50:01

3. 代码实现:
		import javax.servlet.ServletException;
		import javax.servlet.annotation.WebServlet;
		import javax.servlet.http.Cookie;
		import javax.servlet.http.HttpServlet;
		import javax.servlet.http.HttpServletRequest;
		import javax.servlet.http.HttpServletResponse;
		import java.io.IOException;
		import java.net.URLDecoder;
		import java.net.URLEncoder;
		import java.text.SimpleDateFormat;
		import java.util.Date;
	@WebServlet("/cookieTest")
	public class CookieTest extends HttpServlet {
	    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	        //设置响应的消息体的数据格式以及编码
	        response.setContentType("text/html;charset=utf-8");
	
	        //1.获取所有Cookie
	        Cookie[] cookies = request.getCookies();
	        boolean flag = false;//没有cookie为lastTime
	        //2.遍历cookie数组
	        if(cookies != null && cookies.length > 0){
	            for (Cookie cookie : cookies) {
	                //3.获取cookie的名称
	                String name = cookie.getName();
	                //4.判断名称是否是:lastTime
	                if("lastTime".equals(name)){
	                    //有该Cookie,不是第一次访问
	
	                    flag = true;//有lastTime的cookie
	
	                    //设置Cookie的value
	                    //获取当前时间的字符串,重新设置Cookie的值,重新发送cookie
	                    Date date  = new Date();
	                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
	                    String str_date = sdf.format(date);
	                    System.out.println("编码前:"+str_date);
	                    //URL编码
	                    str_date = URLEncoder.encode(str_date,"utf-8");
	                    System.out.println("编码后:"+str_date);
	                    cookie.setValue(str_date);
	                    //设置cookie的存活时间
	                    cookie.setMaxAge(60 * 60 * 24 * 30);//一个月
	                    response.addCookie(cookie);

	                    //响应数据
	                    //获取Cookie的value,时间
	                    String value = cookie.getValue();
	                    System.out.println("解码前:"+value);
	                    //URL解码:
	                    value = URLDecoder.decode(value,"utf-8");
	                    System.out.println("解码后:"+value);
	                    response.getWriter().write("<h1>欢迎回来,您上次访问时间为:"+value+"</h1>");
	
	                    break;
	
	                }
	            }
	        }

	        if(cookies == null || cookies.length == 0 || flag == false){
	            //没有,第一次访问
	
	            //设置Cookie的value
	            //获取当前时间的字符串,重新设置Cookie的值,重新发送cookie
	            Date date  = new Date();
	            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
	            String str_date = sdf.format(date);
	            System.out.println("编码前:"+str_date);
	            //URL编码
	            str_date = URLEncoder.encode(str_date,"utf-8");
	            System.out.println("编码后:"+str_date);
	
	            Cookie cookie = new Cookie("lastTime",str_date);
	            //设置cookie的存活时间
	            cookie.setMaxAge(60 * 60 * 24 * 30);//一个月
	            response.addCookie(cookie);
	
	            response.getWriter().write("<h1>您好,欢迎您首次访问</h1>");
	        }
	    }
	    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	        this.doPost(request, response);
	    }
	}

JSP

1. 概念:
	* Java Server Pages: java服务器端页面
		* 可以理解为:一个特殊的页面,其中既可以指定定义html标签,又可以定义java代码
		* 用于简化书写!!!


2. 原理
	* JSP本质上就是一个Servlet

3. JSP的脚本:JSP定义Java代码的方式
	1. <%  代码 %>:定义的java代码,在service方法中。service方法中可以定义什么,该脚本中就可以定义什么。
	2. <%! 代码 %>:定义的java代码,在jsp转换后的java类的成员位置。
	3. <%= 代码 %>:定义的java代码,会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么。


4. JSP的内置对象:
	* 在jsp页面中不需要获取和创建,可以直接使用的对象
	* jsp一共有9个内置对象。
	* 今天学习3个:
		* request
		* response
		* out:字符输出流对象。可以将数据输出到页面上。和response.getWriter()类似
			* response.getWriter()和out.write()的区别:
				* 在tomcat服务器真正给客户端做出响应之前,会先找response缓冲区数据,再找out缓冲区数据。
				* response.getWriter()数据输出永远在out.write()之前

Session

1. 概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。HttpSession
2. 快速入门:
	1. 获取HttpSession对象:
		HttpSession session = request.getSession();
	2. 使用HttpSession对象:
		Object getAttribute(String name)  
		void setAttribute(String name, Object value)
		void removeAttribute(String name)  

3. 原理
	* Session的实现是依赖于Cookie的。

4. 细节:
	1. 当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
		* 默认情况下。不是。
		* 如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存。
			 Cookie c = new Cookie("JSESSIONID",session.getId());
	         c.setMaxAge(60*60);
	         response.addCookie(c);

	2. 客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
		* 不是同一个,但是要确保数据不丢失。tomcat自动完成以下工作
			* session的钝化:
				* 在服务器正常关闭之前,将session对象系列化到硬盘上
			* session的活化:
				* 在服务器启动后,将session文件转化为内存中的session对象即可。
			
	3. session什么时候被销毁?
		1. 服务器关闭
		2. session对象调用invalidate() 。
		3. session默认失效时间 30分钟
			选择性配置修改	
			<session-config>
		        <session-timeout>30</session-timeout>
		    </session-config>

 5. session的特点
	 1. session用于存储一次会话的多次请求的数据,存在服务器端
	 2. session可以存储任意类型,任意大小的数据

	* session与Cookie的区别:
		1. session存储数据在服务器端,Cookie在客户端
		2. session没有数据大小限制,Cookie有
		3. session数据安全,Cookie相对于不安全

5、JSP、MVC

JSP

1. 指令
	* 作用:用于配置JSP页面,导入资源文件
	* 格式:
		<%@ 指令名称 属性名1=属性值1 属性名2=属性值2 ... %>
	* 分类:
		1. page		: 配置JSP页面的
			* contentType:等同于response.setContentType()
				1. 设置响应体的mime类型以及字符集
				2. 设置当前jsp页面的编码(只能是高级的IDE才能生效,如果使用低级工具,则需要设置pageEncoding属性设置当前页面的字符集)
			* import:导包
			* errorPage:当前页面发生异常后,会自动跳转到指定的错误页面
			* isErrorPage:标识当前也是是否是错误页面。
				* true:是,可以使用内置对象exception
				* false:否。默认值。不可以使用内置对象exception

		2. include	: 页面包含的。导入页面的资源文件
			* <%@include file="top.jsp"%>
		3. taglib	: 导入资源
			* <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
				* prefix:前缀,自定义的
2. 注释:
	1. html注释:
		<!-- -->:只能注释html代码片段
	2. jsp注释:推荐使用
		<%-- --%>:可以注释所有

3. 内置对象
	* 在jsp页面中不需要创建,直接使用的对象
	* 一共有9个:
			变量名					真实类型						作用
		* pageContext				PageContext					当前页面共享数据,还可以获取其他八个内置对象
		* request					HttpServletRequest			一次请求访问的多个资源(转发)
		* session					HttpSession					一次会话的多个请求间
		* application				ServletContext				所有用户间共享数据
		* response					HttpServletResponse			响应对象
		* page						Object						当前页面(Servlet)的对象  this
		* out						JspWriter					输出对象,数据输出到页面上
		* config					ServletConfig				Servlet的配置对象
		* exception					Throwable					异常对象

MVC:开发模式

1. jsp演变历史
	1. 早期只有servlet,只能使用response输出标签数据,非常麻烦
	2. 后来又jsp,简化了Servlet的开发,如果过度使用jsp,在jsp中即写大量的java代码,有写html表,造成难于维护,难于分工协作
	3. 再后来,java的web开发,借鉴mvc开发模式,使得程序的设计更加合理性
2. MVC:
	1. M:Model,模型。JavaBean
		* 完成具体的业务操作,如:查询数据库,封装对象
	2. V:View,视图。JSP
		* 展示数据
	3. C:Controller,控制器。Servlet
		* 获取用户的输入
		* 调用模型
		* 将数据交给视图进行展示

	* 优缺点:
		1. 优点:
			1. 耦合性低,方便维护,可以利于分工协作
			2. 重用性高

		2. 缺点:
			1. 使得项目架构变得复杂,对开发人员要求高

EL表达式

1. 概念:Expression Language 表达式语言
2. 作用:替换和简化jsp页面中java代码的编写
3. 语法:${表达式}
4. 注意:
	* jsp默认支持el表达式的。如果要忽略el表达式
		1. 设置jsp中page指令中:isELIgnored="true" 忽略当前jsp页面中所有的el表达式
		2. \${表达式} :忽略当前这个el表达式

5. 使用:
	1. 运算:
		* 运算符:
			1. 算数运算符: + - * /(div) %(mod)
			2. 比较运算符: > < >= <= == !=
			3. 逻辑运算符: &&(and) ||(or) !(not)
			4. 空运算符: empty
				* 功能:用于判断字符串、集合、数组对象是否为null或者长度是否为0
				* ${empty list}:判断字符串、集合、数组对象是否为null或者长度为0
				* ${not empty str}:表示判断字符串、集合、数组对象是否不为null 并且 长度>0
	2. 获取值
		1. el表达式只能从域对象中获取值
		2. 语法:
			1. ${域名称.键名}:从指定域中获取指定键的值
				* 域名称:
					1. pageScope		--> pageContext
					2. requestScope 	--> request
					3. sessionScope 	--> session
					4. applicationScope --> application(ServletContext)
				* 举例:在request域中存储了name=张三
				* 获取:${requestScope.name}

			2. ${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止。

			3. 获取对象、List集合、Map集合的值
				1. 对象:${域名称.键名.属性名}
					* 本质上会去调用对象的getter方法

				2. List集合:${域名称.键名[索引]}

				3. Map集合:
					* ${域名称.键名.key名称}
					* ${域名称.键名["key名称"]}


	3. 隐式对象:
		* el表达式中有11个隐式对象
		* pageContext:
			* 获取jsp其他八个内置对象
				* ${pageContext.request.contextPath}:动态获取虚拟目录

JSTL

1. 概念:JavaServer Pages Tag Library  JSP标准标签库
	* 是由Apache组织提供的开源的免费的jsp标签		<标签>

2. 作用:用于简化和替换jsp页面上的java代码		

3. 使用步骤:
	1. 导入jstl相关jar包
	2. 引入标签库:taglib指令:  <%@ taglib %>
	3. 使用标签

4. 常用的JSTL标签
	1. if:相当于java代码的if语句
		1. 属性:
            * test 必须属性,接受boolean表达式
                * 如果表达式为true,则显示if标签体内容,如果为false,则不显示标签体内容
                * 一般情况下,test属性值会结合el表达式一起使用
   		 2. 注意:
       		 * c:if标签没有else情况,想要else情况,则可以在定义一个c:if标签
	2. choose:相当于java代码的switch语句
		1. 使用choose标签声明         			相当于switch声明
        2. 使用when标签做判断         			相当于case
        3. 使用otherwise标签做其他情况的声明    	相当于default

	3. foreach:相当于java代码的for语句

三层架构:软件设计架构

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

6、Filter:过滤器

1. 概念:
	* 生活中的过滤器:净水器,空气净化器,土匪、
	* web中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能。
	* 过滤器的作用:
		* 一般用于完成通用的操作。如:登录验证、统一编码处理、敏感字符过滤...

2. 快速方法:
	1. 步骤:
		1. 定义一个类,实现接口Filter
		2. 复写方法
		3. 配置拦截路径
			1. web.xml
			2. 注解
	2. 代码:
		@WebFilter("/*")//访问所有资源之前,都会执行该过滤器
		public class FilterDemo1 implements Filter {
		    @Override
		    public void init(FilterConfig filterConfig) throws ServletException {		
		    }
		
		    @Override
		    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
		        System.out.println("filterDemo1被执行了....");
		        //放行
		        filterChain.doFilter(servletRequest,servletResponse);		
		    }
		
		    @Override
		    public void destroy() {
		
		    }
		}

3. 过滤器细节:
	1. web.xml配置	
		<filter>
	        <filter-name>demo1</filter-name>
	        <filter-class>cn.itcast.web.filter.FilterDemo1</filter-class>
	    </filter>
	    <filter-mapping>
	        <filter-name>demo1</filter-name>
			<!-- 拦截路径 -->
	        <url-pattern>/*</url-pattern>
	    </filter-mapping>
	2. 过滤器执行流程
		1. 执行过滤器
		2. 执行放行后的资源
		3. 回来执行过滤器放行代码下边的代码
	3. 过滤器生命周期方法
		1. init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次。用于加载资源
		2. doFilter:每一次请求被拦截资源时,会执行。执行多次
		3. destroy:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。只执行一次。用于释放资源
	4. 过滤器配置详解
		* 拦截路径配置:
			1. 具体资源路径: /index.jsp   只有访问index.jsp资源时,过滤器才会被执行
			2. 拦截目录: /user/*	访问/user下的所有资源时,过滤器都会被执行
			3. 后缀名拦截: *.jsp		访问所有后缀名为jsp资源时,过滤器都会被执行
			4. 拦截所有资源:/*		访问所有资源时,过滤器都会被执行
		* 拦截方式配置:资源被访问的方式
			* 注解配置:
				* 设置dispatcherTypes属性
					1. REQUEST:默认值。浏览器直接请求资源
					2. FORWARD:转发访问资源
					3. INCLUDE:包含访问资源
					4. ERROR:错误跳转资源
					5. ASYNC:异步访问资源
			* web.xml配置
				* 设置<dispatcher></dispatcher>标签即可
			
	5. 过滤器链(配置多个过滤器)
		* 执行顺序:如果有两个过滤器:过滤器1和过滤器2
			1. 过滤器1
			2. 过滤器2
			3. 资源执行
			4. 过滤器2
			5. 过滤器1 

		* 过滤器先后顺序问题:
			1. 注解配置:按照类名的字符串比较规则比较,值小的先执行
				* 如: AFilter 和 BFilter,AFilter就先执行了。
			2. web.xml配置: <filter-mapping>谁定义在上边,谁先执行

7、Listener:监听器

* 概念:web的三大组件之一。
	* 事件监听机制
		* 事件	:一件事情
		* 事件源 :事件发生的地方
		* 监听器 :一个对象
		* 注册监听:将事件、事件源、监听器绑定在一起。 当事件源上发生某个事件后,执行监听器代码

* ServletContextListener:监听ServletContext对象的创建和销毁
	* 方法:
		* void contextDestroyed(ServletContextEvent sce) :ServletContext对象被销毁之前会调用该方法
		* void contextInitialized(ServletContextEvent sce) :ServletContext对象创建后会调用该方法
		1. 定义一个类,实现ServletContextListener接口
		2. 复写方法
		3. 配置
			1. web.xml
					<listener>
 					 <listener-class>cn.itcast.web.listener.ContextLoaderListener</listener-class>
 				</listener>
 	* 指定初始化参数<context-param>
			2. 注解:
				* @WebListener

8、BOM、DOM

事件

* 功能: 某些组件被执行了某些操作后,触发某些代码的执行。
	* 造句:  xxx被xxx,我就xxx
		* 我方水晶被摧毁后,我就责备对友。
		* 敌方水晶被摧毁后,我就夸奖自己。

* 如何绑定事件
	1. 直接在html标签上,指定事件的属性(操作),属性值就是js代码
		1. 事件:onclick--- 单击事件

	2. 通过js获取元素对象,指定事件属性,设置一个函数

	* 代码:
		<body>
			<img id="light" src="img/off.gif"  onclick="fun();">
			<img id="light2" src="img/off.gif">
			
			<script>
			    function fun(){
			        alert('被点了');
			        alert('被点了');
			    }
			
			    function fun2(){
			        alert('点我?');
			    }
			
			    //1.获取light2对象
			    var light2 = document.getElementById("light2");
			    //2.绑定事件
			    light2.onclick = fun2;
</script>
		</body>

BOM

1. 概念:Browser Object Model 浏览器对象模型
	* 将浏览器的各个组成部分封装成对象。

2. 组成:
	* Window:窗口对象
	* Navigator:浏览器对象
	* Screen:显示器屏幕对象
	* History:历史记录对象
	* Location:地址栏对象

3. Window:窗口对象
    1. 创建
    2. 方法
         1. 与弹出框有关的方法:
            alert()	显示带有一段消息和一个确认按钮的警告框。
            confirm()	显示带有一段消息以及确认按钮和取消按钮的对话框。
                * 如果用户点击确定按钮,则方法返回true
                * 如果用户点击取消按钮,则方法返回false
            prompt()	显示可提示用户输入的对话框。
                * 返回值:获取用户输入的值
         2. 与打开关闭有关的方法:
            close()	关闭浏览器窗口。
                * 谁调用我 ,我关谁
            open()	打开一个新的浏览器窗口
                * 返回新的Window对象
         3. 与定时器有关的方式
            setTimeout()	在指定的毫秒数后调用函数或计算表达式。
                * 参数:
                    1. js代码或者方法对象
                    2. 毫秒值
                * 返回值:唯一标识,用于取消定时器
            clearTimeout()	取消由 setTimeout() 方法设置的 timeout。

            setInterval()	按照指定的周期(以毫秒计)来调用函数或计算表达式。
            clearInterval()	取消由 setInterval() 设置的 timeout。

    3. 属性:
        1. 获取其他BOM对象:
            history
            location
            Navigator
            Screen:
        2. 获取DOM对象
            document
    4. 特点
        * Window对象不需要创建可以直接使用 window使用。 window.方法名();
        * window引用可以省略。  方法名();

4. Location:地址栏对象
	1. 创建(获取):
		1. window.location
		2. location

	2. 方法:
		* reload()	重新加载当前文档。刷新
	3. 属性
		* href	设置或返回完整的 URL。

5. History:历史记录对象
    1. 创建(获取):
        1. window.history
        2. history

    2. 方法:
        * back()	加载 history 列表中的前一个 URL。
        * forward()	加载 history 列表中的下一个 URL。
        * go(参数)	加载 history 列表中的某个具体页面。
            * 参数:
                * 正数:前进几个历史记录
                * 负数:后退几个历史记录
    3. 属性:
        * length	返回当前窗口历史列表中的 URL 数量。

DOM

* 概念: Document Object Model 文档对象模型
	* 将标记语言文档的各个组成部分,封装为对象。可以使用这些对象,对标记语言文档进行CRUD的动态操作

* W3C DOM 标准被分为 3 个不同的部分:

	* 核心 DOM - 针对任何结构化文档的标准模型
		* Document:文档对象
		* Element:元素对象
		* Attribute:属性对象
		* Text:文本对象
		* Comment:注释对象

		* Node:节点对象,其他5个的父对象
	* XML DOM - 针对 XML 文档的标准模型
	* HTML DOM - 针对 HTML 文档的标准模型


* 核心DOM模型:
	* Document:文档对象
		1. 创建(获取):在html dom模型中可以使用window对象来获取
			1. window.document
			2. document
		2. 方法:
			1. 获取Element对象:
				1. getElementById()	: 根据id属性值获取元素对象。id属性值一般唯一
				2. getElementsByTagName():根据元素名称获取元素对象们。返回值是一个数组
				3. getElementsByClassName():根据Class属性值获取元素对象们。返回值是一个数组
				4. getElementsByName(): 根据name属性值获取元素对象们。返回值是一个数组
			2. 创建其他DOM对象:
				createAttribute(name)
            	createComment()
            	createElement()
            	createTextNode()
		3. 属性
	* Element:元素对象
		1. 获取/创建:通过document来获取和创建
		2. 方法:
			1. removeAttribute():删除属性
			2. setAttribute():设置属性
	* Node:节点对象,其他5个的父对象
		* 特点:所有dom对象都可以被认为是一个节点
		* 方法:
			* CRUD dom树:
				* appendChild():向节点的子节点列表的结尾添加新的子节点。
				* removeChild()	:删除(并返回)当前节点的指定子节点。
				* replaceChild():用新节点替换一个子节点。
		* 属性:
			* parentNode 返回节点的父节点。


* HTML DOM
	1. 标签体的设置和获取:innerHTML
	2. 使用html元素对象的属性
	3. 控制元素样式
		1. 使用元素的style属性来设置
			如:
				 //修改样式方式1
		        div1.style.border = "1px solid red";
		        div1.style.width = "200px";
		        //font-size--> fontSize
		        div1.style.fontSize = "20px";
		2. 提前定义好类选择器的样式,通过元素的className属性来设置其class属性值。

事件监听机制

* 概念:某些组件被执行了某些操作后,触发某些代码的执行。	
	* 事件:某些操作。如: 单击,双击,键盘按下了,鼠标移动了
	* 事件源:组件。如: 按钮 文本输入框...
	* 监听器:代码。
	* 注册监听:将事件,事件源,监听器结合在一起。 当事件源上发生了某个事件,则触发执行某个监听器代码。
* 常见的事件:
	1. 点击事件:
		1. onclick:单击事件
		2. ondblclick:双击事件
	2. 焦点事件
		1. onblur:失去焦点
		2. onfocus:元素获得焦点。

	3. 加载事件:
		1. onload:一张页面或一幅图像完成加载。

	4. 鼠标事件:
		1. onmousedown	鼠标按钮被按下。
		2. onmouseup	鼠标按键被松开。
		3. onmousemove	鼠标被移动。
		4. onmouseover	鼠标移到某元素之上。
		5. onmouseout	鼠标从某元素移开。
5. 键盘事件:
		1. onkeydown	某个键盘按键被按下。	
		2. onkeyup		某个键盘按键被松开。
		3. onkeypress	某个键盘按键被按下并松开。

	6. 选择和改变
		1. onchange	域的内容被改变。
		2. onselect	文本被选中。

	7. 表单事件:
		1. onsubmit	确认按钮被点击。
		2. onreset	重置按钮被点击。

9、JQuery

1. 概念: 一个JavaScript框架。简化JS开发
	* jQuery是一个快速、简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架)。jQuery设计的宗旨	是“write Less,Do More”,即倡导写更少的代码,做更多的事情。它封装JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,优	化HTML文档操作、事件处理、动画设计和Ajax交互。

	* JavaScript框架:本质上就是一些js文件,封装了js的原生代码而已
2. 快速入门
	1. 步骤:
		1. 下载JQuery
			* 目前jQuery有三个大版本:
				1.x:兼容ie678,使用最为广泛的,官方只做BUG维护,
					 功能不再新增。因此一般项目来说,使用1.x版本就可以了,
					 最终版本:1.12.4 (2016年5月20日)
				2.x:不兼容ie678,很少有人使用,官方只做BUG维护,
					 功能不再新增。如果不考虑兼容低版本的浏览器可以使用2.x,
					 最终版本:2.2.4 (2016年5月20日)
				3.x:不兼容ie678,只支持最新的浏览器。除非特殊要求,
					 一般不会使用3.x版本的,很多老的jQuery插件不支持这个版本。
					 目前该版本是官方主要更新维护的版本。最新版本:3.2.1(2017年3月20日)
			* jquery-xxx.js 与 jquery-xxx.min.js区别:
				1. jquery-xxx.js:开发版本。给程序员看的,有良好的缩进和注释。体积大一些
				2. jquery-xxx.min.js:生产版本。程序中使用,没有缩进。体积小一些。程序加载更快

		2. 导入JQuery的js文件:导入min.js文件
		3. 使用
			var div1 = $("#div1");
   				alert(div1.html());

3. JQuery对象和JS对象区别与转换
	1. JQuery对象在操作时,更加方便。
    2. JQuery对象和js对象方法不通用的.
    3. 两者相互转换
        * jq -- > js : jq对象[索引] 或者 jq对象.get(索引)
        * js -- > jq : $(js对象)

4. 选择器:筛选具有相似特征的元素(标签)

	1. 基本操作学习:
		1. 事件绑定
			//1.获取b1按钮
            $("#b1").click(function(){
                alert("abc");
            });
		2. 入口函数
			 $(function () {
	           
   			 });
			 window.onload  和 $(function) 区别
                 * window.onload 只能定义一次,如果定义多次,后边的会将前边的覆盖掉
                 * $(function)可以定义多次的。
		3. 样式控制:css方法
			 // $("#div1").css("background-color","red");
      		$("#div1").css("backgroundColor","pink");

	2. 分类
		1. 基本选择器
			1. 标签选择器(元素选择器)
				* 语法: $("html标签名") 获得所有匹配标签名称的元素
			2. id选择器 
				* 语法: $("#id的属性值") 获得与指定id属性值匹配的元素
			3. 类选择器
				* 语法: $(".class的属性值") 获得与指定的class属性值匹配的元素
			4. 并集选择器:
				* 语法: $("选择器1,选择器2....") 获取多个选择器选中的所有元素
		2. 层级选择器
			1. 后代选择器
				* 语法: $("A B ") 选择A元素内部的所有B元素		
			2. 子选择器
				* 语法: $("A > B") 选择A元素内部的所有B子元素
		3. 属性选择器
			1. 属性名称选择器 
				* 语法: $("A[属性名]") 包含指定属性的选择器
			2. 属性选择器
				* 语法: $("A[属性名='值']") 包含指定属性等于指定值的选择器
			3. 复合属性选择器
				* 语法: $("A[属性名='值'][]...") 包含多个属性条件的选择器
		4. 过滤选择器
			1. 首元素选择器 
				* 语法: :first 获得选择的元素中的第一个元素
			2. 尾元素选择器 
				* 语法: :last 获得选择的元素中的最后一个元素
			3. 非元素选择器
				* 语法: :not(selector) 不包括指定内容的元素
			4. 偶数选择器
				* 语法: :even 偶数,从 0 开始计数
			5. 奇数选择器
				* 语法: :odd 奇数,从 0 开始计数
			6. 等于索引选择器
				* 语法: :eq(index) 指定索引元素
			7. 大于索引选择器 
				* 语法: :gt(index) 大于指定索引元素
			8. 小于索引选择器 
				* 语法: :lt(index) 小于指定索引元素
			9. 标题选择器
				* 语法: :header 获得标题(h1~h6)元素,固定写法
		5. 表单过滤选择器
			1. 可用元素选择器 
				* 语法: :enabled 获得可用元素
			2. 不可用元素选择器 
				* 语法: :disabled 获得不可用元素
			3. 选中选择器 
				* 语法: :checked 获得单选/复选框选中的元素
			4. 选中选择器 
				* 语法: :selected 获得下拉框选中的元素

5. DOM操作
	1. 内容操作
		1. html(): 获取/设置元素的标签体内容   <a><font>内容</font></a>  --> <font>内容</font>
		2. text(): 获取/设置元素的标签体纯文本内容   <a><font>内容</font></a> --> 内容
		3. val(): 获取/设置元素的value属性值
	2. 属性操作
		1. 通用属性操作
			1. attr(): 获取/设置元素的属性
			2. removeAttr():删除属性
			3. prop():获取/设置元素的属性
			4. removeProp():删除属性

			* attr和prop区别?
				1. 如果操作的是元素的固有属性,则建议使用prop
				2. 如果操作的是元素自定义的属性,则建议使用attr
		2. 对class属性操作
			1. addClass():添加class属性值
			2. removeClass():删除class属性值
			3. toggleClass():切换class属性
				* toggleClass("one"): 
					* 判断如果元素对象上存在class="one",则将属性值one删除掉。  如果元素对象上不存在class="one",则添加
			4. css():
	3. CRUD操作:
		1. append():父元素将子元素追加到末尾
			* 对象1.append(对象2): 将对象2添加到对象1元素内部,并且在末尾
		2. prepend():父元素将子元素追加到开头
			* 对象1.prepend(对象2):将对象2添加到对象1元素内部,并且在开头
		3. appendTo():
			* 对象1.appendTo(对象2):将对象1添加到对象2内部,并且在末尾
		4. prependTo():
			* 对象1.prependTo(对象2):将对象1添加到对象2内部,并且在开头

		5. after():添加元素到元素后边
			* 对象1.after(对象2): 将对象2添加到对象1后边。对象1和对象2是兄弟关系
		6. before():添加元素到元素前边
			* 对象1.before(对象2): 将对象2添加到对象1前边。对象1和对象2是兄弟关系
		7. insertAfter()
			* 对象1.insertAfter(对象2):将对象2添加到对象1后边。对象1和对象2是兄弟关系
		8. insertBefore()
			* 对象1.insertBefore(对象2): 将对象2添加到对象1前边。对象1和对象2是兄弟关系

		9. remove():移除元素
			* 对象.remove():将对象删除掉
		10. empty():清空元素的所有后代元素。
			* 对象.empty():将对象的后代元素全部清空,但是保留当前对象以及其属性节点

10、Redis

1. 概念: redis是一款高性能的NOSQL系列的非关系型数据库
1.1.什么是NOSQL
		NoSQL(NoSQL = Not Only SQL),意即“不仅仅是SQL”,是一项全新的数据库理念,泛指非关系型的数据库。
		随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。

		1.1.1.	NOSQL和关系型数据库比较
			优点:
				1)成本:nosql数据库简单易部署,基本都是开源软件,不需要像使用oracle那样花费大量成本购买使用,相比关系型数据库价格便宜。
				2)查询速度:nosql数据库将数据存储于缓存之中,关系型数据库将数据存储在硬盘中,自然查询速度远不及nosql数据库。
				3)存储数据的格式:nosql的存储格式是key,value形式、文档形式、图片形式等等,所以可以存储基础类型以及对象或者是集合等各种格式,而数据库则只支持基础类型。
				4)扩展性:关系型数据库有类似join这样的多表查询机制的限制导致扩展很艰难。

			缺点:
				1)维护的工具和资料有限,因为nosql是属于新的技术,不能和关系型数据库10几年的技术同日而语。
				2)不提供对sql的支持,如果不支持sql这样的工业标准,将产生一定用户的学习和使用成本。
				3)不提供关系型数据库对事务的处理。

		1.1.2.	非关系型数据库的优势:
			1)性能NOSQL是基于键值对的,可以想象成表中的主键和值的对应关系,而且不需要经过SQL层的解析,所以性能非常高。
			2)可扩展性同样也是因为基于键值对,数据之间没有耦合性,所以非常容易水平扩展。

		1.1.3.	关系型数据库的优势:
			1)复杂查询可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询。
			2)事务支持使得对于安全性能很高的数据访问要求得以实现。对于这两类数据库,对方的优势就是自己的弱势,反之亦然。

		1.1.4.	总结
			关系型数据库与NoSQL数据库并非对立而是互补的关系,即通常情况下使用关系型数据库,在适合使用NoSQL的时候使用NoSQL数据库,
			让NoSQL数据库对关系型数据库的不足进行弥补。
			一般会将数据存储在关系型数据库中,在nosql数据库中备份存储关系型数据库的数据

	1.2.主流的NOSQL产品
		•	键值(Key-Value)存储数据库
				相关产品: Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB
				典型应用: 内容缓存,主要用于处理大量数据的高访问负载。 
				数据模型: 一系列键值对
				优势: 快速查询
				劣势: 存储的数据缺少结构化
		•	列存储数据库
				相关产品:Cassandra, HBase, Riak
				典型应用:分布式的文件系统
				数据模型:以列簇式存储,将同一列数据存在一起
				优势:查找速度快,可扩展性强,更容易进行分布式扩展
				劣势:功能相对局限
		•	文档型数据库
				相关产品:CouchDB、MongoDB
				典型应用:Web应用(与Key-Value类似,Value是结构化的)
				数据模型: 一系列键值对
				优势:数据结构要求不严格
				劣势: 查询性能不高,而且缺乏统一的查询语法
		•	图形(Graph)数据库
				相关数据库:Neo4J、InfoGrid、Infinite Graph
				典型应用:社交网络
				数据模型:图结构
				优势:利用图结构相关算法。
				劣势:需要对整个图做计算才能得出结果,不容易做分布式的集群方案。
	1.3 什么是Redis
		Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,官方提供测试数据,50个并发执行100000个请求,读的速度是110000次/s,写的速度是81000次/s ,且Redis通过提供多种键值数据类型来适应不同场景下的存储需求,目前为止Redis支持的键值数据类型如下:
			1) 字符串类型 string
			2) 哈希类型 hash
			3) 列表类型 list
			4) 集合类型 set
			5) 有序集合类型 sortedset
		1.3.1 redis的应用场景
			•	缓存(数据查询、短连接、新闻内容、商品内容等等)
			•	聊天室的在线好友列表
			•	任务队列。(秒杀、抢购、12306等等)
			•	应用排行榜
			•	网站访问统计
			•	数据过期处理(可以精确到毫秒
			•	分布式集群架构中的session分离
2. 下载安装
	1. 官网:https://redis.io
	2. 中文网:http://www.redis.net.cn/
	3. 解压直接可以使用:
		* redis.windows.conf:配置文件
		* redis-cli.exe:redis的客户端
		* redis-server.exe:redis服务器端
	
3. 命令操作
	1. redis的数据结构:
		* redis存储的是:key,value格式的数据,其中key都是字符串,value有5种不同的数据结构
			* value的数据结构:
				1) 字符串类型 string
				2) 哈希类型 hash : map格式  
				3) 列表类型 list : linkedlist格式。支持重复元素
				4) 集合类型 set  : 不允许重复元素
				5) 有序集合类型 sortedset:不允许重复元素,且元素有顺序
	
	2. 字符串类型 string
		1. 存储: set key value
			127.0.0.1:6379> set username zhangsan
			OK
		2. 获取: get key
			127.0.0.1:6379> get username
			"zhangsan"
		3. 删除: del key
			127.0.0.1:6379> del age
			(integer) 1
	3. 哈希类型 hash
		1. 存储: hset key field value
			127.0.0.1:6379> hset myhash username lisi
			(integer) 1
			127.0.0.1:6379> hset myhash password 123
			(integer) 1
		2. 获取: 
			* hget key field: 获取指定的field对应的值
				127.0.0.1:6379> hget myhash username
				"lisi"
			* hgetall key:获取所有的field和value
				127.0.0.1:6379> hgetall myhash
				1) "username"
				2) "li"
				3) "password"
				4) "123"
				
		3. 删除: hdel key field
			127.0.0.1:6379> hdel myhash username
			(integer) 1
	
	4. 列表类型 list:可以添加一个元素到列表的头部(左边)或者尾部(右边)
		1. 添加:
			1. lpush key value: 将元素加入列表左表
				
			2. rpush key value:将元素加入列表右边
				
				127.0.0.1:6379> lpush myList a
				(integer) 1
				127.0.0.1:6379> lpush myList b
				(integer) 2
				127.0.0.1:6379> rpush myList c
				(integer) 3
		2. 获取:
			* lrange key start end :范围获取
				127.0.0.1:6379> lrange myList 0 -1
				1) "b"
				2) "a"
				3) "c"
		3. 删除:
			* lpop key: 删除列表最左边的元素,并将元素返回
			* rpop key: 删除列表最右边的元素,并将元素返回
5. 集合类型 set : 不允许重复元素
		1. 存储:sadd key value
			127.0.0.1:6379> sadd myset a
			(integer) 1
			127.0.0.1:6379> sadd myset a
			(integer) 0
		2. 获取:smembers key:获取set集合中所有元素
			127.0.0.1:6379> smembers myset
			1) "a"
		3. 删除:srem key value:删除set集合中的某个元素	
			127.0.0.1:6379> srem myset a
			(integer) 1
	6. 有序集合类型 sortedset:不允许重复元素,且元素有顺序.每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

		1. 存储:zadd key score value
			127.0.0.1:6379> zadd mysort 60 zhangsan
			(integer) 1
			127.0.0.1:6379> zadd mysort 50 lisi
			(integer) 1
			127.0.0.1:6379> zadd mysort 80 wangwu
			(integer) 1
		2. 获取:zrange key start end [withscores]
			127.0.0.1:6379> zrange mysort 0 -1
			1) "lisi"
			2) "zhangsan"
			3) "wangwu"

			127.0.0.1:6379> zrange mysort 0 -1 withscores
			1) "zhangsan"
			2) "60"
			3) "wangwu"
			4) "80"
			5) "lisi"
			6) "500"
		3. 删除:zrem key value
			127.0.0.1:6379> zrem mysort lisi
			(integer) 1

	7. 通用命令
		1. keys * : 查询所有的键
		2. type key : 获取键对应的value的类型
		3. del key:删除指定的key value
4. 持久化
	1. redis是一个内存数据库,当redis服务器重启,获取电脑重启,数据会丢失,我们可以将redis内存中的数据持久化保存到硬盘的文件中。
	2. redis持久化机制:
		1. RDB:默认方式,不需要进行配置,默认就使用这种机制
			* 在一定的间隔时间中,检测key的变化情况,然后持久化数据
			1. 编辑redis.windwos.conf文件
				#   after 900 sec (15 min) if at least 1 key changed
				save 900 1
				#   after 300 sec (5 min) if at least 10 keys changed
				save 300 10
				#   after 60 sec if at least 10000 keys changed
				save 60 10000
				
			2. 重新启动redis服务器,并指定配置文件名称
				D:\xxxx\redis-2.8.9>redis-server.exe redis.windows.conf	
			
		2. AOF:日志记录的方式,可以记录每一条命令的操作。可以每一次命令操作后,持久化数据
			1. 编辑redis.windwos.conf文件
				appendonly no(关闭aof) --> appendonly yes (开启aof)
				
				# appendfsync always : 每一次操作都进行持久化
				appendfsync everysec : 每隔一秒进行一次持久化
				# appendfsync no	 : 不进行持久化

5. Java客户端 Jedis
	* Jedis: 一款java操作redis数据库的工具.
	* 使用步骤:
		1. 下载jedis的jar包
		2. 使用
			//1. 获取连接
    		Jedis jedis = new Jedis("localhost",6379);
   			//2. 操作
   			jedis.set("username","zhangsan");
    		//3. 关闭连接
    		jedis.close();
* Jedis操作各种redis中的数据结构
		1) 字符串类型 string
			set
			get
			
			 //1. 获取连接
	        Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
	        //2. 操作
	        //存储
	        jedis.set("username","zhangsan");
	        //获取
	        String username = jedis.get("username");
	        System.out.println(username);
	
	        //可以使用setex()方法存储可以指定过期时间的 key value
	        jedis.setex("activecode",20,"hehe");//将activecode:hehe键值对存入redis,并且20秒后自动删除该键值对
	
	        //3. 关闭连接
	        jedis.close();

		2) 哈希类型 hash : map格式  
			hset
			hget
			hgetAll
			//1. 获取连接
	        Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
	        //2. 操作
	        // 存储hash
	        jedis.hset("user","name","lisi");
	        jedis.hset("user","age","23");
	        jedis.hset("user","gender","female");
	
	        // 获取hash
	        String name = jedis.hget("user", "name");
	        System.out.println(name);
     // 获取hash的所有map中的数据
	        Map<String, String> user = jedis.hgetAll("user");
	
	        // keyset
	        Set<String> keySet = user.keySet();
	        for (String key : keySet) {
	            //获取value
	            String value = user.get(key);
	            System.out.println(key + ":" + value);
	        }
	
	        //3. 关闭连接
	        jedis.close();
	3) 列表类型 list : linkedlist格式。支持重复元素
			lpush / rpush
			lpop / rpop
			lrange start end : 范围获取
			
			 //1. 获取连接
	        Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
	        //2. 操作
	        // list 存储
	        jedis.lpush("mylist","a","b","c");//从左边存
	        jedis.rpush("mylist","a","b","c");//从右边存
	
	        // list 范围获取
	        List<String> mylist = jedis.lrange("mylist", 0, -1);
	        System.out.println(mylist);
	        
	        // list 弹出
	        String element1 = jedis.lpop("mylist");//c
	        System.out.println(element1);
	
	        String element2 = jedis.rpop("mylist");//c
	        System.out.println(element2);
	
	        // list 范围获取
	        List<String> mylist2 = jedis.lrange("mylist", 0, -1);
	        System.out.println(mylist2);
	
	        //3. 关闭连接
	        jedis.close();
4) 集合类型 set  : 不允许重复元素
			sadd
			smembers:获取所有元素

			//1. 获取连接
	        Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
	        //2. 操作
 // set 存储
	        jedis.sadd("myset","java","php","c++");
	
	        // set 获取
	        Set<String> myset = jedis.smembers("myset");
	        System.out.println(myset);
	
	        //3. 关闭连接
	        jedis.close();
5) 有序集合类型 sortedset:不允许重复元素,且元素有顺序
			zadd
			zrange

			//1. 获取连接
	        Jedis jedis = new Jedis();//如果使用空参构造,默认值 "localhost",6379端口
	        //2. 操作
	        // sortedset 存储
	        jedis.zadd("mysortedset",3,"亚瑟");
	        jedis.zadd("mysortedset",30,"后裔");
	        jedis.zadd("mysortedset",55,"孙悟空");
	
	        // sortedset 获取
	        Set<String> mysortedset = jedis.zrange("mysortedset", 0, -1);
	
	        System.out.println(mysortedset);
	        //3. 关闭连接
	        jedis.close();
* jedis连接池: JedisPool
		* 使用:
			1. 创建JedisPool连接池对象
			2. 调用方法 getResource()方法获取Jedis连接
				//0.创建一个配置对象
		        JedisPoolConfig config = new JedisPoolConfig();
		        config.setMaxTotal(50);
		        config.setMaxIdle(10);
		
		        //1.创建Jedis连接池对象
		        JedisPool jedisPool = new JedisPool(config,"localhost",6379);
		
		        //2.获取连接
		        Jedis jedis = jedisPool.getResource();
		        //3. 使用
		        jedis.set("xxx","xxx");
 //4. 关闭 归还到连接池中
		        jedis.close();
		
		* 连接池工具类
			public class JedisPoolUtils {

			    private static JedisPool jedisPool;
			
			    static{
			        //读取配置文件
			        InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
			        //创建Properties对象
			        Properties pro = new Properties();
			        //关联文件
			        try {
			            pro.load(is);
			        } catch (IOException e) {
			            e.printStackTrace();
			        }
			        //获取数据,设置到JedisPoolConfig中
			        JedisPoolConfig config = new JedisPoolConfig();
			        config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal")));
			        config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle")));
			
			        //初始化JedisPool
			        jedisPool = new JedisPool(config,pro.getProperty("host"),Integer.parseInt(pro.getProperty("port")));}
			    public static Jedis getJedis(){
			        return jedisPool.getResource();
			    }
			}

11、01-jdbcTeamplate增删改查

1.导入相关的jar包依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>org.java</groupId>
	<artifactId>spring-springjdbctemplate</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<properties>
		<spring-version>4.3.2.RELEASE</spring-version>
	</properties>
	<dependencies>
		<!-- spring:core -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring-version}</version>
		</dependency>
		<!-- spring-jdbc -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring-version}</version>
		</dependency>
		<!-- spring-tx -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${spring-version}</version>
		</dependency>
		<!-- mysql -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.38</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>
		<!-- springTest -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>4.3.2.RELEASE</version>
			<scope>test</scope>
		</dependency>
		<!-- 使用c3p0作为数据库连接池 -->
		<dependency>
			<groupId>com.mchange</groupId>
			<artifactId>c3p0</artifactId>
			<version>0.9.5.2</version>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.8</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>
</project>

2.编写接口和实现

public class Book {
	private Integer id;
	private String name;
	private Double price;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Double getPrice() {
		return price;
	}
	public void setPrice(Double price) {
		this.price = price;
	}
	
}

import java.util.List;

public interface BookDao {
	//添加书籍信息
	void save(Book book);
	//修改
	void update(Book book);
	
	//根据id查询
	Book getById(Integer id);
	/**
	 * 查询总的信息条数
	 * @return
	 */
	int getCount();
	//根据书的名字模糊查询
	List<Book> getByNameLike(String name);
}

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;

public class BookDaoImpl extends JdbcDaoSupport implements BookDao {
	@Override
	public void save(Book book) {
		String sql = "INSERT INTO book(`name`,`price`) VALUES(?,?)";
		super.getJdbcTemplate().update(sql, book.getName(),book.getPrice());
	}

	@Override
	public void update(Book book) {
		String sql = "update book set name=?,price=? where id=?";
		super.getJdbcTemplate().update(sql, book.getName(),book.getPrice(),book.getId());
	}

	@Override
	public Book getById(Integer id) {
		String sql = "select * from book where id=?";
		return super.getJdbcTemplate().queryForObject(sql, new BeanPropertyRowMapper<Book>(Book.class),id);
	}

	@Override
	public int getCount() {
		String sql = "select count(1) from book";
		return super.getJdbcTemplate().queryForObject(sql, Integer.class);
	}

	@Override
	public List<Book> getByNameLike(String name) {
		String sql = "select * from book where name like ?";
		return super.getJdbcTemplate().query(sql, new BeanPropertyRowMapper<Book>(Book.class),"%"+name+"%");
	}
}

3.编写spring的核心配置文件’

<?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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
	<!-- 目标:将数据源和JdbcTemplate都交给spring来管理 -->
		 <!-- 使用c3p0作为连接池 -->
	 <bean id="mydataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
		<constructor-arg name="url" value="jdbc:mysql://localhost:3306/mybatis"></constructor-arg>
		<constructor-arg name="username" value="root"></constructor-arg>
		<constructor-arg name="password" value="root"></constructor-arg>
	</bean>
	
	<!-- 配置jdbcTemplate -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<constructor-arg name="dataSource" ref="mydataSource"></constructor-arg>
	</bean>
	
	
	<!-- 配置bookDao的实现 -->
	<bean id="bookDao" class="cn.kgc.dao.impl.BookDaoImpl">
		<!-- <property name="dataSource" ref="mydataSource"></property>	 -->
		<property name="jdbcTemplate" ref="jdbcTemplate"></property>
	</bean>
</beans>


4.测试

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")
public class SpringTest {
	@Autowired
	private BookDao bookDao;
	@Test
	public void testSave(){
		Book book = new Book();
		book.setName("xx");
		book.setPrice(xx);
		bookDao.save(book);
	}
	
	@Test
	public void testUpdate(){
		Book book = new Book();
		book.setId(4);
		book.setName("xx");
		book.setPrice(xx);
		bookDao.update(book);
	}
	@Test
	public void testFindById(){
		Book s = bookDao.getById(1);
		System.out.println(s);
	}
	
	@Test
	public void testgetCount(){
		int count = bookDao.getCount();
		System.out.println(count);
	}
	@Test
	public void testgetNameLike(){
		List<Book> byNameLike = bookDao.getByNameLike("天");
		System.out.println(byNameLike);
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值