hibernate&rr&jsp&Session&cookie 向右看齐 2022-06-11 01:29 88阅读 0赞 //////////RR/////////// 案例:文件下载 response:响应 作用: 往浏览器写东西 组成部分 : 响应行 响应头 响应体 操作响应行 格式: 协议/版本 状态码 状态码说明 状态码: 1xx:已发送请求 2xx:已完成响应 200:正常 响应 3xx:还需要浏览器的近一步操作 302:重定向 配合响应头:location 304:读缓存 4xx:用户操作错误 404:用户操作错误 405:访问的方法不存在 5xx:服务器错误 500:内部异常 常用方法: setStatus(int 状态 码):针对于1,2,3 了解: sendError(int 状态码)针对于 4xx 5xx 操作响应头 格式:key/value(value可以是多个值) 常用方法 setHeader(Striing key,String value):设置字符串形式的响应头 setIntHeader(Striing key,int value):设置整形形式的响应头 setDateHeader(Striing key,String value):设置时间形式的响应头 addHeader(Striing key,String value):添加字符串形式的响应头 addHeader(Striing key,int value)添加整形形式的响应头 addHeader(Striing key,long value):添加时间形式的响应头 常用 的响应头: location:重定向 refresh:定时刷新 content-type:设置文件mime类型,设置响应流的编码和告诉浏览器用啥编码打开 content-disposition文件下载需要的操作 重定向: 方式一 :掌握 response.sendRedirect("路径名“) 方式二:了解 response.setStatus(302); response.setHeader("location","路径"); 操作响应体 页面上要展示的内容 常用的方法: Writer getWriter():字符流 ServletOutputStream getOutputStream();字节流 自己写的东西用字符流,其他都用字节流 处理响应中文乱码 方式一:掌握 response.setContentType("text/html;charset=utf-8") 方式二:理解 response.setHeader("content-type","text/html;charset=utf-8"); 注意: 两个流互斥 当响应完成之后,服务器会判断一下流是否关闭,没有关闭,服务器会帮我们关闭(底层用的缓冲 流) // 测试hibernate框架 1:先加载配置文件 Configuation config=new Confoguation(); //默认加载src目录下hibernate.cfg.xml的 配置文件 config.configure(); 2:创建SessionFactory对象,生成Session对象 SessionFactory factory=config.buildSessionFactory(); 3:创建session对象 Session session=factory.openSession(); 4:开启事物 Transaction tr=session.beginTransaction(); 5:编写保存的代码 Customer c=new Customer(); //主键是 自动递增 c.setCust_name(“测试”); c.setCust_lever("2"); c.setCust_phone("110"); //保存数据,操作对象就是相当于操作数据库的表结构 session.save(c); 6:提交事务 tr.commit(); 7:释放资源 session.close(); factory.closs(); 快速入门; 1:下载Hibernate框架的开发包 2:编写数据库和表结构 3:创建web项目,导入了开发的jar包, Mysql驱动包,Hibernate开发的必须要又的jar包,日志的包 4:编写javaBean 以后不使用基本数据类型,使用包装类 5:编写映射 的配置文件(核心)先导入开发的约束,里面正常配置标签 6:编写hibernate的核心配置文件,里面的内容是固定的 7:编写代码,使用类和方法 可选的配置: hibernate.show_aql 显示sql hibernate.format_aql 格式化SQL hibernate.hbm2ddl_auto 通过映射转成DDl语句 create 每次都会创建一个新的表 create-drop 每次都会创建一个新的表,当执行就结束后,将创建的表 删除 update 如果有表就使用原来的表,没有就创建一个新的表,同时更新表结构 validate 如果有表,使用原来的表。同时校验映射 文件与表中字段是否一致,如果不一致就会报错 加载映射: 如果xml方式:<mapping resource="cn/itcast/hibernate/domain/User.hbm.xml"/> 特点: 不是线程安全的,应该避免多个线程使用同一个seccoin实例 它是轻量级的,它的创建和销毁不会消耗太多的资源,应为每次客户请求的时候分配独立的Session实例 Session 有一个缓存,被称为Hibernate的一级缓存,每个Session实例都有自己的缓存 常用方法: save(obj) delete(obj) get(Class.id) update(obj) saveOrUpdate(obj) 保存或者修改(如果没有数据,保存数据,如果有,修改数据) createQuery() HQL语句的查询方式 Transaction接口 Transaction 是事务的接口 常用方法: commit()-----提交事务 rollback() 回滚事务 特点: hibernate框架默认情况下事务不自动提交,需要手动提交事务 如果没有开启事务,那么每个Session的操作,都相当于一个独立的事务 持久化类: 1:持久化类讲究是一个java类(编写的javaBean)这个 java类与表建立了映射的关系就可以称为 持久化类 持久化类=javaBean+xxx.hhbn.xml 持久化类的编写规范 1:提供一个无参数的public 访问控制符的构造器 底层就行反射 2:提供一个标识属性 映射数据表主键字段 唯一标识OID,数据库中通过主键java对象地址确定对象,持久化类通过唯一标识OID确定记录 3:所有属性提供public 访问控制符的set或者get方法 4:标识属性应尽量使用基本数据类型的包装类型 区分自然主键和代理主键 1:创建表的时候: 自然主键:对象本身的一个属性,创建一个人员表,每个人都有一个身份证号(唯一的)使用身份证号作为表的主键,自然主键(开发中不会使用这种方式) 代理主键:不是对象本身的一个属性,创建一个人员表,为每个人员单独创建一个字段,用这个字段作为主键,代理 主键(开发中推荐使用这种) 2:创建表的时候尽量代理主键 创建表 主键的生成策略 1:increment:适用于 short int long 作为主键,不是使用的数据库自动增长机制 hibernate中提供的一种增长机制 *先进行查询 select max(id) from user; *再进行插入 获得最大值+1作为新的纪录的主键 *问题:不能再集群环境下或者有并发访问的情况下使用 2:identity:使用于short int long 作为主键。但是这个必须使用再有自动增长的数据库中,采用的是数据库底层的自动增长机制 底层使用的是数据库的自动增长(auto_increment)像oracle数据库没有自动增长 3:sequence:适用于short int long 作为主键 底层使用的 是序列的增长方式 Oracle数据 库层没有自动增长,想自动增长需要使用序列 4:uuid:使用于char varchar类型作为主键 使用随机的字符串作为主键 5:native:本地策略,根据底层数据库不同,自动选择适用于该数据库的生成策略(short int long ) 如果底层使用的MySQL数据库,相当于identity 如果底层使用的是oracle数据库,相当于seqence 6:assigned主键的 生成不用hibernate管理了,必须手动设置 持久化对象的状态: Hibernate的持久化类 *持久化类:java类与数据库的某个表建立了映射关系,这个类 就是持久化类 *持久化类=java类+hbm的配置文件 2:Hibernate的持久化类的状太: hibernate为了管理持久化类:将持久化 类分成了三个 状态 1:瞬时太:Transient Object *没有持久化标识的OID,没有被纳入到Session对象管理 2:持久太:persistent Object *没有持久化标识的oid已经被纳入到Session对象的管理 *注意:持久化持久态的对象有自动跟新数据库的能力 3:脱管态:Detached Object *有持久化标识的OID,没有纳入到Session对象的管理 Session对象的一级缓存 1:什么是缓存? *其实就是一块内存空间,将数据或者文件中的数据存放到缓存中,再次读取的时候,直接从缓存中 获取,可以提升程序的性能 2:Hibernate框架提供了两种缓存 *一级缓存 自带的不可卸载的,一级缓存的生命周期与session一致,一级缓存称为session级别的缓存 *二级缓存 默认没有开启,需要手动配置猜可以使用的,二级缓存可以再多个 session中共享数据,二级缓存称为是sessionFactory级别的缓存。 3:session对象的缓存概述 *session接口中,有一系列的java集合构成了session级别的缓存(一级缓存)将对象 存入到一级缓存中,session没有结束生命周期,那么对象再session中存放着。 4:证明一级缓存的存在,编写查询代码就可以证明 *再同一个Session对象中两次查询,可以证明使用了缓存 5:hibernate框架是如何做到数据发生变化时进行同步的操作的 ? *使用get方法查询User对象 *然后设置User对象的一个 属性,注意,没有做update操作,发现数据库中的记录也改变了 *利用快照机制来完成的(SnapShot) 控制一级缓存: 1:学习Session接口中与一级缓存相关的方法 *Session.clear()-------清空缓存 *Session.evict(Object entity) 从一级缓存中清除指定的尸体对象 *Session.flush() 刷出缓存 解决的办法丢失跟新的问题 悲观锁: *使用session.get(Customer.class 1.LockMode.UPGRADE);方法 乐观锁 1:再对应的JavaBean中添加一个属性,名称可以是任意的, 2:再映射的配置文件中提供<version name="version"/>方法 ThreadLocal类,底层是Map集合 Map<"当前的线程",值> map.put("当前的线程",值); map.get("当前的线程"); 绑定本地的session 1:之前在讲javaWEB的事务的时候,需要 在业务层使用Connection来开启事务 *一种是通过参数的方式传递 *另一种是通过把Connection绑定到ThreadLocal对象中 2:现在的Hibernate框架中,使用session对象开启事务,所以需要来传递session对象,框架提供了ThreadLocal的方式 *需要在hiberate。cfg.xml的配置文件中提供配置 *<property name="hibernate.current_session_content_class">thread</property> *重新HibernateUtil的工具类,使用sessionFactory的getCurrentSession()方法,获取当前的session对象,并且在Session对象不用手东来关闭,线程结束了,回自动的关闭 *注意,想使用getCurrentSession()方法,必须配置才能使用 Criteria查询接口(做条件查询非常的合适) Criterion 是Hibernate提供的一个条件查询的对象,想传入的使用 工具类Restrictions可以简化开发。它提供的静态的方法,拼接查询的条件 (QBC) 案例:记录用户上次访问的时间 需求: 当 用户第一次的登陆的时候,提示:你 是 第一次访问,且记录该访问时间, 下一次访问的时候,获取上一次访问时间且展示出来 技术会话: 会话技术 cookie jsp jsp:java server page(java服务器的页面) 本质上jsp就是一个serverlet,在heml代码中嵌套java代码 运行在服务器端,处理请求,生成动态的内容 对应的java和class文件在tomcat目录ixa的work目录 后追名.jsp 执行的流程: 1:浏览器发送请求,访问jsp页面 2:服务器接收请求,jspSerlvet回帮 我们查找 对应的jsp页面 3:服务器讲jsp页面翻译成java文件 4:jvm会将java编译成.class文件 5:服务器运行class文件,生成动态的内容 6:讲内容发送给服务器 7:服务器组成响应信息,发送给浏览器 8:浏览器接受 数据,解析展示 jsp的脚本: java程序的片段:<%....%> 生成jsp的service方法中 输出表达式:<%=..%> 生成jsp的service方法中,相当于在java中调用out.print() 声明成员:<%!...%> 成员的位置上 ///////////////////// 会话技点 当用户打开浏览器的时候,访问不同的资源,知道用户讲浏览器关闭,可以认为 是一次会话 作用: 因为http协议是一个无状太的协议,它记录不上上次访问的内容,用户在访问过程中难免回产生一些数据,通过会话 技术可以将它保存起来 例如: 用户登录 验证码 购物车 访问记录 分类: cookie:浏览器端会话技术 session服务器端的会话技术 ///////////////// cookie: 小饼干 小甜点 cookie是由服务器生成,通过response将cookie写回浏览器(set-cookie)保留在浏览器上 下一次访问,浏览器根据一定的规则携带不同的cookie(通过request的头cookie)我们服务器就可以就接受cookie cookie的api: new Cookie(String key,String value) 写回 浏览器 response.addCookie(Cookie c) 获取cookie: cookiee的常用方法: getName()获取cookie的key(名称) getValue:获取指定的cookie 的值 //////////////// 案例:步骤分析: 1:创建一个servelt RemServlet 路径:/rem 2:在servlet中: 获取指定的cookie例如:名称为lastTime response.getCookies() 判断cookie是否为空 cookit的常用方法: setMaxAge(int 秒):设置cookie在浏览器 端存活的时间,以秒为单位 如果设置为0:删除该cookie(前提必须路径一致) setPath(String path):设置cookie的 路径 当 我们访问的路径中包含次cookie的path,就携带 默认路径: 访问servlet的路径,从”/项目名称"开始,到最后一个“/"结束 例如: 访问的servlet路径: /day/a/b 默认路径就是: /day/a 手动设置路径:以"/项目名”开始 将数组 转换成集合: String []arr=ids.split("-"); List<String> asList=Arrays.asList(arr); //将aslist放入新list中 LinkedList<String> list=new LinkedList<>(asList); 扩展:删除浏览记录 1:在浏览器记录中添加一个超连接 <a href="/daay/clearHistory">清空</a> 2:创建servelt ClearHistory 创建一个cookie 名称保持一致 setMaxAge(0) 写回浏览器 3:页面跳转 重定向 product_list.jsp 注意cookie不能垮浏览器 cookie中不支持 中文 案例:添加购物车 需求: 在商品 详情页面有一个添加到购物车,点击 则将该商品添加到购物车 ,点击购物车连接将里面的所有商品 展示出来 技术分析: session session: 服务器端会话技术 当我们第一次访问的服务器的时候,服务器 获取id, 能获取id 要拿着这个id去服务器中查找有无次session 若查找到了:直接拿过来的时候 ,将数据保存,需要将当前session的 id返回给浏览器 若查找找不到:创建 不能获取id 创建一个session,将你的 数据保存在这个session中,将 当前session的id返回给浏览器 获取一个 session: HttpSession request.getSession() 域对象: xxxxAttribute 生命周期: 创建:第一次调用request.getSession()创建 销毁: 服务器非 正常 关闭 session超时 默认时间超时:30分钟 web.xml有配置 手动的设置超时:setMaxInactiveInterval(int 秒) 手动 干掉:session *(重要)session.invalidate() 存放的私有数据 /////////////// 步骤分析: 1:点击添加到购物车的时候,提交到一个servlet add2CartServlet 需要将 商品名称携带过去 2:add2CartServlet中的操作 获取商品的名称 将商品添加到购物车,购物车的结构Map<String 名称,Integer 购买数量> 将购物车放入session中就可以了 将商品添加到购物车分析: 获取购物车 判断购物车是否为空】如果是空 : 这是第一次添加 创建一个购物车 将商品put进去 若不为空:继续判断购物车中是否有该 商品 若有: 取出count将数量+1 将商品再次放入购物车中 若没有:将商品 put进去 数量+1 提示信息:你的xx已经添加到购物车 中 3:点击购物车连接的时候 从session获取购物车 判断购物车是否为空 若为空:提示信息 若 不为空 :遍历 session依赖于cookie 三个域对象 ServletContent:共享的数据 HttpServletRequest;一次请求的 数据 HttpSession:私有的数据 /////////////// 案例1-在页面中展示所有的商品信息,不要使用jsp的脚本 技术分析: jsp/el/jst1 jsp: java服务器页面 作用: 将内容生成和信息的 展示想分离 运行在服务器端,本质上就是一个serlet,产生的Java文件和class保留在tomcat的 work目录下 jsp脚本: <%...%>java代码片段 <%=..%>输出表达式 相当于out.print() <%!...%>声明成员 jsp指令 作用:声明jsp页面的一些属性和动作 格式: <%@指令名称 属性=“值” 属性=“值”> 指令的分类: page:主要声明jsp页面的一些属性 include:静态的包含 taglib:导入标签库 注意: 一个页面中可以出现多个指令 指令可以放在任意的位置,一般放在jsp页面的最上面 //////////// page指令: 重要的属性3个: contentType:设置响应流的编码,以及通知 浏览器用什么编码打开,设置文件的mimetype pageEncoding:设置页面的编码 import:导入所需要的包 contentType和pageEncoding联系 若两者都出现的时候,各自使用各自的编码 若只出现一者,两个都使用出现的这个编码 若两个都不出现,使用服务器默认的编码 tomcat使用iso-8859-1 了解属性 language:当前jsp页面里面可以嵌套的语言(现在只能java) buffer:设置jsp页面也买你的流的缓冲区的大小 autoFlush;是否自动刷新 extends:声明当前的jsp页面继承于哪个类,必须继承 的是httpservlet以及它的子类 session:设置jsp页面是否可以使用session内置对象 isELIgnored:是否忽略el表达式; errorPage:当前jsp页面 出现异常的时候要跳转的jsp页面 isErrorPage:当前jsp页面是否是一个错误的页面 若为true 可以使用jsp页面的一个内置对象exception include指令: 静态包含,就是将其他页面或者servlet的 内容 包含进来,一起进行编译运行,生成一个java文件你 格式: <%@include file="相对路径或者是内部的路径"%> 路径: 相对路径: ./或者什么都不写 当前的路径 上一级路径 ../ 绝对路径: 带协议和主机的绝对路径 不带协议和主机的绝对路径 /项目名/资源 内部路径: 不带协议和主机的绝对路径去掉项目名 请求转发 静态包含 动态包含 taglib指令:导入标签库 格式: <%@taglib perfix="前缀名" uri="名称空间"%> 若导入之后: <前缀名:标签。。> 例如: <c:if text="">输出的内容</c:if> jsp的内置对象 :(9大内置对象) 在jsp页面上可以直接使用的 对象 内置对象 类型 out JspWriter request HttpServletRequest response HttpServletReaponse session HttpSession exception Throwable page Servlet(this) config ServletConfig application PageContext jsp的域对象 application 整个项目 session 一次会话 request 一次请求 pageContext 一个页面 pageContext的作用 :理解 1:域对象 xxxAttribute() 2:操作 其他的域对象 方法: xxxAttribute(...,int scope); scope的取值 APPLICATION_SCOPE SESSION_SCOPE REQUEST_SCOPE PAGE_SCOPE 3:获取 其他的内置对象 getxxx() 注意 : getRequest()获取request的内置对象 4:便捷查找 findAttribute(String key): 依次从pagecontext,request,session,application四个域中查找响应的属性,若查找到了就 返回值,且结束该次 的查找 查找不到就返回一个null jsp的动作标签 <jsp:forward>:请求转发 相当于java中request.getRequestDispatcher().forward() <jsp:forward page="内置路径"></jsp:forward> <jsp:include>动作包含 就是将被包含页面 或者servlet的运行结果 包含到当前的页面中 //////////////////////// el: jsp的内置表达式语言,从jsp2.0开始 用来代替<%=..%> 作用: 1:获取域 中的数据 2:执行运算 3:获取常见的web对象 4:调用 java的方法 格式: ${el表达式} 获取域 中的数据: 注意: 若属性出现了"."|"+"|"-等的 特殊符号,需要 使用scope获取 例如:${requestScope["arr.age"]} ${pageScope|requestScope|SessionScope|applicationScope.属性名} 获取复杂 数据 获取数组中的数据 ${域中的名称[index]} 获取list中的数据 ${域中的名称[index]} 获取map中的数据 ${域中的名称.键名} javabean导航 javaBean: java语言编写的一个可重用的组件 侠义上来说就是我们编写的一个普通的java类例如: User person javaBean规范 : 1:必须是一个公共的具体的类 public class 2:提供私有的 字段 private String id;//id称之为字段 3:提供公共访问字段的方法 get|set|is方法 publiic String getID(){} 一旦有公共的方法之后,get|set|is之后的内容,将首字母 小写,将这个东西称之为bean属性 id就是一个bean属性 4:提供一个无参 的构造器 5:一般实现序列化接口 serializable ${域中javaBean名称.bean属性} /////////////////// 执行运算: 四则运算 关系(>..) 逻辑 (&& ||) 注意: +:只能进行加法运算,字符串 形式数字可以进行加法 运算 empty:判断一个容器 的长度是否为 0(array set list map),还可以判断一个对象是否为 空 ${empty 域中的对象名称} 三元运算符 //////////////////// el的内置对象(了解) 11个 pageScope requestScope sessionScope applicationScope param paramValues header headerValues initParam cookie* pageContext* 注意: 除了pageContext其余对象获取的全是map集合 了解:和参数相关的el内置 对象 param paramVavlues 了解:和请求 头相关的el内置 对象 header headerValues 了解:和全局初始化 参数相关的el内置对象 initParam cookie内置对象: ${cookie}获取 map{key=Cookie} 例如:创建cookie Cookie c=new Cookie("username","tom"); 通过${cookie}获取相当于 {username=new Cookie("username","tom"); 相当于map的key是cookie的键 map的value是当前cookie 若想获取名称username的cookie的value值 (获取tom) ${cookie.username.value}--javabean导航 注意 java中cookie的api getName():获取cookie的名称 getValue():获取cookie的value的值 我们称name个 value是cookie的bean属性 使用cookie.给cookie起名字.value} 例如: 获取 jession的值 ${cookie.JSESSIONID.value} pageContent:获取不是map集合,相当于jsp的pageContent内置 对象 在jsp页面中获取项目名 ${pageContext.request}
还没有评论,来说两句吧...