JSP随笔

18 篇文章 0 订阅
4 篇文章 0 订阅


本文中的<后所接字母中间是没有空格的,为了在页面显示才打的空格。

CHAPTER 01 JSP简介

JSP环境的搭建

  1. 设置环境变量:Java_home D:/jdk1.7
    Path D:/jdk1.7/bin
  2. 检测正确网址:http://127.0.0.1:8080/
    http://locallhost:8080/
  3. 配置端口号:用记事本打开conf文件夹下的server.xml
    找到 < Connector port = “8080” protocol = “HTTP/1.1” connectionTimeout = “200000” redirectPort = “8443”/>
    将8080改为你向设置的端口号。
    默认端口号8080
    端口号为80时可以省略端口号
    例如:http://127.0.0.1/
  4. 设置WEB服务目录
    (1)根目录
    webapps/Root
    (2)webapps下的Web服务目录
    新建文件夹ch1
    URL为http://127.0.0.1:8080/ch1/example1_1.jsp
    (3)新建Web服务目录
    找到conf文件夹下的server.xml用记事本打开
    举例:假设将D:/JspServer 作为Web服务目录并让用户使用matthew虚拟目录访问Web服务目录D:/JspServer下的JSP页面
    找到server.xml文件的</ Host>在文件底部,然后在</ Host>前加入:
    < Content path = “/matthew” docBase = “D:/JspServer” debug = “0” reloadable = “true”/>

CHAPTER 02 JSP语法

JSP基本元素

一个JSP页面由5种元素组成:
(1) 普通的HTML标记符
(2) JSP标记,如指令标记、动作标记
(3) 变量和方法的声明
(4) Java程序片
(5) Java表达式

常用的HTML语言标记

< HTML> </ HTML> 表示html文件的开始和结束
< BODY> </ BODY> 表示文件的主体部分
该标记可以有 BGCOLOR属性设置背景颜色
< Hn> </ Hn>表示标题
< P>表示分段
< b>着重显示
< i>斜体
< BR> 表示换行
< FONT> </ FONT>表示设置字体
该标记可以有SIZE和 COLOR属性
< A href =“连接的地址”>连接提示信息</ A>
Print 和 println的效果一样

<% %> Java程序片

程序片将被JSP引擎顺序执行,在程序片中声明的变量为局部变量。

<%! %> Java数据声明和定义方法

声明成员变量占用内存直到JSP引擎关闭才释放。
每个用户启动一个线程,任一用户对JSP页面成员变量操作的结果都会影响其他用户。
实现计数器example2_2.jsp
定义方法,方法内声明的变量为局部变量。
为了避免一个用户操作时被其他用户影响(成员变量被所有的用户共享),那么就应该将操作成员变量的方法用synchronized关键字修饰,用此关键字修饰后该方法被两个用户同时访问时,一个等待,一个进行。
<%= 变量名%> Java表达式,输出变量的值

JSP中的注释,为了增强JSP页面的可读性

  1. HTMl注释
    < !-- 注释内容 -->
    JSP引擎把HTML注释交给用户,因此用户通过浏览器查看JSP页面的源文件时,能够看到HTML注释。

  2. JSP注释
    <%-- 注释内容 -->
    JSP引擎忽略JSP注释

Page指令标记

属性值用单引号或双引号括起来,可以用一个page指令指定多个属性值。
<%@ page 属性1=“属性1的值” 。。。。。%>
page指令的作用对整个JSP页面有效,与其书写的位置无关。

  1. contentType属性
    要求JSP页面必须设置相应的MIME类型和JSP页面字符的编码
    “MIME类型”;charset=编码”
    Eg: <%@ page contentType = “text/html;charset = gb2312”%>
    如果不用page指令为contentType指定一个值,那么contentType属性的默认值是:
    “text/html;charset=ISO-8859-1”
    不允许两次使用page指令给contentType属性指定不同的属性值。
  2. language属性
    该属性的值目前只能取”java”,默认值是java。
  3. import属性
  4. session属性
  5. buffer属性
  6. autoFlash属性
  7. isThreadSafe属性
    用来设置JSP页面是否可以多线程访问
  8. info属性
    info属性的属性值是一个字符串,其目的是为JSP页面准备一个常用但可能要经常修改的字符串。
<%@page info = “we are students”%>

调用方法getServletInfo();
注意:当JSP页面被转移成JAVA文件是,转译成的类是Servlet的一个子类,所以在JSP页面中可以使用Servlet类的方法:getServletInfo();

include指令标记

如果需要在JSP页面内某处整体嵌入一个文件语法格式如下:
<%@include file = “文件的URL”%>
静态的插入一个文件。
所谓静态插入就是当JSP页面和插入的文件合并成一个新的JSP页面,然后JSP引擎再将这个新的JSP页面转译成Java文件。

include动作标记

include动作标记语法格式为:
<jsp:include page = “文件的URL”/>

<jsp:include page = “文件的URL”>
Param 子标记
</ jsp:include>
需要注意的是当include动作标记不需要param子标记是,必须用第一种形式。
动态包含一个文件,即JSP页面运行是才将文件加入。
如果包含的是JSP文件,JSP引擎就执行这个文件,然后将执行的结果发送到用户端,并有用户端的浏览器负责显示这些结果。
如果包含的时TXT文件,就将文件的内容发送到用户端,由用户端的浏览器负责显示。
jsp:include之间没有空格

param动作标记

param标记以”名字——值”对的形式为其他标记提供附加信息,param标记不能独立使用,需作为jsp:include 、jsp:forward 、 jsp:plugin标记的子标记来使用。
param动作标记语法格式是:
<jsp:param name = “名字” value = “指定的param的值”>

forward动作标记

forward动作标记的语法格式是:
<jsp:forward page = “要转向的页面”/>

<jsp:forward page = “要转向的页面”>
param子标记
</jsp:forward>
该指令的作用是:从该指令处停止当前页面的执行,而转向执行page属性指定的jsp页面。需要注意的是,当forward动作标记不需要param子标记时,必须使用第一种形式。
需要注意的是,当前页面使用forward动作标记转向后,尽管用户看到了转向后的页面的想过,但浏览器地址栏中显示的仍然是转向前的JSP页面的URL地址,因此,如果刷新浏览器的显示,将再次执行当前浏览器地址栏中显示的JSP页面。

useBean动作标记

该标记用来创建并使用一个JAVABEAN,负责存储数据,JSP页面显示JAVABEAN中的数据,而servlet负责管理JAVABEAN中的数据。

CHAPTER 03 JSP内置对象

Http协议被称作“请求和相应”协议
内置对象——不用声明可以在JSP页面的脚本部分使用
(1) request
(2) response
(3) session
(4) application
(5) out
(6) page
(7) page countext
(8) exception
(9) config

request对象

内置对象request封装了用户提交的信息。

提交手段 get和post方法地主要区别是:

使用get方法提交地信息会在提交地过程中显示在浏览器地地址栏中,而post方法提交地信息不会显示在地址栏中。
request对象获取用户提交信息地最常用地方法是getParameter(String s)
request设置编码
request在获取信息之前使用setCharacterEncoding(“gb2312”)

处理HTML标记

< form>标记

表单地一般格式是:
< form action = “提交信息地目的地页面” method = get||post name = “表单的页面”>
数据提交手段部分
</ form>
提交手段包括:文本框、列表、文本区等
< input type = “text” name = “boy” value = “ok”> 文本框
< input type = “submit” value = “发送” name = “submit”> 按钮
<select…> </ select> 列表
<option…> </ option> 列表
<textArea…> </ textArea> 文本框

< input>标记

< input type = “输入对象地GUI类型” name = “名字”>

文本框 text

< input type = “text” name = “me” value = “hi” size = “12” align = “left” maxlength = “30”>
Value的值是text的初始值,size是text对象的长度(单位是字符),align是text在浏览器窗体中的对齐方式,maxlength指定text可输入的最多字符数目。
request对象通过name指定的名字来获取用户在文本框输入的字符串。
如果未输入,获取的字符串长度为0,即该字符串为:""

  1. 单选按钮radio
    < input type = “radio” name = “rad” value = “red” align = “top” checked = “java”>
    value指定radio的值,align是radio在浏览器窗体中的对齐方式,如果几个单选按钮的name取值相同,那么同一时刻只能有一个被选中。
    request对象调用getPeremeter方法获取被选中的radio中value属性指定的值。
    checked如果取值是一个非空的字符串,那么该单选按钮的初始状态就似乎选中状态。

  2. 复选框checkbox
    < input type = “checkbox” name = “ch” value = “pink” align = “top” checked = “java”>
    value指定checkbox的值,复选框与单选按钮的区别就是可以多选,即如果几个checkbox的names取值相同,那么同一时刻可有多个checkbox被选中。
    request对象需调用getParameterValues方法,获取被选中的多个checkbox中的value属性指定的值。
    为了使服务器通过getParameterValues方法能获取提交的值,复选框name的值应互不相同。
    checked如果取值使一个非空的字符串那么该复选框的初始状态就使选中状态。

  3. 口令框password
    < input type = “password” name = “me” size = “12” maxlength = “30”>
    服务器通过name指定的字符串获取password提交的值。
    口令框仅仅起不让别人偷看的作用,不提供加密措施。

  4. 隐藏hidden
    当< input>中的属性type的值是hidden时,< input>没有可见的输入界面,表单直接将< input>中value属性的值提交给服务器。
    < input type = “hidden” name = “h” value = “123”>
    Request对象调用getParameter方法,通过name的名字来获取由value指定的值。

  5. submit按钮
    < input type = “submit” name = “me” value = “确定” size = “12”>
    单击submit按钮后,服务器可以获得表单提交的各个数据。
    Request对象调用getParameter方法,通过name的名字来获取由value指定的值。

  6. 重置按钮reset
    < input type = “reset” value = “重置”>

注意: HTML标记用于设置网页的背景音乐,音乐文件可以使==.wav 和.mp3格式。loop的值取正整数表示背景音乐播放的次数,取-1为无限循环播放。

< select>、< option>标记

下拉式列表和滚动列表通过< select>和< option>标记来定义
< select name = “myName”>
< option value = “item1”>
< option value = “item2”>

</ select>
在select中增加size属性的值就变成滚动列表,size的值时滚动列表的可见行的数目。
< select name = “myName” size = “正整数”>
< option value = “item1”>
< option value = “item2”>

</ select>

< textArea>标记

< textArea name = “名字” rows = “文本可见行数” cols = “文本可见列数”>
</ textArea>

< table>标记

< table>
< tr width = “该行的宽度”>
< th width = “单元格的宽度”>单元格中的数据</ th> //th为着重显示

< td width = “单元格的宽度”>单元格中的数据</ td> //td为普通显示
</ tr>

</ table>

< image>标记

< image arc = “图像文件的URL”>描述文字</ image>
如果图片在web服务目录的一个子目录下比如image,那么图像的URL就是image/图像文件的名字。
< image>标记中可以使用width和height属性指定被显示的图像的宽和高如果省略,将按图像原始宽度和高度来显示。

< embed>标记

用来播放音乐和视频
< embed src = “音乐或视频文件的URl”>描述文字</ embed>
autostart属性,取值“true”或“false”,autostart属性的值用来指定音乐或视频文件传输完毕后是否立即播放,默认值为false。
loop属性,取值为正整数指定音乐或视频文件重复播放的次数,取值为-1则无限循环播放。
width和height属性指定被显示的播放器的宽和高如果省略,将使用默认值。

处理超链接

HTML的超链接标记< a href = 链接的页面地址?参数1 = 串值&参数2 = 串值2&……>文字说明</ a>
串值中不能有汉字否则会乱码。

response对象

  1. 动态响应contentType属性
    Response.setContentType(“application/msword;charset=gb2312”)
    转变MIME类型
    例子将页面转换为word文档形式
<%@ page contentType="text/html;charset=gb2312" %>
<HTML><body bgcolor=cyan><font size=3>
 <p>我正在学习response对象的
 <br>setContentType方法
 <p>将当前页面保存为word文档吗?
  <form action="" method="get" name=form>
     <input type="submit" value="yes" name="submit">
   </form>
 <% String str=request.getParameter("submit");
    if(str==null) {
       str="";
    }
    if(str.equals("yes")) {
       response.setContentType("application/msword;charset=gb2312");
    }
 %> 
</font></body></HTML>
  1. response的HTTP文件头
    addHeader(String head,String value)或
    setHeader(String head,String value)
    设置页面5秒刷新一次response.setHeader(“Refresh”,“5”)
  2. response重定向
    response.sendRedirect(“URL url”);
  3. response的状态行

session对象

HTTP协议时一种无状态协议,session会记录有关连接的信息。

  1. session对象的ID
    String类型的ID号
    注意:同一个用户在不同的Web服务目录中的session是互不相同的。
  2. session对象与URL重写
    session对象是否能和用户,建立起一一对应关系依赖于用户端是否支持Cookie。
    如果用户端不支持Cookie,JSP页面可以通过URL重写来实现session对象的唯一性。
String str = response.encodeRedirecutURL(“second.jsp”);

然后将连接目标写成<%= str%>即可。

  1. session对象存储数据
    (1) public void setAttribute(String key,Object obj)
    session对象可以调用该方法将参数Object指定的对象obj添加到session对象中,并为添加的对象指定一个索引关键字。如果添加的两个对象的关键字相同,则先前添加的对象被清除。
    (2) public Object getAttribute(String key)
    获取session对象索引关键字key的对象。由于任何对象都可以添加到session对象中,因此用该方法取回对象是,应强制转化为原来的类型。
    (3) public Enumeration getAttributeNames()
    session对象调用该方法产生一个枚举对象,该枚举对象使用nextElemets()遍历session中的各个对象所对应的关键字。
    (4) public void removeAttribute(String key)
    session对象调用该方法移除关键字key对应的对象。
  2. session对象的生存周期
    (1)一个用户在某个Web服务目录的session对象的生存期限依赖于session对象是否调用invalidate()方法。
    (2)如果关闭服务器,那么用户的session消失。
    (3)所谓发呆状态时间是指用户对某个Web服务目录发出的两次请求之间的间隔时间(默认的发呆时间是30分钟)
    可以修改Tomcat服务器下的web.xml 重新设置session对象的最长发呆时间。
<session-config>
<session-timeout>30</session-timeout>
</session-config>
  1. session对象可以使用下列方法获取或设置生存时间有关的信息。
    (1)public long getCreationTime() 获取session创建的时间,单位是毫秒(GMT时间,1970年7月1日午夜起至session创建时刻所走过的毫秒数).
    (2)public long getAccessedTime() 获取session最后一次被操作的时间,单位是毫秒。
    (3)public int getMaxInactiveInterval() 获取session最长的发呆时间(单位是秒)
    (4)public void setMaxInactiveInterval (int interval) 设置session最长的发呆时间(单位是秒)
    (5)public boolean isNew() 判断session是否是和i一个新建的对象。
    (6)invalidate () 使session无效。

application对象的常用方法

  1. public void setAttribute(String key,Object obj)application对象可以调用该方法将参数Object指定的对象obj添加到application对象中,并为添加的对象指定一个索引关键字。如哦添加的两个对象的关键字相同,则先添加的对象被清除。
  2. public void getAttribute(String key)获取application对象含有的关键字是key的对象。由于任何对象都可以添加到application对象中,因此使用该方法取回对象是,应强制转化为原来的类型。
  3. public Enumeration getAttributeNames()application对象调用该方法产生一个枚举对象,该枚举对象使用nextElemets()遍历application中的各个对象所对应的关键字。
  4. public void removeAttribute(String key) application对象调用该方法移除关键字key对应的对象。
  5. public String getServletInfo()获取Servlet编译器的当前版本的信息。
  6. 由于application对象对所有的用户都是相同的,任何用户对该对象中存储的数据的改变都会影响到其他用户,因此在某系情况下,对该对象的操作需要实现同步处理。
  7. 有些服务器不直接支持使用application对象,必须用ServletContext类声明这个对象,再使用getServletContext()方法对这个application对象进行初始化。
ServletContext  application = new getServletContext();

向量

JAVA的java.util包中的Vector泛型类负责创建一个向量对象。
当我们创建一个向量是不用像数组那样必须给出数组的大小。向量创建后,例如对于

Vector<String> a = new Vector<String>();

可以使用add(V a)方法把String对象a添加到向量的末尾,向量的大小会自动增加。

CHAPTER 04 JSP与Javabean

Javabean是一个可以重复使用的软件组件。

  1. 只须在类的方法命名上遵守以下规则:
    (1) 如果类的成员变量的名字是xxx,那么为了获取或更改成员变量的值,即获取或更改属性,类中必须提供连个方法:
    getXxx(),用来获取属性xxx。
    setXxx(),用来修改属性xxx。

    也就是方法的名字用get或set为前缀,后缀是将成员变量名字的首字母大写的字符序列。
    (2) 对于boolean类型的成员变量,即布尔逻辑类型的属性,允许使用is代替上面的get和set。
    (3) 类中声明的方法的访问属性都必须是public的。
    (4) 类中声明的构造方法必须是public、无参数的。
  2. 保存bean的字节码在\WEB-INF\classes
  3. 创建和使用bean
    <jsp: useBean id = “bean的名字” class = “创建的bean的字节码” scope = “bean的有效范围”/>
  4. Bean的有效范围(生命周期)
    Scope的取值给出了bean的存货时间(生命周期)
    (1) Page 有效范围是当前页面,直到页面执行完毕,不同用户的scope取值是page的bean也是互不相同的。
    (2) Request bean的request存活时间略长于page存活时间,因为JSP引擎认为页面执行完毕后,响应才算结束。 不同用户的scope取值是request的bean也是互不相同的。
    (3) Session 有效范围是用户的session(会话)期间。如果用户在某个页面更改了这个bean的属性,其他页面的这个bean的属性也将发生同样的变化。
    (4) Application 有效范围是application期间。JSP引擎为Web服务目录下所有的JSP页面分配一个共享的bean。不同用户的scope取值是application的bean也都是相同的一个。
  5. 获取和修改bean的属性
    (1) getProperty动作标记
    使用getProperty动作标记可以获得bean的属性值。
    <jsp: getProperty name = “bean的id的名字” property = “bean的属性” />
    该指令相当于Java表达式:<%= bean.getXxx()%>
    (2) setProperty 动作标记
    <jsp: setProperty name = “bean的id的名字” property = “bean的属性” value = “<%= expression%>或字符串”/>
    用HTTP表单的所有参数的值设置bean相对应的属性值的使用格式如下:
    <jsp: setProperty name = “bean的id的名字” property = “” />
    用HTTP表单的某个参数的值设置bean相对应的属性值的使用格式如下:
    <jsp: setProperty name = “bean的id的名字” property = “属性名” param=“参数名” />
    注意: setProperty标记的上述用法具体制定了bean属性的值将对应表单中哪个参数名指定的值,这种设置bean的属性值的方法,不要求property给出的bean属性的名字和param给出的参数名一直,***即不要求bean属性的名字必须和表单中某个参数名字相同。
    param和value属性不能同时出现。
    **

CHAPTER 05 Java Servlet基础

Java Servlet的核心思想式在服务器端创建能响应用户请求的对象。

源文件及字节码文件

写一个创建servlet的类就是编写一个特殊类的子类,这个特殊的类就是javax.servlet.http包中的HttpServlet类。HttpServlet类实现了Servlet接口,实现了响应用户的方法。HttpServlet类的子类被习惯地称作一个Sevlet类。
注意: 要将Tomcat安装目录lib子目录中的servlet-api.jar文件复制到Tomcat服务器所使用的JDK分扩展目录中,比如,复制到D:\jdk1.7\jre\lib\ext中。
字节码需要保存在\WEB-INF\classes里面

编写部署文件web.xml

Web.xml

<?xml version=”1.0” encoding=”iso-8859-1”?>
<web-app>
<servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>myservlet.control.example5_1_Servlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/lookHello</url-pattern>
</servlet-mapping>
</web-app>

比如,< url-pattern>标记的内容是:/lookHello,那么用户必须在浏览器的地址栏中输入:
http://127.0.0.1:8080/ch5/lookHello
来请求名字的是hello的servlet
如果修改并重新保存web.xml文件,Tomcat服务器就会立刻重新读取web.xml文件,因此,修改web.xml文件不必重新启动Tomcat服务器。但是,如果修改导致web.xml文件出现错误,Tomcat服务器就会关闭当前Web服务目录下的所有servlet的使用权限。所以必须保证web.xml文件正确无误,才能成功启动Tomcat服务器。

向servlet传递参数的值

Servlet名?参数1 = 值&参数2=值

servlet对象的生命周期

一个servlet的生命周期主要有下列3个过程组成:
(1) 初始化servlet 调用init完成初始化工作
(2) 新诞生的servlet再调用service方法响应用户的请求
(3) 当服务器关闭时,调用destory方法摧毁servlet
Init方法只被调用一次,即在servlet第一次被请求加载时调用该方法。

init方法

public void init(ServletConfig config)throws ServletException
servlet第一次被请求加载时,服务器创建一个servlet,这个对象调用init方法完成必要的初始化工作。该方法在执行时,服务器会把一个ServletConfig类型的对象传递给init()方法,这个对象就被保存在servlet中,直到servlet被销毁。这个ServletConfig对象负责向servlet传递服务设置信息,如果传递失败就会发生ServletException,servlet就不能正常工作。

service方法

该方法时HttpServlet类中的方法可以在子类中直接继承该方法或重写这个方法。Service方法的声明格式是:
Public void service(HttpServletRequest request ,HttpServletResponse response)throws ServletException,IOException
Service方法可能被多次的调用,也就是说,当后续的用户请求该servlet时,服务器将启动一个新的线程,在该线程中servlet调用service方法响应用户端的请求,即每个用户的请求都导致service方法被调用执行,调用过程运行在不同的线程中,互不干扰。因此,不同线程的service方法中的局部变量互不干扰。

destroy方法

该方法时HttpServlet类中的方法,子类可以直接急成这个方法,一般不需要重写destroy方法的声明格式时:
Public destroy()
当服务器终止服务时,比如关闭服务器,destroy()方法会被执行,销毁servlet

doGet和doPost方法

HttpServlet类除了init,service,destroy方法外,该类还有连个很重要的方法用来处理用户的请求并作出响应doGet和doPost。
当服务器创建servlet后,该servlet会调用init方法初始化自己,以后每当服务器在接收一个对gaiservlet请求时,就会产生一个新线程。
Servlet类中重写doPost或soGet方法来响应用户的请求,这样可以增加响应的灵活性并降低服务器的负担。

通过表单向servlet提交数据

<form action = “computeBill?参数1=值&参数2=值” method = post></form>

通过超链接访问servlet

<a href = “triangle?sideA=3&sideB=4&sideC=5”>三角形(3,4,5)的面积</a>

共享变量

Servlet类时HttpServlet的一个子类,在编写子类时就可以声明某些成员变量,那么请求该Servlet类所创建的servlet的用户将共享该servlet的成员变量。

重定向和转发

在Servlet类中使用HttpServletResponse类的sendRedirect重定向方法,以及RequestDispatcher类的forward转发方法。

  1. sendRedirect方法 网址变 不传值
    重定向方法void sendRedirect(String location)时HttpServletResponse类中的方法。
    重定向的目标页面或servlet无法使用request获取用户提交的数据。
  2. RequestDispatcher对象 网址不变 传值
    RequestDispatcher对象可以把用户对当前JSP页面或servlet的请求转发给另一个JSP页面或Servlet,而且将用户对当前JSP页面或Servlet的请求和响应(HttpServletRequest对象和HttpServletResponse对象)传递给转发到的JSP页面或servlet。
    实现转发的步骤:
    (1) 得到ResquestDispatcher对象。用户所请求的当前JSP或servlet可以让HttpServletRequest对象request调用
    public RequestDispatcher getRequest Dispatcher(String path)
    方法返回一个RequestDispatcher对象,其中参数path时要转发到的JSP页面或servlet:例如
RequestDispatcher dispatcher = request.getRequestDispatcher(“a.jsp”);

(2)转发。在步骤1中获取的RequestDispatcher对象调用
Void forward(ServletRequest request,ServletResponse response)throws ServletException, ava.io.IOException
方法可以将用户对当前JSP页面或servlet的请求转发给RequestDispatcher对象所指定的JSP页面或servlet。例如:

Dispatcher.forward(request,response);

使用session

HttpServletRequest对象request调用getSession方法获取用户的session对象:

HttpSession session = request.getSession(true;

CHAPTER 06 MVC模式

  1. 模型-视图-控制器
    (1)模型(model):用于存储数据的对象。
    一个或多个Javabean对象,用于存储数据。不涉及对数据的具体处理细节。
    (2)视图(view):向控制器提交所需数据、显示模型中的数据。
    (3)控制器(Controller)负责具体的业务逻辑操作。

  2. 模型的生命周期与视图更新
    三种生命周期:request,session,application

    • Request
      JavaBean的创建
      • 用BeanClass类的某个构造方法创建bean对象例如:

          BeanClass bean = new BeanClass();
        
      • 将所创建的bean对象存放到HttpServletRequest对象request中,并指定查找该bean 的关键字。该步骤决定了bean的生命周期为request。例如:

        Request.SetAttribute(“keyword”,bean);
      
      视图的更新
      servlet所请求的JSP页面,比如show.jsp页面可以使用如下标记获得servlet所创建的bean的引用(type属性使得该JSP页面不负责创建bean):
        <jsp: useBean id="keyword" type ="user.yourbean.BeanClass" scope="request"/>
      
      该标记中的id是servlet所创建的bean索引关键字。
      如果servlet使用的是class属性获取servlet所创建的bean的引用
        <jsp: useBean id="keyword" class ="user.yourbean.BeanClass" scope="request"/>
      
      该标记中的id是servlet所创建的bean索引关键字。那么即使servlet所请求的JSP页面事先已经有了id是“keyword”,scope是“request”的bean,那么这个bean也会被servlet所创建的bean替换。原因是servlet所请求的JSP页面一旦被刷新,就会根据当前页面使用的
        <jsp: useBean id="keyword" class="user.yourbean.BeanClass" scope="request"/>
      
      标记到Tomcat引擎管理的内置对象PageContext中寻找id是“keyword”,生命周期是request,而该bean已经被servlet刷新了。
      具体type和class的区分
    • Session
      和request一样
    • Application
      第一步相同,第二步servlet使用getServletContext()方法返回服务器的ServletContext内置对象的引用,将所创建的bean对象存放到服务器这个ServletContext内置对象中,并指定查找该bean的关键字。例如:
getServletContext().setAttribute("keyword",bean);

CHAPTER 07 在JSP中使用数据库

  1. JBDC的任务:与一个数据库建立连接;向数据库发送SQL语句;处理数据库返回结果。
  2. 连接数据库的常用方式:建立JDBC-ODBC桥接器、加载存Java数据库驱动
  3. 使用java.sql包中的Connection类声明一对象con,在使用类DriverManager调用静态方法getConnection创建一连接对象并捕获异常:
try{
Connection con = DriverManager.getConnection("jdbc:odbc:数据源名字","login name","password");
}
  1. 用Java语言编写的数据库驱动程序称为纯java数据库驱动程序。即JDBC可调用纯Java驱动程序和相应的数据库建立连接。
    优点:不设置数据源,不依赖于ODBC,具有很好的移植性。
    缺点:数据库驱动程序升级后,访问数据库的应用程序想使用升级版本的驱动程序必须重新安装新的驱动程序。
  2. Statement的三种类型:
    Statement——用来执行包含有静态SQL的字符串;
    PreparedStatement——Statement的一个子类,允许程序员预编译SQL语句;
    CallableStatement——PreparedStatement的子类,提供对存储过程的访问。
  3. 经DBMS处理,SQL操作返回的结果以特定形式显示给用户,管理输出格式的类是ResultSet。

结果集与查询

ResultSet类的若干方法

返回类型方法名称
booleannext()
bytegetByte(int/String columnIndex/columnName)
DategetDate(int/String columnIndex/columnName)
doublegetDouble(int/String columnIndex/columnName)
floatgetFloat(int/String columnIndex/columnName)
intgetInt(int/String columnIndex/columnName)
longgetLong(int/String columnIndex/columnName)
StringgetString(int/String columnIndex/columnName)

注意: 无论字段是何种属性,总可以使用getString(int column Index)或getString(String column Name)方法返回字段值的串表示。
当使用ResultSet的getXxx方法查看一行记录时,不可以颠倒字段的顺序,例如
不可以

rs.getFloat(4);
rs.getDate(3);

结果集的列名与列的数目

  1. 首先让结果集ResultSet对象rs调用getMetaData()方法返回一个ResultSetMetaData对象(结果集的元数据对象):
rs = sql.executeQuery(SQL语句);
ResultSetMetaData metaData = rs.getMetaData();
  1. 然后ResultSetMetaData对象,比如metaData,调用getColumnCount()方法就可以返回结果集rs中的列的数目:
int columnCount = metaData.getColumnCount();
  1. ResultSetMetaData对象,比如metaData,调用getColumnName(int i)方法就可以返回结果集rs中的第i列的名字:
String columnName =  metaData.getColumnName(i);

连接MySQL数据库

使用JDBC数据库驱动程序方式和数据库建立连接需要两个步骤:

  1. 加载JDBC数据库驱动
  2. 与指定的数据库建立连接,加载JDBC:
Class.forName("com.mysql.jdbc.Driver");

建立连接

Java.sql包中的DriverManager类有两个用于建立连接的类方法(static方法):

Connection getConnection(java.lang.String,java.lang.String,java.lang.String);
Connection getConnection(java.lang.String);

利用DriverManager类的getConnection方法创建连接,格式如下:

Connection Myconn = DriverManager.getConnection(url,login,password);

DriverManager类:

主要控制所有注册的JDBC驱动程序的集合,所有方法都是静态的,一个虚拟机只有一DriverManager 。
作用:
(1)是最高层次的类,保持驱动程序的信息、状态信息等。
(2)当驱动程序被装入时,用此类进行登记。
(3)需要打开一个连接时,可根据JDBC URL选择驱动程序。

Connection类

作用:
(1)管理有关连接的所有方面,是连接到底层DBMS驱动程序的管道,被管理的信息包括:数据源标识、子协议、状态信息、DBMS SQL执行计划ID和句柄、其他和底层DBMS交互操作所必要的环境信息。
(2)事务管理:内部有一个自动提交标志的状态。
设定:setAutoCommit()
读出:getAutoCommit()

关闭Statement

每个Statement对象在使用完毕后都应关闭。使用Con.close();关闭。

MySQL乱码解决

  1. 数据库和表使用支持中文的字符编码
    创建数据库时使用:
    create 数据库名 CHARACTER SET gb2312
    创建表时指定某字段的字符编码:
    字段名 类型 CHARACTER SET gb2312
    连接数据库支持中文编码

查询操作

它是以统一形式的列组织的数据行组成。
该对象一次只能看到一数据行,使用next()方法可走到下一行,最初该指针指向第一行之前。它可使用getXxx方法获得字段值,将位置索引或列名传给方法的参数。
无论何种属性的字段,总可以使用getXxx(int 位置索引)或getXxx(String 字段名字)返回字段值的串表示。
当使用getXxx方法查看一行记录时,不可颠倒字段的顺序。

  1. SQL查询语句与结果集
    ResultSet类的若干方法
    注意: 无论字段是何种属性,总可以使用getString(int columnIndex)或getString(String columnName)方法返回字段值的串表示。
  2. 结果集的列名和列的数目
    首先让结果集ResultSet对象rs调用getMetaData()方法返回一个ResultSetMetaData对象(结果集的元数据对象):
ResultSetMetaData metaData = rs.getMetaData();

然后ResultSetMetaData对象meta调用getColumnCount():返回rs中列的数目:

int columnCount = metaData.getColumn();

ResultSetMetaData对象meta调用getColumnName(int i)方法就可以返回结果集rs中的第i列的名字:

  getColumnName(int i);

顺序查询

<%@ page contentType="text/html;charset=gb2312" %>
<%@ page import="java.sql.*" %>
<HTML><body bgcolor=#EEDDFF>
 <% Connection con;
    Statement sql; 
    ResultSet rs;
    try{  Class.forName("com.mysql.jdbc.Driver");   //加载驱动
    }
    catch(Exception e){
       out.println("忘记把MySQL数据库的JDBC-数据库驱动程序复制到JDK的扩展目录中");
    }
    try { String uri= "jdbc:mysql://127.0.0.1/warehouse";
          String user="root";
          String password="";
          con=DriverManager.getConnection(uri,user,password);   //连接数据库
          //也可以写成con=DriverManager.getConnection(uri+"?user=root&password=");
          sql=con.createStatement();
          rs=sql.executeQuery("SELECT * FROM product "); //得到语句对象执行查询SQL语句
          out.print("<table border=2>");           //顺序查询
          out.print("<tr>");
            out.print("<th width=100>"+"产品号");
            out.print("<th width=100>"+"名称");
            out.print("<th width=50>"+"生产日期");
            out.print("<th width=50>"+"价格");
          out.print("</TR>");
          while(rs.next()){
            out.print("<tr>");
              out.print("<td >"+rs.getString(1)+"</td>"); 
              out.print("<td >"+rs.getString(2)+"</td>");
              out.print("<td >"+rs.getDate("madeTime")+"</td>"); 
              out.print("<td >"+rs.getFloat("price")+"</td>");
            out.print("</tr>") ; 
          }
          out.print("</table>");
          con.close();        //断开连接
    }
    catch(SQLException e){ 
          out.print(e);
    }
 %>
</body></HTML>

随机查询

为了得到一个可滚动的结果集,需使用下述操作:
Statement stmt=con.createStatement(int type,int concurrency);
然后根据参数type、concurrency的取值情况,stmt返回相应类型的结果集:
ResultSet re=stmt.executeQuery(SQL语句);
其中type取值决定滚动方式,可以是:
ResultSet.TYPE_FORWARD_ONLY:游标只向下走。
ResultSet.TYPE_SCROLL_INSENSITIVE:游标可上下走,数据库变化当前结果集不变。
ResultSet.TYPE_SCROLL_SENSITIVE:游标可上下走,数据库变化当前结果集同步变。
ResultSet.CONCUR_READ_ONLY:不能用结果集更新数据库中的表。
ResultSet.CONCUR_UPDATABLE:能用结果集更新数据库的表。
滚动查询经常用到ResultSet的下述方法:

  1. public boolean previous():将游标向上移动,当移动到结果集第1行的前面时返回false。
  2. public void beforeFirst():将游标移动到结果集的初始位置,即第1行之前。
  3. public void afterLast():将游标移到结果集最后一行之后。
  4. public void first():将游标移到结果集的第1行。
  5. public void last():将游标移到结果集的最后1行。
  6. public boolean isAfterLast():判断游标是否在最后一行之后。
  7. public boolean isBeforeFirst():判断游标是否在第一行之前。
  8. public boolean isFirst():判断游标是否指向结果集的第一行。
  9. public boolean isLast():判断游标是否指向结果集的最后一行。
  10. public int getRow():得到当前游标所指行的行号,行号从1开始。如果结果集没有行,返回0.
  11. public boolean absolute(int row):将游标移到参数row指定的行号。

注意: 如果row取负值,就是倒数的行数。absolute(-1)表示移到最后一行,absolute(-2)表示移到倒数第2行。当移动到第1行前面或最后一行的后面时,该方法返回false。
可以看出,用滚动集的absolute(int row)方法就可以随机查询某条记录。

更新、添加与删除

Statement对象调用方法:
public int executeUpdate(String sqlStatement);
通过参数指定的SQL语句实现。
更新:UPDATE<表名>SET<字段名>=新值 WHERE〈条件子句〉
添加:INSERT INTO 表(字段列表)VALUES(对应的具体记录)或INSERT INTO表(VALUES(对应的具体记录))
删除:DELETE FROM〈表名〉WHERE 〈条件子句〉
注意: 可以使用一个Statement对象进行添加和查询操作,但需要注意的是,当查询语句返回结果集后,如果没有立即输出结果集的记录,而接着执行了更新、添加或删除语句,那么结果集就不能输出记录了。要想输出记录就必须重新返回结果集。

用结果集操作数据库中的表

尽管可以用SQL语句对数据库中表进行更新、插入操作,但也可以使用内存中ResultSet结果集对底层数据库表进行更新和插入操作(这些操作由系统自动转化为响应的SQL语句)。
优点是不必熟悉有关更新、插入的SQL语句,而且方便编写代码;
缺点是必须要事先返回结果集。为了避免出现中文乱码,数据库的连接方式采用如下方式:

"jdbc:mysql://地址/数据库?user=用户&password=密码&characterEncoding=gb2312";

首先,必须得到一个可滚动的ResultSet结果集,例如:

String uri = "jdbc:mysql://地址/数据库?user=root&password=&characterEncoding=gb2312";

首先,必须得到一个可滚动的ResultSet结果集,例如:

String uri = "jdbc:mysql;//127.0.0.1/warehouse?"+"user=root&password=&characterEncoding=gb2312";
con = DriverManager.getConnection(uri);
Statement sql = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
ResulSet rs = sql.executeQuery("SELECT * FROM product");
更新记录

使用结果集更新数据库表中第n行记录中某列的值的步骤是:

  1. 使结果集rs的游标移动到第n行。让结果集调用absolute()方法可以将游标移到第n行:
rs.absolute(n);
  1. 结果集将第n行的p列的列值更新。结果集可以使用下列方法更新列值:
    updateInt(String columnName/int columnIndex , int x)
    updateLong(String columnName/int columnIndex , long x)
    updateDouble(String columnName/int columnIndex , double x)
    updateString(String columnName/int columnIndex , String x)
    updateBoolean(String columnName/int columnIndex , boolean x)
    updateDate(String columnName/int columnIndex , Date x)
  2. 更新数据库中的表。最后,结果集调用updateRow()方法用结果集中的第n行更新数据库表中的第n行记录,以下代码片段更新product表中的第3行记录的name列(字段)的值。
rs.absolute(3);
rs.updateString(2,"IBM PC"); //也可以写成rs.updateDtring("name","IBM PC");
rs.updateRow();
插入记录

使用结果集向数据库表中插入(添加)一行记录步骤是:

  1. 将结果集rs的游标移动到插入行。结果集中有一个特殊区域,用作构建要插入的行的暂存区域(staging area),习惯上将该区域位置称作结果集的插入行。为了向数据库表中插入一行新的记录,必须首先将结果集的游标移动到插入行,代码如下:
rs.moveTovInsertRow();
  1. 更新插入行的列值。结果集可以用updateXxx()方面更新插入行的列值,例如:
rs.updateString(1,"coo2");
rs.updateString(2,"IBM ipad");
rs.updateDate(3,Date());
rs.updateDouble(4,5356);
  1. 插入记录。最后,结果集调用insertRow()方法用结果集中的插入行向数据库表中插入一行新纪录。
rs.insertRow();

预处理语句

Java提供了更高效率的数据库操作机制,就是PreparedStatement对象,该对象被习惯地称作预处理语句对象。

预处理语句优点

当向数据库发送一个SQL语句,比如" select * from product ",数据库库中的SQL解释器负责将把SQL语句生成底层的内部命令,然后执行该命令,完成有关的数据操作。如果不断地向数据库提交SQL语句势必增加数据库中SQL解释器的负担,影响执行的速度。如果应用程序能针对连接的数据库,事先就将SQL语句解释为数据库底层的内部命令,然后直接让数据库去执行这个命令,显然不仅减轻了数据库的负担,而且也提高了访问数据库的速度。
Connection 连接对象con调用prepareStatement(String sql)方法:

PrepareStatement pre = con.prepareStatement(String sql);

对参数sql指定的SQL语句进行预编译处理,生成该数据库底层的内部命令,并将该命令封装在PreparedStatement对象pre中,那么该对象调用下列方法都可以使得该底层内部命令被数据库执行:

ResultSet executeQuery()
boolean execute()
int executeUpdate()

只要编译好了PreparedStatement对象pre,那么pre可以随时执行上述方法,显然提高了访问数据库的速度。

通配符

在对SQL进行预处理时可以使用通配符“?”来代替字段的值,只要在预处理语句执行之前设置通配符所表示的具体值即可。例如:

prepareStatement pre = com.prepareStatement("SELECT * FROM product WHERE price < ?");

那么在sql对象执行之前,必须调用相应的方法设置通配符“?”代表的具体值,例如:

pre.setDouble(1,6565);

指定上述预处理语句pre中通配符?代表的值是6565。通配符按照他们在预处理的SQL语句中从左至右依次出现的顺序分别被称作第一个,第二个。。。。第m个通配符。例如下列方法:

void setDouble(int parameterIndex,int x);

用来这只通配符的值,其中参数parameterIndex用来表示SQL语句中从左到右的第parameterIndex个通配符号,x是该通配符所代表的具体值。
尽管

prepareStatement pre = com.prepareStatement("SELECT * FROM product WHERE price < ?");
pre.setDouble(1,6565);

的功能等同于

pre = con.prepareStatement("SELECT * FROM product WHERE price < 6565");

但是,使用通配符可以是的应用程序更容易动态地改变SQL语句中关于字段值的条件
设置通配符值的常用方法:
void setDate(int parameterIndex,Date x )
void setDouble(int parameterIndex,double x )
void setFloat(int parameterIndex,float x )
void setInt(int parameterIndex,int x )
void setLong(int parameterIndex,long x )
void setString(int parameterIndex,String x )

事务

事物由一组SQL语句组成。所谓“事务处理”是指应用程序保证事务中的SQL语句要么全部执行,要么一个都不执行。
事物是保证数据库中数据完整性与一致性的重要机制
JDBC事物多处理步骤如下:

  1. setAutoCommit(boolean autoCommit)方法
    事务处理的第一步是使用setAutoCommit(boolean autoCommit)方法关闭自动提交模式。
    连接con首先调用setAutoCommit(boolean autoCommit)方法,将参数autoCommit取值为false来关闭自动提交模式:
con. setAutoCommit(false)
  1. commit()方法
    连接con调用setAutoCommit(false)之后,产生的Statement对象对数据库提交任何一个SQL语句操作都不会立刻生效,这样一来,就有机会让Statement对象(PreparedStatement对象)提交多个SQL语句,这些SQL语句就是一个事务。事物中的SQL语句不会生效直到
con.commit();

语句执行,使事务中的SQL语句全部生效。

  1. rollback()方法
    连接con调用commit()方法进行事务处理时,只要事务中任何一个SQL语句没有生效就会抛出SQLException异常。在处理SQLException异常时,必须让con调用rollback()方法,其作用是:撤销事务中成功执行过的SQL语句对数据库数据所做的更新、插入、或删除操作,即撤销引起数据发生变化的SQL语句操作,将数据库中的数据恢复到commit()方法执行之前的状态。
try{
}
catch(SQLException e){
     try{
         con.rollback();
     }
     catch(SQLException exp){
         out.println(exp);
     }
}

处理异常时,需撤销SQL语句至commit()之前。

分页显示记录

可以使用二维数组table存放表中的记录。为了避免长时间占用数据库的连接,应当将全部记录存放到二维数组中,然后关闭数据库连接(服务器付出内存开销来换取连接资源)。
假设总记录数为m,每页显示量为n,则总页数的计算公式是
(1)m被n整除,总页数=m/n
(2)m不能被n整除,总页数=m/n+1
选择语句:
总页数=(m%n)==0?(m/n):(m/n +1)
如果准备显示第p页的内容,应当从table第(p-1)*n行开始,连续输出n行(最后一页可能不足n行)
若要显示第p页的内容,将游标放在(p-1)*n+1条记录处。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值