java高级教程

第一章  Servlet

第一节  Java Servlet概述

1  什么是Servlet

Servlet 是标准的服务器端 Java 应用程序,它扩展了 Web 服务器的功能。

Servlet 运行在一个 Java 环境中,即 Java 虚拟机,或 JVMservlet 将被载入到一个应用服务器中,例如 WebSphere(tm) Application Server

由于 Servlet 是由一个用户的请求来调用,Servlet 对应一个 Web 站点单一 URL 的系统响应。一个企业级 Web 站点可能对一个请求就有多个 Servlet,例如注册、购物和支付。

由于 Servlet 运行在服务器环境中,用户永远不会直接看到它们而且 Servlet 不需要图形的用户界面。Servlet Java 组件,可以在系统需要它们时被载入。

使用Servlet生成的动态文本,比CGI脚本更容易,且运行效率更高,是CGI脚本的高效替代品。

Servlet API的最大一个优点是协议的独立性,它不假定网络传输使用的协议、Servlet如何装载以及运行的服务器环境,这些特性使得Servlet API可以方便的嵌入到许多不同种类的服务器中。另外,它还具有可扩展、简单、短小、容易使用的特点。

2  Servlet的用途

一个简单的Servlet可以处理使用HTML FORMHTTP(S)上使用POST传递的数据,例如:一个带有信用卡数据的定单。复杂的Servlet可以用于实现定单输入和处理系统、生产及库存数据库、或者一个复杂的联机支付系统。

一个Servlet可以将请求传递给另一个服务器,这项技术在多个服务器中可以用来平衡装载相同的镜像内容。或者,可以用于将一个逻辑服务划分给几个服务器,按照任务类型或组织的边界路由请求,实现负载均衡。

3  API的有效性

Java Servlet API是一个标准的Java扩展API。在J2EE中,它已经发展成为Java核心框架的一部分。

JavaSoft提供了一个包,可以用于在其他服务器中嵌入Servlet

4  Servlet API的特性

Servlet API已经被大多数基于JavaWeb服务器支持,因此,当使用Servlet API时,可以继承Java的许多优点:不但代码不存在内存漏洞和难以发现的指针bug,而且还可以运行在许多不同服务器提供商的平台上。

主要功能

Servlet采用常见的接受请求和生成响应的编程模型,该模型使用了一系列的分布式系统编程工具箱,这包括从远程过程调用到向Web服务器发出HTTP请求等。

Servlet编程非常简单,主要就是实现一个Servlet接口,例如:

Public class MyServlet extends GenericServlet

       {

              Public void service(ServletRequest request, ServletResponse response)

                     throws ServletException, IOException

              {

                     ……

              }

       }

Service方法内可以操作requestresponse参数,这里封装了客户机发送的数据,提供了对参数的访问,并允许Servlet报告各种状态。通常Servlet通过输入流得到大多数参数,并使用输出流发送它们的响应。

ServletInputStream in = request.getInputStream();

ServletOutputStream out = request.getOutputStream();

环境状态

由于Servlet是一种Java对象,它们由特定的实例数据组成,这意味着正在执行的Servlet是运行在服务器内部的独立的应用程序。

在初始化期间,Servlet访问一些特定的Servlet配置数据,这允许相同Servlet类的不同实例可以用不同的数据来初始化,并当作不同名字的Servlet来管理。在初始化期间提供的数据中,包括了每个实例将在哪里保存它们自己的状态。

Servlet还可以利用ServletContext对象与它们自己的环境进行交互。

使用模式

Servlet可以使用下面几种模式,然而,不是所有服务器环境都支持以下所有这些模式:

l        基本的模式:以请求/响应协议为核心。

l        服务器可以用过滤链链接多个Servlet

l        Servlet可以支持特定的协议,例如HTTP

l        在基于HTTP的应用程序中,Servlet是一个基于CGI扩展的完全的替代品。

l        在基于HTTP的应用程序中,Servlet还可以作为HTML的服务器端来包含动态的生成的Web文档。

主要方法

Servlet装载之后,其生命周期涉及三个主要方法:

u      init方法

Servlet通过调用init方法被服务器激活,如果开发者需要,可以执行一些内在的设置,这样,无需每个请求都设置一次。

u      service方法

当初始化后,Servlet处理许多请求,为每一个客户请求生成一个service调用,这些请求可能是并行的,这允许Servlet调整多个客户的行为,类的静态属性可以用于在请求中共享数据。

u      destroy方法

Servlet对象将一直处理请求,除非服务器调用destroy方法显示的关闭ServletServlet类还是一个合格的垃圾收集器。

安全特性

与当前任何其他的服务器扩展API不同,Java Servlet提供了强大的安全策略支持。这是因为所有的Java环境都提供了一个安全管理器,可以用于控制是否允许执行某项操作,例如网络或文件的访问。缺省的,通过网络装载的所有Servlet都是不可信的,它不允许执行诸如访问网络服务或本地文件的操作。仅仅在Java Web Server中创建的,或者在本地由服务器管理员控制的…/Servlet目录的Servlet,才是完全可信的,并赋予所有的权限。

性能特性

Servlet最突出的特性之一就是对于每一个请求不需要象CGI那样单独创建一个新的进程。在大多数环境中,许多Servlet可以并行运行在与服务器相同的进程中,处理许多已初始化的客户请求,这些初始化的开销由许多方法分担,对于该service方法所面对的所有客户请求,它们都有机会共享数据和通讯资源,并充分利用系统缓存。

Servlet的生命周期

Servlet部署在容器里,它的生命周期由容器管理。

       Servlet的生命周期概括为以下几个阶段:

u      装载Servlet:这项操作一般是动态执行的。有些服务器提供了相应的管理功能,可以在启动的时候就装载Servlet并能够初始化特定的Servlet

u      创建一个Servlet实例。

u      调用Servletinit()方法。

u      服务:如果容器接收到对此Servlet的请求,那么它将调用Servetservice()方法。

u      销毁:实例被销毁,通过调用Servletdestroy()方法来销毁Servlet

在几个阶段中,对外提供服务是最重要的阶段,service()方法是我们最关心的方法,因为它才是真正处理业务的方法。

Servlet为客户端提供服务,如下图所示:

客户端

Web容器

Servlet

1:请求

2init()

3service()

5:响应

6destroy()

4:返回结果

第二节Servlet编程示例

在进行具体Servlet编程之前,这里,先举一个最简单的Servlet程序,熟悉一下Servlet的结构。

源程序:HelloWorld.java

package com.iss.test;

import java.io.*

import javax.servlet.*;
import javax.servlet.
http.*;


public class HelloWorldServlet extends HttpServlet
{
    //Initialize
global variables
    public void init()
          throws ServletException
    {
    }

    //Process the HTTP
Get request
    public void doGet(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException
    {

response.setContentType("text/html;charset=gb2312");
          PrintWriter out = response.getWriter();

 

out.println(“”);

out.println(“”);

out.println(“HelloWorld”);

out.println(“”);

out.println(“”);

out.println(“Hello, World!”);

out.println(“”);

out.println(“”);


    }

 

public void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException

{
        doGet(request, response);
  }


    //Clean up resources
    public void
destroy()
    {
    }
}

编译

使用任何一种编译工具,编译为class文件。比如jdk自带的javac命令:

Javac HelloWorld.java

打包

       使用任何一种打包工具,打成可发布的jar包或web组件包。

部署

       将打包好的程序发布到任何支持Servlet容器的服务器上去。

       这个servlet对应的部署描述符如下:(位于WEB-INF下的web.xml中)

      

      

       http://java.sun.com/xml/ns/j2ee

              xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance

              xsi:schemaLocation=”http://java.sun.com/xml/ns/j2ee web-app_2_4.xsd

              version=” 2.4” >

 

       Welcome to Tomcat

      

              HelloWorldServlet

      

      

              HelloWorldServlet

              com.iss.test.HelloWorldServet

      

      

              HelloWorldServlet

              /hello

      

 

      

运行

从客户端访问服务器上的应用,比如通过浏览器访问,服务器给客户端返回“Helloworld!”的信息。

第三节Servlet相关类和接口

HttpServlet

一个抽象类,可以从该类派生出一个子类来实现一个HttpServlet,接受来自Web站点的请求,并将处理后的响应结果发回Web站点。在HttpServlet的子类中,必须至少重载下表中所列的其中一种方法。

HttpServlet子类通常重载的方法

方法名

用途

doGet

如果Servlet支持HTTP GET请求,用于HTTP GET请求

doPost

如果Servlet支持HTTP POST请求,用于HTTP POST请求

doPut

如果Servlet支持HTTP PUT请求,用于HTTP PUT请求

doDelete

如果Servlet支持HTTP DELETE请求,用于HTTP DELETE请求

initdestroy

如果需要管理Servlet生命周期内所持有资源,可以重载这两个方法

      

通常,不重载service方法,对于上表中的每一种HTTP请求,service方法通过分派它们到相应的Handle线程(doXXX方法)来处理这些标准的HTTP请求。

通常也不重载doOptionsdoTrace方法,service方法通过分派它们到doTracedoOptions来支持HTTP1.1 TRACEOPTIONS

Servlet通常运行在多线程的服务器中,因此,所编写的Servlet代码必须能够处理并行请求和对数据资源的同步访问。

doGet

protected void doGet(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException

用于获取服务器信息,并将其作为响应返回给客户端。当经由web浏览器,或者通过HTMLJsp直接访问ServletURL时,一般使用Get调用。

doPost

protected void doPost(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException

用于客户端把数据传送到服务器端。使用它的好处是可以隐藏发送给服务器的任何数据。适合于发送大量的数据。

doPut

protected void doPut(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException

Put的调用和Post相似,它允许客户端把真正的文件存放在服务器上,而不仅仅是传送数据。

doDelete

protected void doDelete(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException

       它的调用和Post相似,它允许客户端删除服务器端的文件或者web页面。

doTrace

protected void doTrace(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException

由容器调用以使此Servlet能够处理Trace请求。这个方法主要用于测试,它是不可以覆盖的方法。

doHead

protected void doHead(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException

它用于处理客户端的Head调用,并且返回一个response。当客户端只需要知道响应的Header时,它就发出一个Header请求。

doOptions

protected void doOptions(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException

它用于处理客户端的Options调用,通过这个调用,客户端可以获得此Servlet支持的方法。

HttpServletRequest接口

该接口扩展了javax.servlet.servletRequest接口,用于提供更多的功能给HttpServletServlet引擎实现该接口,创建HttpServletRequest对象,将来自客户浏览器的信息传递给HttpServletservice方法。

getDateHeader

public long getDateHeader(String name)

得到一个特定请求的header的、描述Date对象的长整形值。Header是大小写敏感的。如果请求中没有该nameheader,则方法返回-1,如果方法不能转换日期,则抛IllegalArgumentException异常。

getHeader

public String getHeader(String name)

得到有关请求header的值,为一个字符串,如果指定名字的header没有随请求一起发送,该方法返回nullname是大小写敏感的。

getCookies

public Cookie[] getCookies()

得到一个Cookie对象数组,含有所有发送请求的浏览器的Cookie,如果浏览器没有发送任何Cookie,则返回null

getHeaderNames

public Enumeration getHeaderNames()

       得到请求中的所有header名。

getRequestURI

public String getRequestURI()

       得到HTTP请求的第一行中从协议名到查询字符串之间的URL部分。

getSession

public HttpSession getSession(Boolean create)

public HttpSession getSession()

       得到与请求相联系的当前HttpSession,如果需要,则为请求创建一个新的任务。

HttpServletResponse接口

该接口扩展了OutputStream类,因此,可以使用OutputStream类中声明的方法,例如,getOutputStream()方法。

addCookie

       public void addCookie(Cookie cookie)

       增加指定的cookie到响应。

setHeader

       public void setHeader(String name, String value)

       使用给定的名字和值设置响应头。

ServletConfig接口

该接口定义了一个Servlet配置对象,Servlet引擎可以用来传递信息给Servlet以便初始化Servlet

配置信息含有初始化参数,这些参数以“名字/值”的形式成对出现,描述关于服务器的Servlet信息。

getServletContext

       public ServletContext getServletContext()

       得到服务器传递给Servlet的一个ServletContext对象。

getInitParameter

       public String getInitParameter(String name)

       得到一个含有参数name指定的初始化参数的值,如果参数不存在则为null

getInitParameterNames

       public Enumeration getInitParameterNames()

       得到Servlet的初始化参数的名字,返回值是一个Enumeration对象。

ServletContext接口

该接口定义了一套ServletServlet引擎通信的方法,例如:得到MIME类型的文件、确定运行在服务器上的其他Servlet或写Servlet日志文件。

Servlet引擎通过返回一个ServetContext对象来与Servlet交流,Servlet使用ServletConfig接口的getServletContext方法得到ServletContext对象。

getContext

        public ServletContext getContext(String uripath)

得到服务器上特定URL的一个ServletContext对象,该方法允许Servlet访问特定URL上的资源,并得到来自该URLRequestDispatcher对象。

getMimeType

        public String getMimeType(String file)

得到指定文件的MIME类型,如果不知道MIMI类型则为nullMIMI类型由Servlet引擎的配置决定,MIME类通常为“text/html”和“image/gif”。

getRealPath

       public String getRealPath(String path)

       得到参数path中对应于虚拟路径的真实路径。虚拟路径含有一个Servlet名,后跟Servlet文件名。

getServerInfo

       public String getServerInfo()

       得到正在允许的Servlet引擎的名字和版本。

getAttribute

       public Object getAttribute(String name)

       得到Servlet引擎的参数name所指定的属性。

getAttributeNames

       public Enumeration getAttributeNames()

       得到一个含有属性名的Enumeration对象,这些属性在Servlet上下文中有效。

setAttribute

        public void setAttribute(String name, Object object)

设置Servlet上下文中属性的名字,如果指定的名字name已使用,该方法将覆盖老的名字,并将名字捆绑到新的属性中。

removeAttribute

       public void removeAttribute(String name)

       Servlet上下文中移走给定名字name的属性名。

ServletInputStream

该类是一个抽象类,它提供了从客户机请求读取二进制数据的一个输入流,对于一些协议,例如HTTP POSTPUT,可以使用ServletInputStream对象读取和发送数据。

readLine

       public int readLine(byte[] b, int off, int len) throws IOException

       读输入流,一次一行。如果读到输入流的尾部,则返回-1

ServletOutputStream

       该类是一个抽象类,它提供了一个输入流,用于向客户机发送数据。

print

public void print(String s) throws IOException

public void print(boolean b) throws IOException

public void print(char c) throws IOException

public void print(int i) throws IOException

public void print(long l) throws IOException

public void print(float f) throws IOException

public void print(double d) throws IOException

public void println() throws IOException

public void println(String s) throws IOException

public void println(boolean b) throws IOException

public void println(char c) throws IOException

public void println(int i) throws IOException

public void println(long l) throws IOException

public void println(float f) throws IOException

public void println(double d) throws IOException

第四节Servlet的配置

名字、类和其他杂项

配置Servet时,首先必须指定Servlet的名字、Servlet的类(如果是JSP,必须指定JSP文件的位置)。另外,可以选择性的给Servlet增加一定的描述,并且指定它在部署时显示的名字,部署时显示的Icon

上述HelloWorldServlet是这样配置的:

      

              HelloWorldServlet

              com.iss.test.HelloWorldServet

      

如果要配置的Servlet是一个JSP文件,那么可以这样指定:

      

              HelloWorldServlet

              HelloWorldServet.jsp

      

初始化参数

       一个Servlet的初始化参数可以如下指定:

      

             

parameter1

                     1000

             

              ……

      

       在这个配置里,指定parameter1的参数值为1000

启动装入优先级

       启动装入优先级通过来配置。如下所示:

      

              HelloWorldServlet1

              com.iss.test.HelloWorldServet

              10

      

      

              HelloWorldServlet2

              HelloWorldServet.jsp

30

      

      

              HelloWorldServlet3

              HelloWorldServet.jsp

              AnyTime

      

这种配置可以保证HelloWorldServlet1HelloWorldServlet2之前被载入,HelloWorldServlet3则可以在服务器启动后的任何时候载入。

Servlet的映射

可以给一个Servlet做多个映射,这样,我们可以通过不同的方式来访问这个Servlet

一个典型的配置如下所示:

              HelloWorldServlet

              /hello_servlet

      

              HelloWorldServlet

              /hello/*

      

              HelloWorldServlet

              /helloworld/helloworld.html

      

       通过这些配置,我们可以使用不同的方式来访问这个Servlet

运行安全设置

一个Servlet的安全设置如下所示:

      

             

                     admin

             

             

                     admin1

                     admin

             

      

第五节Filter过滤器

Web应用中的过滤器截取从客户端进来的请求,并做出处理的答复。可以说过滤器是外部进入网站的第一道关,在这个关卡里,可以验证客户是否来自可信的网络,可以对客户提交的数据进行重新编码,可以从系统里获得配置信息,过滤掉客户的某些不应当出现的词汇,验证客户是否已经登陆,验证客户端的浏览器是否支持当前的应用,记录系统日志,等等。

过滤器可以部署多个,这些过滤器组成了一个过滤链,每个过滤器只执行某个特定的操作或者检查,这样请求在达到被访问的目标之前,需要经过这个过滤链,如果由于安全问题不能访问目标资源,那么过滤器就可以把客户端的请求拦截。

Filter的开发

开发一个Filter,必须直接或间接实现Filter接口。Filter接口定义了以下的方法:

u      init():用于初始化Filter,获得FilterConfig对象。

u      destroy():销毁这个Filter

u      doFilter():进行过滤处理。

Filter的配置

配置Filter分为两步:一是声明Filter,二是使用Filter

一个Filter的配置示例如下:

      

              filter1

              com.iss.test.Filter1

             

                     parameter1

                     value1

             

      

              filter2

              com.iss.test.Filter2

      

 

      

              filter1

              /*

      

      

              filter2

              /security/*

      

              filter2

              /admin/*

      

从上面可以看出,一个Filter可以有多个Filter Mapping。一个web组件可以有多个过滤器,这些过滤器按照配置中出现的先后组成一个过滤链。每个到达的请求,经过这些过滤链中的过滤器逐个过滤,如果不通过,请求就被拦截。

第六节  Cookie编程技术

Cookie是一组短小的、服务器发送到浏览器的文本信息,当浏览器再次访问相同的网站或域时,该文本信息会原样的传回,服务器根据客户机传回的信息,可以向访问者提供许多方便。比如:识别用户、避免输入用户名和密码、定制一个站点、定向广告等等。

Servlet Cookie API

Cookie发送到客户端,Servlet可以使用相应的名字和值创建一个或多个Cookie

              public Cookie(String name, String value)

构造器的两个参数中,不能使用下列字符:

              [ ] ( ) = , “ / ? @ : ;

同时,也不能使用空格。

创建Cookie后,可以使用response.addCookie(cookie)Cookie插入到相应的头中,在客户端,对于得到请求,可以使用response.getCookies(cookies)从响应头中提起Cookie,得到的是一个Cookie数组。

Cookie常用操作

Cookie放进响应头

       Cookie放进响应头可以使用HttpServletResponse类的方法:

              public void addCookie(Cookie cookie);

       例如:

              Cookie userCookie = new Cookie(“user”,”uid 1234” );

              response.addCookie(userCookie);

读取来自客户端的Cookie

       读取来自客户端的Cookie可以使用HttpServletRequest类的方法:

              public Cookie[] getCookies();

第七节  Session编程技术

HTTP状态的维护

HTTP是一种“无状态”的协议,这会造成许多问题。为了解决“状态”的维护,通常有四种解决方案:

Ø        cookie

Ø        URL重写

Ø        隐藏的form

Ø        session

Session API的使用

得到HttpSession对象

       HttpServletRequest有两个方法可以得到Session对象:

              public HttpSession getSession(Boolean create);

              public HttpSession getSession();

得到与request对象相联系的HttpSession,如果request对象中没有session对象且参数createtrue,则创建一个新的。

得到session中的数据

       public Enumeration getAttributeName();

       public Object getAttribute(String name);

Session中写数据

       public void setAttribute(String name, Object value);


第二章  JDBC

JDBC封装了与底层数据库的通信细节,提供了与数据库相关的类和接口,为数据库开发人员提供了一种面向应用的开发平台。

 

第一节  JDBC概述

数据库是用于存储和处理数据的工具,数据库是构成了许多公司的重要基础。当前,由于数据库产品缤纷复杂,一个公司里经常出现同时使用多种数据库的现象。使用Java进行数据库开发时通过JDBC技术,可以一致性地访问不同的数据库,不用分别为不同平台的不同数据库编写各自不同的应用程序。

1 JDBC的概念

JDBC(Java Data Base ConnectivityJava数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。同时,JDBC也是个商标名。

JDBC向应用程序开发者提供了独立于数据库的、统一的API,这个API提供了编写的标准,并考虑了所有不同应用程序设计的标准,其关键是一组由驱动程序实现的Java接口。驱动程序负责标准的JDBC调用,当应用程序被移植到不同的平台或数据库系统,应用程序不变,改变的是驱动程序,驱动程序扮演了多层数据库设计中的中间层的角色。如下图所示:

应用程序

JDBC

Oracle

驱动程序

Sybase

驱动程序

DB2

驱动程序

Informix

驱动程序

……

驱动程序

Java具有坚固、安全、易于使用、易于理解和可从网络上自动下载等特征,是编写数据库应用程序的杰出语言,所需要的只是Java应用程序与各种不同数据库之间进行对话的方法,而JDBC正是作为此种用途的机制。

       随着越来越多的使用Java编程语言,对从Java中便捷的访问数据库的要求也在日益增加。对于服务器端的数据库应用,JDBC往往与RMICORBAJSPServletEJB等技术混合使用,用于实现多层结构的应用系统。

2 数据库驱动程序

数据库厂商一般会提供一组API访问数据库。流行的数据库如OracleSQL ServerSybaseInformix都为客户提供了专用的API。有四种类型的数据库驱动程序,它们分别是:

u      JDBCODBC

u      部分Java、部分本机驱动程序

u      中间数据访问服务器

u      Java驱动程序

以下分别介绍。

JDBCODBC

JDBCODBC桥是一个JDBC驱动程序,它通过将JDBC操作转换为ODBC操作来实现JDBC操作。对ODBC,它像是通常的应用程序,桥为所有对ODBC可用的数据库实现JDBC。它作为sun.jdbc.odbc包实现,其中包含一个用来访问ODBC的本地库。桥是由IntersolvJavaSoft联合开发的。由于ODBC被广泛地使用,该桥地优点是让JDBC能够访问几乎所有地数据库。

通过odbc子协议,使用URL打开JDBC连接即可使用桥。建立连接前,必须将桥驱动程序类sun.jdbd.odbc.JdbcOdbcDriver添加到名为jdbc.driversjava.lang.System属性中,或用Java类加载器将其显示的加载。可以用如下方式显示加载:

              Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”)

加载时,ODBC驱动程序将创建自己的实例,同时在JDBC驱动程序管理器中进行注册。

桥驱动程序使用odbc子协议。该子协议的URL为以下的形式:

jdbc:odbc:[=]*

JDBCODBC桥在JDBC APIODBC API之间提供了一个桥梁,这个桥把标准的JDBC调用翻译成对应的ODBC调用,然后通过ODBC库把它们发送到ODBC数据源,如图所示:

JDBC

API

ODBC

API

JDBCODBC

ODBC

 

数据源

 

Java应用程序

这种方式有一个明显的缺点就是效率相对低下,所以不推荐使用这种桥驱动程序,但它可以减少开发人员进行企业开发的麻烦。

部分Java、部分本机驱动程序

这种驱动使用Java实现与数据库厂商专有API的混和形式来提供数据访问。它比前一种方式要快。JDBC驱动将标准的JDBC调用转变为对数据库API的本地调用,该类型的驱动程序是本地部分Java技术性能的本机API驱动程序,如下图所示:

JDBC

API

厂商专有API

JDBC驱动程序

 

数据源

 

Java应用程序

在这种方式里,驱动程序和厂商专有的API必须在每个运行Java应用程序的客户端安装。

现在大多数的数据库厂商都在其数据库产品中提供驱动程序,这种使用方式比前一种有效。

中间数据访问服务器

这种方式使用一个中间数据访问服务器,通过这种服务器,它可以把Java客户端连接到多个数据库服务器上,如下图所示:

JDBC

API

JDBC驱动程序

本机驱动程序

 

数据源

 

Java应用程序

JDBC驱动程序

这种方式不需要客户端的数据库驱动,而是使用网络-服务器中间层来访问一个数据库。该类型的驱动程序是网络协议完全Java技术性能的驱动程序,它为Java应用程序提供了一种进行JDBC调用的机制。

使用该类型的驱动程序是平台无关的,并且不需要客户端的安装和管理,因此很适合做Internet的应用。

Java驱动程序

这种方式使用厂商专有的网络协议把JDBC API调用转换成直接的网络调用,这种方式的本质是使用套接字(Socket)进行编程。纯Java驱动运行在客户端,并且直接访问数据库,因此运行这个模式要使用一个两层的体系,如下图所示:

JDBC

API

JDBC驱动程序

 

数据源

 

Java应用程序

该类型的驱动程序是本地协议完全Java技术性能的驱动程序,同时它的使用也比较简单,客户端不需要安装任何中间件或者运行库。现在大部分厂商都提供第四类驱动程序的支持。

3 JDBC的用途

Ø        与数据库建立连接

Ø        发送SQL语句

Ø        处理结果

4 JDBC URL

JDBC URL的概念

JDBC URL提供了一种标识数据库的方法,可以使相应的驱动程序能识别该数据库并与之建立连接。JDBC的作用是提供某些约定,驱动程序编程员在构造它们的JDBC URL时应该遵循这些约定。

u      由于JDBC URL要与各种不同的驱动程序一起使用,因此,这些约定应非常灵活。首先,它们应允许不同的驱动程序使用不同的方案来命名数据库。

u      JDBC URL应允许驱动程序编程员将一切所需的信息编入其中。

u      JDBC URL应允许某种程度的间接性。即:JDBC URL可指向逻辑主机或数据库名,而这种逻辑主机或数据库名将由网络命名系统动态的转换为实际的名称。

JDBC URL的语法格式

       JDBC URL的标准语法如下所示。它由三部分组成,各部分之间用冒号分割。

              jdbd:<子协议>:<子名称>

       JDBC URL的三个部分可分解如下:

Ø        jdbc:协议,JDBC URL中的协议总是jdbc

Ø        <子协议>:驱动程序名或数据库连接机制的名称。

Ø        <子名称>:标识数据库的方法。子名称可以依不同的子协议而变化,使用子名称的目的是为定位数据库提供足够的信息。如果数据库是通过Internet来访问的,则在JDBC URL中应将网络地址作为子名称的一部分包括进去,且必须遵循如下所示的标准URL命名约定:

//主机名:端口/子协议

对于不同的数据库,厂商提供的驱动程序和连接的URL都不同,几个主要的数据库厂商与其对应的驱动程序和连接的URL如下所示:

 

数据库驱动程序和URL

数据库名

驱动程序

URL

MS SQL Server 2000

com.microsoft.jdbc.sqlserver.SQLServerDriver

Jdbc:Microsoft:sqlserver://[ip]:[port];user=[user];password=[password]

JDBC-ODBC

sun.jdbc.odbc.JdbcOdbcDriver

jdbc:odbc:[odbcsource]

Oracle oci8

orcle.jdbc.driver.OracleDriver

jdbc.oracle:oci8:@[sid]

Oracle thin Driver

oracle.jdbc.driver.OracleDriver

jdbd:oracle:thin:@[ip]:[port]:[sid]

Cloudscape

com.cloudscape.core.JDBCDriver

jdbc:cloudscape:database

MySQL

org.gjt.mm.mysql.Driver

jdbc:mysql:/ip/database,user,password

 

5ODBC子协议

子协议odbc是一种特殊情况。它是为指定ODBC风格的数据资源的URL而保留的,并允许在子名称后面指定任意多个属性值。

odbc子协议的完整语法为:

              jdbcodbc<数据资源名称>[;<属性名>=<属性值>]*

       例如:

              jdbc:odbc:test

              jdbc:odbc:test;UID=uid;PWD=pwd

6、事务

事务就是将一些SQL语句作为一个整体来执行,要么所有语句全部完成,要么一条语句都不执行。当调用方法commitrollback时,当前事务即告结束,另一个事务谁即开始。

缺省情况下,新连接处于自动提交模式,也就是说,当执行完语句后,将自动对那个语句调用commit方法。这种情况下,由于每个语句都是被单独提交的,因此,一个事务只由一个语句组成。如果禁用自动提交模式,事务将要等到commitrollback方法被显示调用时才结束,因此,它将包括上一次调用commitrollback方法以来所有执行过的语句。对于第二种情况,事务中的所有语句将作为组来提交或还原。

方法commit使SQL语句对数据库所做的任何更改成为永久性的,它还将释放事务持有的全部锁,而方法rollback将放弃那些更改。


 

第二节  JDBC核心类和接口

Driver接口

每个数据库驱动程序必须实现Driver接口。我们在编程中要连接数据库,必须先装载特定厂商提供的数据库驱动程序(Driver),驱动程序的装载方法如下:

       Class.forName(“);

DriverManager

对于简单的应用程序,仅需要使用该类的方法getConnection,该方法将建立与数据库的连接。JDBC允许用户调用DriverManager类的方法getDrivergetDriversregisterDriverDriver类的方法connect,但在多数情况下,最好让DriverManager类管理建立连接的细节。

       DriverManager类是JDBC的管理层,作用于用户和驱动程序之间,用于管理JDBC驱动程序。它跟踪可用的驱动程序,并在数据库和相应的驱动程序之间建立连接,另外,DriverManager类也处理诸如驱动程序登录时间限制及登录和跟踪消息的显示等事务。

作为初始化的一部分,DriverManager将试图装载系统属性“jdbc.drivers”所指的驱动程序类,这可以让用户定制在它们的应用程序中使用的JDBC驱动程序。例如,在WindowsHOME目录的/.hotjava/properties文件中,可以指定:

       Jdbc.drivers=<驱动程序>

       另外,程序还可以显示的装载JDBC驱动程序。例如:下述代码用于装载my.sql.Driver

       Class.forName(“my.sql.Driver”);

DriverManager中有一个非常重要的方法,就是getConnection(parameter),通过这个方法可以获得一个连接。

getConnection

       public static synchronized Connection getConnection(String url)

尝试建立一个和给定的URL的数据库连接,调用此方法时,DriverManager将在已注册的驱动中选择恰当的驱动来建立连接。

       public static synchronized Connection getConnection(String url, Properties info)

       与上类似,不过提供了一些属性,这些属性连接特定的数据库需要,至少包含userpassword属性。

       public static synchronized Connection getConnection(String url, String user,String password)

       连接到指定URL的数据库,使用用户名为user,密码为password

Connection接口

Connection对象代表与数据库的连接,也就是在已经加载的Driver和数据库之间建立连接。

连接过程包括所执行的SQL语句和在该连接上所返回的结果。一个应用程序可与单个数据库有一个或多个连接,或者可与许多数据库有连接。

close

       public void close()

关闭到数据库的连接,在使用完连接之后必须关闭,否则连接会保持一段比较长的时间,直到超时。

commit

       public void commit()

提交对数据库的更改,使更改生效。这个方法只有调用了setAutoCommit(false)方法后才有效,否则对数据库的更改会自动提交到数据库。

createStatement

       public Statement createStatement()

          throws SQLException

       public Statement createStatement(int resultSetType, int resultSetConcurrency)

          throws SQLException

       public Statement createStatement(int resultSetType,

                               int resultSetConcurrency,

                               int resultSetHoldability)

          throws SQLException

       创建一个StatementStatement用于执行SQL语句。

prepareStatement

public PreparedStatement prepareStatement(String sql)

          throws SQLException

public PreparedStatement prepareStatement(String sql,

                                          int autoGeneratedKeys)

        throws SQLException

public PreparedStatement prepareStatement(String sql,

                                          int[] columnIndexes)

        throws SQLException

public PreparedStatement prepareStatement(String sql,

                                          String[] columnNames)

        throws SQLException

public PreparedStatement prepareStatement(String sql,

                                        int resultSetType,

                                        int resultSetConcurrency)

              throws SQLException

public PreparedStatement prepareStatement(String sql,

                                       int resultSetType,

                                       int resultSetConcurrency,

                                       int resultSetHoldability)

          throws SQLException

public PreparedStatement prepareStatement(String sql,

                                       String[] columnNames)

              throws SQLException

        使用指定的SQL语句创建一个预处理语句,sql参数中往往包含一个或者多个“?”占位符。

Statement接口

一个Statement对象仅能有一个ResultSet对象。当完成对表的操作之后,必须重新得到另一个Statement对象,才能进行其他表的操作。

Statement对象可以用于执行一个静态的SQL语句,并得到SQL语句执行后的结果。

execute

public boolean execute(String sql)

                throws SQLException

运行语句,返回是否有结果集。

executeQuery

public ResultSet executeQuery(String sql)

                       throws SQLException

运行查询语句,返回ResultSet对象。

executeUpdate

public int executeUpdate(String sql)

                  throws SQLException

运行更新操作,返回更新的行数。

PreparedStatement接口

PreparedStatement对象可以代表一个预编译的SQL语句,它从Statement接口继承而来,并与之有如下两方面的不同:

u      PreparedStatement实例包含已编译的SQL语句。

u      包含于PreparedStatement对象中的SQL语句可具有一个或多个IN参数。IN参数的值在SQL语句创建时未被指定。相反的,该语句为每个IN参数保留一个问号(“?”)作为占位符。每个问号的值必须在该语句执行之前,通过适当的setXXX方法来提供。

由于PreparedStatement对象已经预编译过,所以其执行速度要快于Statement对象。因此,需要多次执行的SQL语句经常创建为PreparedStatement对象,以提供效率。

作为Statement的子类,PreparedStatement继承了Statement的所有功能。另外它还添加了一整套方法,用于设置发送给数据库以取代IN参数占位符的值。

另外,Statement接口中的三种方法executeexecuteQueryexecuteUpdate已经被更改,使之不再需要参数。

所有的setXXX方法的原型如下,其中XXX是与该参数相应的类型。例如,如果参数具有Java类型long,则使用的方法就是setLongsetXXX方法的第一个参数parameterIndex为要设置的参数的序数位置,第二个参数是设置给该参数的值。

setXXX

public void setXXX(int parameterIndex, XXX x)

             throws SQLException

设定指定位置的参数值。

execute

public boolean execute()

                throws SQLException

运行语句,返回是否有结果集。

executeQuery

public ResultSet executeQuery()

                throws SQLException

运行查询语句,返回ResultSet对象。

executeUpdate

public int executeUpdate()

                throws SQLException

运行更新操作,返回更新的行数。

ResultSet接口

ResultSet提供了对数据库中表的访问,一个ResultSet对象通常由执行一个Statement而生成。

ResultSet对象维护了一个光标指针,用来描述当前记录的位置,最初,光标指向第一个记录的位置之前,next方法将光标移到到下一个记录,其方法的原型如下。

boolean next() throws SQLException

getXXX方法得到当前记录的字段的值,可以使用字段名或其索引得到自动的值,一般来说,使用字段的索引效率更高,字段的编号从1开始,1为当前记录的第一个字段,2为第二个字段,以此类推。

ResultSet接口中,还有一系列的updateXXX方法,可以用来更新当前记录的字段值。

getXXX

public XXX getXXX(int parameterIndex)

             throws SQLException

public XXX getXXX(String columnName)

             throws SQLException

获取指定位置或者指定列的查询结果值。

 

 

 

第三节  JDBC编程实例

基本步骤

Ø        输入java.sql

在程序的开头,必须加入下面的代码:

       Import java.sql.*;

Ø        声明变量

在代码中,一般要声明三个相关的变量。Stmt用于SELECT语句,pstmt用于UPDATE语句,rs用于SELECT的结果集。

       Statement stmt

       PreparedStatement pstmt

       ResultSet rs

Ø        加载jdbc驱动程序

Class.forName(“驱动程序>”);

Ø        定义JDBC URL

String url = “jdbc:odbc:oracle:thin@ 10.10.10 .1:db 9” ;

Ø        连接数据库

Connection conn = DriverManager.getConnection(url);

Ø        进行相应的数据操作

根据需要创建StatementPreparedStatement实例,执行SELECT操作或UPDATE操作。

Statement stmt = conn.createStatement();

ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table2");

Ø        关闭数据库连接

conn.close();

查询记录信息

              Vector data = new Vector();

              ResultSet rs = null;

              Statement stmt = null;

              Connection conn = null;

              //注册驱动器

              try

              {

                     //加载驱动程序

                     Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

                     //Class.forName("oracle.jdbc.driver.OracleDriver");

                     //得到数据库联接

                     conn= DriverManager.getConnection("jdbc:oracle:thin:@192.168.110.52:1521:edu","study","study");

                     //执行sql语句

                     stmt = conn.createStatement();

                     //返回数据集合

                     rs = stmt.executeQuery("select * from book where bookid=‘ 0007’ ");       

             

                     while (rs.next())

                     {

                            DataObject dataObject = new DataObject();

                            dataObject.setBookId(rs.getString("bookid"));

                            dataObject.setBookName(rs.getString("bookname"));

                            dataObject.setBookNumber(rs.getString("booknumber"));

                            data.addElement(dataObject);

                     }

              }

              catch (SQLException e1)

              {

                     e1.printStackTrace();

              }

              catch (ClassNotFoundException e)

              {

                     System.out.println("Driver not found");

              }

 

              //关闭联接

              finally

              {

                     try

                     {

                            rs.close();

                            stmt.close();

                            conn.close();

                     }

                     catch (SQLException e2)

                     {

                            e2.printStackTrace();

                     }

              }

插入记录信息

        String sql;

        Connection conn = null;

        PreparedStatement ps=null;

      

              //注册驱动器

              try

              {

                     //加载驱动程序

                     Class.forName("oracle.jdbc.driver.OracleDriver");

                     // 得到数据库联接

                     conn= DriverManager.getConnection("jdbc:oracle:thin:@192.168.110.52:1521:edu","study","study");

                     // 执行sql语句

                     sql="insert into book ( bookid,bookname,booknumber) values (?,?,?)";    

                     ps = conn.prepareStatement(sql);

                  ps.setString(1, "0021");

                  ps.setString(2, "数据库概论");

                  ps.setInt(3, 11);

                  ps.executeUpdate();

              }

              catch (SQLException e1)

              {

                     e1.printStackTrace();

              }

              catch (ClassNotFoundException e)

              {

                     System.out.println("Driver not found");

              }

              // 关闭联接

              finally

              {

                     try

                     {

                            ps.close();

                            conn.close();

                     }

                     catch (SQLException e2)

                     {

                            e2.printStackTrace();

                     }

              }

更新记录信息

              int state;

              Statement stmt = null;

              Connection conn = null;

              //注册驱动器

              try

              {

                     //加载驱动程序

                     Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

                     //Class.forName("oracle.jdbc.driver.OracleDriver");

                     //得到数据库联接

                     conn= DriverManager.getConnection("jdbc:oracle:thin:@192.168.110.52:1521:edu","study","study");

                     //执行sql语句

                     stmt = conn.createStatement();

                     //返回数据集合

                     state=stmt.executeUpdate("update book set booknumber=9 where bookname='java编程思想'");            

                     if(state>0)

                     {

                            System.out.println("更新成功");

                     }

                  else

                  {

                        System.out.println("更新失败");

                  }

              }

              catch(SQLException e1)

              {

                     e1.printStackTrace();

              }

              catch(ClassNotFoundException e)

              {

                     System.out.println("Driver not found");

              }

              //关闭联接

              finally

              {

                     try

                     {

                            stmt.close();

                            conn.close();

                     }

                     catch(SQLException e2)

                     {

                            e2.printStackTrace();

                     }

              }

删除记录信息

              boolean state=false;

              Statement stmt = null;

              Connection conn = null;

              //注册驱动器

              try

              {

                     //加载驱动程序

                     Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

                     //Class.forName("oracle.jdbc.driver.OracleDriver");

                     //得到数据库联接

                     conn= DriverManager.getConnection("jdbc:oracle:thin:@192.168.110.52:1521:edu","study","study");

                     //执行sql语句

                     stmt = conn.createStatement();

                     //返回数据集合

                     state=stmt.execute("delete from book where bookid='0007'");          

                     if(state)

                     {

                            System.out.println("删除成功");

                     }

            else

            {

                System.out.println("删除失败");

            }

              }

              catch (SQLException e1)

              {

                     e1.printStackTrace();

              }

              catch(ClassNotFoundException e)

              {

                     System.out.println("Driver not found");

              }

 

              //关闭联接

              finally

              {

                     try

                     {

                            stmt.close();

                            conn.close();

                     }

                     catch (SQLException e2)

                     {

                            e2.printStackTrace();

                     }

              }

 

 

 

 

第四节  JDBC数据库连接池

在实际应用开发中,特别是在Web应用系统中,如果JSPServletEJB使用JDBC直接访问数据库中的数据,每一次数据访问请求都必须经历建立数据库连接、打开数据库、存取数据和关闭数据库连接等过程,而连接并打开数据库是一件既消耗资源又费时的工作,如果频繁的发生这种数据库操作,系统的性能必然会急剧的下降,甚至会导致系统崩溃。数据库连接池技术是解决这个问题最常用的方法,在许多应用程序服务器中,基本都提供了这项技术,无需自己编程。

数据库连接池技术的思想非常简单,将数据库连接作为对象存储在一个vector对象中,一旦数据库连接建立后,不同的数据库访问请求就可以共享这些连接,这样,通过复用这些已建立的数据库连接,可以克服上述缺点,极大的节省了系统资源和时间。

数据库连接池的主要操作如下:

Ø        建立数据库连接池对象

Ø        按照事先指定的参数创建初始数量的数据库连接

Ø        对于一个数据库访问请求,直接从连接池中得到一个连接。如果数据库连接池对象中没有空闲的连接,且连接数没有达到最大,创建一个新的数据库连接

Ø        存取数据库

关闭数据库,释放所有数据库连接。


 

第三章  JSP

第一节  JSP简介

JSP概述

JSPSun Microsystems 公司倡导、许多公司参与一起建立的一 种动态网页技术标准,其在动态网页的建设中有其强大而特别的功能。Java Server Pages技术可以让web开发人员和设计人员非常容易的创建和维护动态网页,特别是目前的商业系统

 

 

JSP技术原理

编写一个简单的HTML文件——test.html,在这个HTML中包含一个表单,我们希望能够接收用户在这个表单中填入的字符串,并把它打印出来。

Test.html 的代码:

      

              show string

your string:

    Test.jsp的代码

      

<%@ page contentType="text/html; charset=gb2312" %>

show my string

<%

String strMyString = (String)request.getParameter(“myString”);

 out.println(strMyStirng);

%>

 

       [注:在此我们不做任何有效性验证]

过程描述:

1、用户在test.htm中填写字符串,如“Hello world!!!”,并点击“submit”按钮

2、浏览器将用户提交的请求(其中包含用户填写的数据信息和目标jsp)发送到Servlet容器

3、如果该jsp没有被编译过的话,Servlet容器会编译它;若jsp已被编译完成,则Servlet容器会调用这个jsp执行

4、执行的结果,通过response反映

具体流程见下图:

     点击“submit”提交请求

 

 

 

 

 

 

 

 

 

显示服务器产生的响应

 

 

 

 

 

编译、执行JSP,生成动态内容

发送请求

发送响应

 

 

 

 

 

为什么使用JSP

JSP技术是由Servlet技术发展起来的,自从有了JSP后,在java服务器端编程中普遍采用的就是JSP技术。因为JSP在编写表示页面时远远比Servlet简单,而且不需手工编译——由Servlet容器自动编译。

Servlet目前更多的是作为控制器来使用。

JSP构建在Servlet上,拥有Servlet所有强大的功能。

JSP特点

Ø        将内容的生成和显示进行分离

 

在服务器端,JSP引擎解释JSP标识和小脚本,生成所请求的内容,并且将结果以HTML(或者XML)页面的形式发送回浏览器。

 

 

Ø        强调可重用的组件

 

绝大多数JSP页面依赖于可重用的,跨平台的组件(JavaBeans或者Enterprise JavaBeansTM组件)来执行应用程序所要求的更为复杂的处理。

 

 

Ø        采用标识简化页面开发

 

Web页面开发人员不会都是熟悉脚本语言的编程人员。Java Server Page技术封装了许多功 能,这些功能是在易用的、与JSP相关的XML标识中进行动态内容生成所需要的。 

 

动态网页技术比较

CGI

        后台实现逻辑是基于Java Component的,具有跨平台的特点。

        将应用逻辑与页面表现分离,使得应用逻辑能够最大程度得到复用,从而提高开发效率。

        运行比CGI方式高,尤其对于数据库访问时,提供了连接池缓冲机制,使运行所需资源最小。

        安全,由于后台是完全基于Java技术的,安全性由Java的安全机制予以保障

        内置支持XML,使用XML从而使页面具有更强的表现力和减少编程工作量。

 


 

第二节  JSP页面组成

一个典型的JSP文件

首先,我们来看一个典型的JSP文件:

<%@ page contentType="text/html; charset=gb2312" %>

<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>

<%@ page import=com.iss.scm.bizlogic.outbound.OutboundBiz %>

这是一个典型的JSP,它包含了JSP中常用的元素 -->

<%! String getDate()

       {

       return new java.util.Date().toString();

}

%>

title

<%

 out.println(getDate());

%>

 

 

分析JSP文件中的元素

从上面的JSP文件中,可以总结出五类元素:

Ø        注释

Ø        模版元素

Ø        脚本元素

Ø        指令元素

Ø        动作元素

 

下面,我们分别介绍这些元素:

1、注释

JSP中有多种注释,有JSP自带的注释规范,也有HTML/XML的注释规范。

u      HTML/XML注释

在客户端显示一个注释。

JSP语法:

例子:

描述:这种注释和HTML中很像,唯一不同之处就是,可以在这个注释中用表达式。

u      隐藏注释

写在JSP程序中,但不发给客户。

JSP语法:<%-- comment --%>

例子:

<%-- 下面是使用表达式的例子 --%>

<%= getDate() %>

描述:用隐藏注释标记的字符会在JSP编译时被忽略。JSP编译器不会对<%----%>之间的语句进行编译,它不会显示在客户的浏览器中,也不会在源代码中看到。

u      Scriptlets中的注释

Scriptlets中包含的是java代码,所以java中的注释规范在Scriptlets中也能使用。

语法:// /* … */

例子:

/ *

* 这是一个注释

*/

 

2、模版元素

模版元素是指JSP的静态HTMLXML内容,通常由美工或网页工程师来负责完成。模版元素是网页的框架,它影响页面的结构和美观程度。在JSP编译时,这些模版元素会被编译到Servlet里面。比如被编译时,会用以下代码替代:

        out.write(“”);

 

3、脚本元素

脚本元素主要包括:

u      声明(Declaration

声明是在JSP程序中声明合法的变量和方法,如:

<%! String getDate()

{

       return new java.util.Date().toLocaleString();

}

int iCount = -1;

%>

 

u      表达式(Expression

表达式就是位于<%=%>之间的代码,如:

<%! String strBookName = “Design Pattern” %>

… …

<%= strBookName %>

<%= getDate() %>

 

u      Scriptlets

Scriptlets位于<%%>之间,它们是合法的java代码,如:

 

<%

String[] strEmp= {‘aaa’,’bbb’,’ccc’};

%>

<%

for(int i = 0;i < 3;i++)

{

%>

<%

}

%>

<%= strEmp[i] %>

 

4、指令元素

JSP中有三种指令元素,它们是:

u      页面(page)指令

语法:

<%@ page

       [language=”java”]

       [import=”{package.class|package.*},…”]

       [contentType=”TYPE;charset=CHARSET”]

       [session=”True | False”]

       [buffer=”none | 8kb | sizekb”]

       [autoFlush=”True | False”]

       [isThreadSafe=”True | false”]

       [info=”text”]

       [errorPage=”relativeURL”]

       [isErrorPage=”true | false”]

       [extends=”package.class”]

       [isELIgnored=”true | false”]

       [pageEncoding=”peinfo”]

%>

例子:<%@ page contentType="text/html; charset=gb2312" %>

u      include指令

例子:<%@ include file=/slof/outbound/outbound.jsp %>

u      taglib指令

例子:

<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>

      

 id="sendStockNO"  name="outboundForm"  property= "outboundEntity.sendStockNO"/>

 

5、动作元素

动作可能影响当前的输出流或者用来创建、使用、改变对象。Jsp规范包含标准的动作类型,新的动作类型由taglib指令定义。动作遵循XML语法标准。

动作元素在请求处理阶段起作用。

语法:

或者

JSP规范定义了一系列的标准动作,它们用jsp作为前缀,这些动作元素有:

,,,,,,,,,,,,,,,

      

       下面我们介绍几个典型的动作元素

n       

jsp:param操作被用来以“名-值”对的形式为其他标签提供附加信息。

使用方式:。其中,name为属性相关的关键字,value为属性的值。

n       

jsp:include操作允许在请求时间内在现成的jsp页面里面包含静态或者动态资源。被包含的对象只有对JspWriter对象的访问权,并且它不能设置头或者Cookie。如果页面输出是缓冲的,那么缓冲区的刷新要优于包含的刷新。另外,此指令在运行上效率比<%@ page include %>指令的效率低。

使用方式:。其中,page为一个相对路径,或者是代表相对路径的表达式;flush属性的可选值包括truefalse,当flush属性为true,表示在执行插入操作之前,先调用当前页面的输出流的flush()方法。

n       

jsp:forward操作是运行将请求转发到另一个JSPServlet或者静态资源文件。请求被转向到的资源必须位于同JSP发送请求相同的上下文环境之中。每当遇到此操作时,就停止执行当前的JSP,转而执行被转发的资源。

使用方式:。其中,page值为一个表达式或一个字符串,用于说明将要定向的文件或URL。这个文件可以是JSP文件,也可以是程序段,或者其他能够处理request对象的文件。

n       

该标签用来在JSP页面中创建一个bean实例,并指定它的名字以及作用范围。它保证对象在标签指定的范围内可以使用。

使用方式:

其中,id是一个大小写相关的名字,用来表示这个实例;scope表示此实例可以使用的范围;typeSpec可以是以下四者之一:

class = “className”

class = “className” type = “typeName”

beanName = “beanName” type = “typeName”

type = “typeName”

 

scope解释:

page

能够在JSP文件以及此文件中的所有静态包含文件中使用Bean,直到页面执行完毕向客户端发回响应或转到另一个文件为止。

request

在请求的范围内有效

session

在会话范围内有效,所有的JSP都可以访问

application

在应用服务器启动时创建,所有的JSP都可以访问

n       

此操作和useBean一起协作,用来设置Bean的属性。该标签将会使用Bean给定的setter方法,为Bean中的属性赋值。

使用方法:

其中,name的值为在useBean标签中设置的idpropertyDetails可以是下面几个中的一个:

property=”*”

property=”propertyName” param=”parameterName”

property=”propertyName”

property=”propertyName” value=”propertyValue”

 

n       

此操作和useBean一起协作,用来获取Bean的属性的值。该标签将会使用Bean给定的getter方法。

使用方法:

n       

jsp:plugin用来产生客户端浏览器的特别标签,一般用它来插入Applet或者JavaBean。当JSP文件被编译把结果发送到浏览器时,元素将会根据浏览器的版本替换成元素。

使用方法:

type=”bean | applet”

code=”classFileName”

codebase=”classFileDirectoryName”

[name=”instanceName”]

[archive=”URIToArchive,…”]

[align=”bottom | top | middle | left | right”]

[height=”displayPixels”]

[width=”displayPixels”]

[hspace=”leftRightPixels”]

[vspace=”topBottomPixels”]

[nspluginurl=”URLToPlugin”]

[iepluginurl=”URLToPlugin”]

[

[}” />]

]

[text message for user]

>  

其中,type指示将被执行的插件对象的类型;code指示java类文件的名称;codebase指示运行java类的目录或指向这个目录的路径;name指示BeanApplet的实例的名称;archive指示以逗号分隔的路径名列表;

n       

用于java插件不能启动时,显示给用户的一段文字。

使用方式:

text message for user

 

 

 

 

 

 

 

第三节  JSP内部对象

out

out对象被封装成javax.servlet.jsp.JspWriter接口。主要用来向客户端输出数据。

request

request对象代表请求对象,它被封装成HttpServletRequest接口。

通过getParameter方法可得到request参数,通过GETPOSTHEAD等方法可以得到request的类型,通过CookiesReferer可得到请求的http头。

来自客户端的请求经Servlet容器处理后,由request对象进行封装。它作为jspService()方法的一个参数由容器传递给jsp页面。

response

       response被包装成HttpServletResponse接口。它封装了JSP产生的响应,然后被发送到客户端以响应客户的请求。由容器生成,作为jspService()方法的参数被传入jsp

pageContext

       pageContext对象被封装成javax.servlet.jsp.PageContext接口,它为jsp页面包装成页面的上下文,管理对属于jsp中特殊可见部分中已命名对象的访问。它的创建和初始化都是由容器来完成的,jsp页面里面可以直接使用pageContext对象的句柄。

      

session

       session对象用来保存每个用户信息,以便跟踪每个用户的操作状态。session信息保存在容器里,sessionID保存在客户机的Cookie中。一般情况下,用户首次登陆系统时容器会给此用户分配一个唯一标识的session id,这个id用于区分其他的用户,当用户退出系统时,这个session就会自动消失。

       Session被封装成HttpSession接口。

application

       application对象为多个应用程序保存信息,对于一个容器而言,每个用户都共同使用一个application对象,服务器启动后,就会自动创建application对象,这个对象会一直保持,直到服务器关闭为止。

config

       config对象被封装成javax.servlet.ServletConfig接口,他表示Servlet的配置。当一个Servlet初始化时,容器把某些信息通过此对象传递给这个Servlet

page

       page对象是java.lang.Object类的一个实例。它指的是jsp实现类的实例,也就是说它是jsp本身,通过这个可以对它进行访问。

exception

exception对象是java.lang.Throwable类的一个实例。它指的是运行时的异常,也就是被调用的错误页面的结果,只有在错误页面才可以使用。

要使用exception对象,必须在page指令指定isErrorPage=true”,在出错页面中,使用<%= exception.getMessage() %>来获取错误信息。


 

第四章  Struts

第一节  为什么使用Struts

讨论为什么使用Struts,先让我们来看一下传统单页方法的优缺点:

优点:

只要简单设置应用服务器,然后就可以开始编写代码。不需用核心文件来保持同步,也不需要冗长的库初始配置。由每个单独的 JSP 页面或 servlet 来指定连接。

缺点:

          HTML Java 混合在一起

        JSP 文件的编写者必须既是网页设计者,又是 Java 开发者。其结果通常要么是很糟的 Java 代码,要么是难看的网页,有时甚至 Java 代码和网页都很糟。

 

        Java JavaScript 的不足

随着网页逐渐变大,很容易想到实现一些 JavaScript。当网页中出现 JavaScript 时,这种脚本就可能与 Java 代码产生混淆。

 

        强耦合

更改业务逻辑或数据可能牵涉相关的每个网页。

        内嵌的流程逻辑

要理解应用程序的整个流程,您必须浏览所有网页。试想一下拥有 1000 个页面的错综复杂的逻辑。

 

        调试困难

        除了很糟的外观之外,HTML 标记、Java 代码和 JavaScript 代码都集中在一个网页中还使调试变得相当困难。              

 

        页面代码美观

        在很大的网页中,编码样式看起来杂乱无章。即使有彩色语法显示,阅读和理解这些代码仍然比较困难。

        在应用程序的不同部分中重用表示很困难

 

        一定程度上,可以使用 标记来解决一部分重用,但它们在管理更改方面不能很好地工作。

 

        公共输入和数据处理任务枯燥且重复

 

        错误处理是普通 JSP 页面的常见问题。而且,必须手工填入表单值及手工检索请求对象中的那些值,这是一件既耗时又枯燥的工作。


 

第二节  设计模式MVC

什么是设计模式

简单来说,Design Patten 就是一个常用的方案。 在我们的开发过程中,经常会遇到一些相同或者相近的问题,每次我们都会去寻找一个新的解决方法,为了节省时间提高效率,我们提供一些能够解决这些常见问题的,被证实可行的方案,构成一个统一的资源库。

一个Design Patten描述了一个被证实可行的方案。这些方案非常普通,是有完整定义的最常用的模式。 这些模式可以被重用,有良好的伸缩性。

什么是MVC

MVC 通过将问题分为三个类别来帮助解决单一模块方法所遇到的某些问题,这就Model(模型)View视图)Controller(控制器)

       其中:

Ø        Model(模型)

模型包含了应用程序的核心,它封装了应用程序的数据结构和事务逻辑,集中体现了应用程序的状态。有时候它仅包含了状态信息,因为它并不了解视窗或控制器的信息(任何时候它对视图或控制器都一无所知 )。

JavaBean EJB 很适合扮演这个角色,因为它能够处理绝大部分事务逻辑和数据结构。它能够与数据库或文件系统进行交互,承担维护应用程序数据的责任。

      

Ø        View(视图)

视图实现模块的外观,它是应用程序的外在表现。它可以访问模型的数据, 却不了解模型的情况, 同时它也不了解控制器的情况。当模型发生改变时, 视图会得到通知,它可以访问模型的数据,但不能改变这些数据

 

Ø        Controller(控制器)

控制器对用户的输入做出反应并且将模型和视图联系在一起。servlet能够接受客户端的HTTP请求,并且根据需要创建所需的JavaBean或者EJB,然后将产生的变化通知给视窗

MVC设计模式的特点

        代码分离,显示与逻辑解耦

        验证处理

        流程控制

        更新应用程序的状态

MVC模式的结构

面向WEB应用的 MVC Model 2 模式

客户机和服务器的无状态连接

    由于HTTP本身缺乏状态信息,客户端必须对服务器进行再查询才能发现由输入所造成的改变,在这种情况下,控制器不能将应用程序的改变通知视图。

 

 

实现视图所用的技术与实现模型或控制器的技术不同。

    也可以使用Java代码来生成所有的Html,但这样会产生更多问题。

 

 

 

 

 

 

 

 

 

第三节           Struts概览

 

 

上图表示的是StrutsMVC

其中

Client Browser是客户发送请求的地方。

Controller Servlet接收来自浏览器的请求,并决定将这个请求发往何处;在Struts中,控制器是以 servlet 实现的一个命令设计模式。

Business Logic更新模型的状态,并帮助控制应用程序的流程。就 Struts 而言,这是通过作为实际业务逻辑包装的 Action 类完成的。

Model表示应用程序的状态。业务对象更新应用程序的状态。ActionForm bean 在会话级或请求级表示模型的状态,而不是在持久级。JSP 文件使用 JSP 标记读取来自 ActionForm bean 的信息。

View就是一个 JSP 文件。其中没有流程逻辑,没有业务逻辑,也没有模型信息, 只有标记。标记是使 Struts 有别于其他框架(如 Velocity)的因素之一。

Struts中所使用的组件

Struts中所使用的组件有:ActionServletActionClassActionFormActionMappingActionForwardActionErrorStruts标记库。

Ø        ActionServlet

Struts框架中的控制器;为org.apache.struts.action.ActionServlet,该类扩展了javax.servlet.http.HttpServlet,是Struts框架的核心。

ActionServlet (Command) 创建并使用ActionActionForm ActionForward。在初始化时读取 struts-config.xml 文件配置。

              基本功能:

        截获用户的Http请求

 

        把这个请求映射到相应的Action类,如果这是此类收到的第一个请求,   将初始化实例并缓存 

 

        创建或发现一个ActionForm bean实例(看配置文件是否定义),然后将请求过程移植到bean.

 

        调用Action实例的perform()方法并将ActioForm bean,Action Mapping对象,requestresponse对象传给它

 

        perform返回一个ActionForword对象,此对象连接到相应的jsp页面

web.xml中的配置:

 

 

    action

    org.apache.struts.action.ActionServlet

   

      config

      /WEB-INF/struts-config.xml

   

   

      debug

      2

   

   

      detail

      2

   

    2

 

 

 

 

 

 

 

Ø        ActionClass

Struts框架中封装事务逻辑。

所有Action类都扩展org.apache.struts.action.Action类,并且覆盖类中定义的perform()方法。 Action 类是业务逻辑的一个包装 ,用途是将 HttpServletRequest 转换为业务逻辑。 当事件进展到这一步时,输入表单数据(或 HTML 表单数据)已被从请求流中提取出来并转移到 ActionForm 类中。 ActionForm 类被传递到Actino类,这一切都是自动完成的。扩展 Action 类时要注意简洁。Action 类应该控制应用程序的流程,而不应该控制应用程序的逻辑。通过将业务逻辑放在单独的包或 EJB 中,我们就可以提供更大的灵活性和可重用性。

Action类必须以线程安全的方式进行编程,因为控制器会令多个同时发生的请求共享同一个实例,相应的,在设计Action类时就需要注意以下几点:

        不能使用实例或静态变量存储特定请求的状态信息,它们会在同一个操作中共享跨越请求的全局资源

        如果要访问的资源(如JavaBean和会话变量)在并行访问时需要进行保护,那么访问就要进行同步

Actionstruts-config.xml的配置:

  path="/cautionsave"

       type="org.apache.struts.webapp.example.CautionSaveAction"

       name="cautionsaveForm"

                  scope="session"

                  input="/S63.jsp">

            path="/S64.jsp"/>

 

 

Ø        ActionForm

用于封装数据,显示或向ActionClass的方法传送数据。

ActionForm类扩展org.apache.struts.action.ActionForm类,程序开发人员创建的bean能够包含额外的属性。 框架假设用户在应用程序中为每个表单都创建了一个ActionForm bean,维护 Web 应用程序的会话状态。如果使用动态ActionForm类,则只需在struts-config.xml中进行相应的配置,框架可自动生成ActionForm bean。典型的ActionFrom bean只有属性的设置与读取方法(getXXX,而没有实现事务逻辑的方法。只有简单的输入检查逻辑,使用的目的是为了存储用户在相关表单中输入的最新数据,以便可以将同一网页进行再生,同时提供一组错误信息,这样就可以让用户修改不正确的输入数据

Struts 框架将对ActionForm执行以下操作

        检查 UserActionForm 是否存在;如果不存在,它将创建该类的一个实例。

        将使用 HttpServletRequest 中相应的域设置 ActionForm 的状态。没有太多讨厌的 request.getParameter() 调用。

        Struts 框架在将 ActionForm传递给业务包装 Action 之前将更新它的状态。

        在将它传递给 Action 类之前,Struts 还会对 ActionForm调用 validation() 方法进行表单状态验证,但不提倡这种做法。

        可在会话级维护 ActionForm

ActionFormstruts-config.xml中的配置:

 

      

      

 

 

Ø        ActionMapping

帮助控制器将请求映射到操作。

struts-config.xml 配置信息被转换为一组 ActionMapping,而后者又被放入 ActionMappings 容器中。 ActionMapping对象帮助进行框架内部的流程控制,它们可将特定请求URI映射到特定Action,并且将Action类与ActionForm bean相关联。ActionServlet (Command) 通过 perform() 方法将 ActionMapping 传递给 Action 类。这样就使 Action 可访问用于控制流程的信息。Action将使用ActionMappingfindForward()方法,此方法返回一个指定名称的ActionForward,这样Action就完成了本地转发。

 

Ø        ActionForward

用来指示操作转移的对象。

 

Ø        ActionError

用来存储和回收错误。

ActionError Struts 保持错误列表的方式,封装了单个错误消息。 ActionError类从不独立进行错误处理,它们总是被存储在ActionErrors对象中,View 可以使用标记访问这些类 如下所示:

 

 

Ø        Strtus标记库

用于View层显示,减轻表示层的开发工作。

JSP视图组件所使用的  struts 标记库由四类标记组成:

        Bean标记:用来在JSP页中管理bean

        Logic标记:用来在JSP页中控制流程

        HTML标记:用来生成HTML标记,在表单中显示数据,使用会话IDURL进行编程

        模板标记:使用动态模板构造普通格式的页

下面,分别为大家介绍这四类标记。

1.Bean标记

        创建和复制bean的标记

  Type=“java.long.int”/>

 

        脚本变量定义标记

 

        显示Bean属性

myBean property=myProperty scope=request filter=”true”/>

 

        消息标记和国际化

java.util数据包中定义的LocaleResourceBundle

 

2.Logic标记

        实体常数比较标记

lTransactionTypeID value= 12 >            业务类型为保证金存款

 

        属性存在标记

collect" scope="request"> 

  

 

 

        匹配标记

       

   

 

        重复标记

 

          

class=ItemBody height=20 width="10%">      

   

 

        转发和重定向标记

 

转发标记

重定向标记

标记是一个能够执行HTTP重定向的强大工具

 

3.HTML标记

        显示表单元素和输入控件

表单标记

  action=“logon” focus=“username”>

表单内容

其他还有按钮和取消标记、 复位和提交标记 、文本和文本区标记 、检查框和复选框标记 、文件标记 、单选钮标记 、隐藏标记 、密码标记 、选择标记等等,可查http://apache.jakarta.com网站。

 

        显示错误信息的标记

   

 

        其他HTML标记

    : 显示HTML元素

    : 显示图象标记

    : 显示HTML链接或锚点

    : 创建没有锚点标记的URI

 

4.模板标记

        动态模板是模块化WEB页布局设计的强大手段

 

        插入标记

/>

 

        放置标记

 

        获得标记


 

第四节  Struts工作流程

 

Struts的工作流程见下图

1、应用服务启动时读取struts-config.xml配置文件

2、根据strus-config.xml中的配置项生成Action MappingsMapping中的信息包括:pathactionform beanforwards

3、web浏览器端发过来请求时,由充当ControllerActionServlet获取请求信息

4、ActionServlet根据获取的request查找path,决定使用哪个form bean和哪个action;在此,我们假设使用form bean2action2

5、ActionServlet判断是否存在form bean实例和action实例,若存在则重用,若不存在则创建

6、ActionServlet将控制权转交给Action,由Action来调用业务逻辑层的服务;form bean作为参数传入到action中,由action从中获取数据并传送到业务逻辑层

7、Action从业务逻辑层获取服务之后,返回ActionForward,控制权重新回到ActionServlet手中

8、ActionServlet根据ActionForward中的内容,查找Mappings,确定下一步显示哪个.jsp页面

9、应用服务器容器编译jsp文件,当遇到需要读取数据的tag时,调用form bean2getter方法

10、            编译jsphtml并发送给浏览器

第五节  Struts配置

Web.xml

    web.xml中声明ActionServlet,并且将它配置成启动时进行加载

    指定ActionServlet的启动配置文件如:struts-config.xml

    指定ActionServlet的启动模板配置文件(如果需要的话)如:tiles-defs.xml

    配置Http请求所要映射的servlet名称

    配置所有系统及用户自定义的标签库

 

Struts-config.xml

    全局转发

    ActionMapping

    ActionForm bean

    JDBC数据源

    指定资源文件的位置

    配置需要的Plug in

如:

添加校验模块,并指定其配置文件validator.xmlvalidator-rules.xml的位置

需要的Jar

Struts.jar

tiles.jar

jakarta-regexp-1.2.jar

commons-validator.jar

commons-beanutils.jar

commons-collections.jar

commons-dbcp.jar

commons-digester.jar

commons-logging.jar

commons-pool.jar

commons-services.jar

 


 

第五章  Hibernate

第一节  Hibernate概述

什么是Hibernate

在今日的企业环境中,把面向对象的软件和关系数据库一起使用可能是相当麻烦、浪费时间的。Hibernate 是一个面向Java 环境的对象/关系数据库映射工具。对象/关系数据库映射(object/relational mapping (ORM))这个术语表示一种技术,用来把对象模型表示的对象映射到基于SQL 的关系模型结构中去。

Hibernate 不仅仅管理Java 类到数据库表的映射,还提供数据查询和获取数据的方法,可以大幅度减少开发时人工使用SQL JDBC 处理数据的时间。Hibernate 的目标是对于开发者通常的数据持久化相关的编程任务,解放其中的95%

Hibernate体系结构

Hibernate 非常高层的概览:

这幅图展示了Hibernate 使用数据库和配置文件数据来为应用程序提供持久化服务(和持久化的对象)。

Hibernate 是比较复杂的,提供了好几种不同的运行方式。我们展示一下两种极端情况。

轻型体系结构

应用程序自己提供JDBC 连接,并且自行管理事务。这种方式使用了Hibernate API 的一个最小子集。

全面解决体系结构

对于应用程序来说,所有的底层JDBC/JTA API 都被抽象了,Hibernate 会替你照管所有的细节。

体系结构相关对象

n        SessionFactory (net.sf.hibernate.SessionFactory)

对编译过的映射文件的一个线程安全的,不可变的缓存快照。它是Session 的工厂,是ConnectionProvider 的客户。可能持有事务之间重用的数据的缓存。

n        会话Session (net.sf.hibernate.Session)

单线程,生命期短促的对象,代表应用程序和持久化层之间的一次对话。封装了一个JDBC 连接,也是Transaction 的工厂。持有持久化对象的缓存。

n        持久化对象(Persistent Object)及其集合(Collection)

生命期短促的单线程的对象,包含了持久化状态和商业功能。它们可能是普通的JavaBeans,唯一特别的是他们现在从属于且仅从属于一个Session

n        临时对象(Transient Object)及其集合(Collection

目前没有从属于一个Session 的持久化类的实例。他们可能是刚刚被程序实例化,还没有来得及被持久化,或者是被一个已经关闭的Session 所实例化的。

n        事务,Transaction (net.sf.hibernate.Transaction)

(可选) 单线程,生命期短促的对象,应用程序用它来表示一批工作的原子操作。是底层的JDBC,JTA 或者CORBA 事务的抽象。一个Session 可能跨越多个Transaction事务。

n        ConnectionProvider(net.sf.hibernate.connection.ConnectionProvider)

(可选)JDBC 连接的工厂和池。从底层的Datasource 或者 DriverManager 抽象而来。对应用程序不可见。

n        TransactionFactory (net.sf.hibernate.TransactionFactory)

(可选)事务实例的工厂。对应用程序不可见。

第二节  Hibernate基础语义

Configuration

正如其名,Configuration 类负责管理Hibernate 的配置信息。Hibernate 运行时需要获取一些底层实现的基本信息,其中几个关键属性包括:

Ø        数据库URL

Ø        数据库用户

Ø        数据库用户密码

Ø        数据库JDBC驱动类

Ø        数据库dialect,用于对特定数据库提供支持,其中包含了针对特定数据库特性的实现,如Hibernate数据类型到特定数据库数据类型的映射等。

 

使用Hibernate 必须首先提供这些基础信息以完成初始化工作,为后继操作做好准备。这些属性在hibernate配置文件(hibernate.cfg.xml hibernate.properties)中加以设定(参见后面“Hibernate配置”中的示例配置文件内容)。

 

当我们调用:

Configuration config = new Configuration().configure();

时,Hibernate会自动在当前的CLASSPATH 中搜寻hibernate.cfg.xml文件并将其读取到内存中作为后继操作的基础配置。Configuration 类一般只有在获取SessionFactory时需要涉及,当获取SessionFactory 之后,由于配置信息已经由Hibernate 维护并绑定在返回的SessionFactory之上,因此一般情况下无需再对其进行操作。

 

我们也可以指定配置文件名,如果不希望使用默认的hibernate.cfg.xml文件作为配置文件的话:

File file = new File("c://sample//myhibernate.xml");

Configuration config = new Configuration().configure(file);

SessionFactory

SessionFactory 负责创建Session 实例。我们可以通过Configuation 实例构建SessionFactory

Configuration config = new Configuration().configure();

SessionFactory sessionFactory = config.buildSessionFactory();

Configuration实例config会根据当前的配置信息,构造SessionFactory实例并返回。SessionFactory 一旦构造完毕,即被赋予特定的配置信息。也就是说,之后config 的任何变更将不会影响到已经创建的SessionFactory 实例(sessionFactory)。如果需要使用基于改动后的config 实例的SessionFactory,需要从config 重新构建一个SessionFactory实例。

Session

Session是持久层操作的基础,相当于JDBC中的Connection

Session实例通过SessionFactory实例构建:

Configuration config = new Configuration().configure();

SessionFactory sessionFactory = config.buildSessionFactory();

Session session = sessionFactory.openSession();

之后我们就可以调用Session所提供的savefindflush等方法完成持久层操作:

Ø        Find

String hql= " from TUser where name='Erica'";

List userList = session.find(hql);

Ø        Save

TUser user = new TUser();

user.setName("Emma");

session.save(user);

session.flush();

最后调用Session.flush方法强制数据库同步,这里即强制Hibernateuser实例立即同步到数据库中。如果在事务中则不需要flush方法,在事务提交的时候,hibernate自动会执行flush方法,另外当Session关闭时,也会自动执行flush方法。

Transaction

Transaction 是对实际事务实现的一个抽象,这些实现包括JDBC的事务、JTA 中的UserTransaction、甚至可以是CORBA 事务。为开发者提过一个统一事务的操作界面,使得项目可以在不同的环境和容器之间方便地移值。

使用方法:

        Transaction tx = session.beginTransaction();

        ······

        tx.commit();

当执行事务提交方法时,Hibernate会发现持久数据的变化,并根据这些变化同步更新到数据库中。必须注意的是,在一个事务之中不允许出现另外一个事务,也即:事务不运行嵌套。


 

第三节  Hibernate配置

hibernate.cfg.xml

一个典型的hibernate.cfg.xml配置文件如下:

PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"

"http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">

- SessionFactory 配置 -->

- 数据库URL -->

jdbc:mysql://localhost/sample

- 数据库JDBC驱动 -->

org.gjt.mm.mysql.Driver

- 数据库用户名 -->

User

- 数据库用户密码 -->

Mypass

net.sf.hibernate.dialect.MySQLDialect

- 是否将运行期生成的SQL输出到日志以供调试 -->

True

- 是否使用数据库外连接 -->

True

- 事务管理类型,这里我们使用JDBC Transaction -->

net.sf.hibernate.transaction.JDBCTransactionFactory

—映射文件配置,注意配置文件名必须包含其相对于根的全路径 -->

hibernate.properties

一个典型的hibernate.properties配置文件如下:

hibernate.dialect net.sf.hibernate.dialect.MySQLDialect

hibernate.connection.driver_class org.gjt.mm.mysql.Driver

hibernate.connection.driver_class com.mysql.jdbc.Driver

hibernate.connection.url jdbc:mysql:///sample

hibernate.connection.username user

hibernate.connection.password mypass


 

第四节  Hibernate映射

Hibernate对象和关系数据库之间的映射是用一个XML 文档(XML document)来定义的。这个映射文档被设计为易读的,并且可以手工修改。映射语言是以Java 为中心的,意味着映射是按照持久化类的定义来创建的,而非表的定义。

虽然很多Hibernate 用户选择手工定义XML 映射文档,也有一些工具来生成映射文档,包括XDoclet,Middlegen AndroMDA.

一个映射的例子如下所示:

你可能感兴趣的:(java高级教程)