Servlet 2.1规范概述
1概述
和传统的Server端扩展机制相比,Servlet有如下优点:
1. 比CGI脚本快,因为Servlet采用了不同的处理模式。
2. Servlet使用的标准API为大多数Web Server所接受。
3. 因为是Java语言开发的,所以拥有Java的所有优点,包括易于开发和平台无关等。
4. 可以方便地访问大量的Java类库资源。
2 Servlet生命周期
一个Servlet有一个生命周期,定义了一个Servlet 如何被加载和被初始化,它怎样接收请求、响应请求、怎样提供服务。
在代码中,Servlet生命周期由接口:javax.servlet.Servlet 所定义。 所有的Java Servlet 必须,直接或间接地实现javax.servlet.Servlet接口,这样才能在Servlet Engine上运行。Servlet Engine提供network Service, 响应MIME request, 运行Servlet Container。 javax.servlet.Servlet接口定义了一些方法,在Servlet 的生命同期中这些方法会在特定时间按照一定的顺序被调用。如下图:
2.1 Servlet 如何被加载(Load),被实例化(Instantiated)
Servlet Engine 负责实例化和加载Servlet,这个过程可以在Servlet Engine 加载时执行,可以在Servlet 响应请求时执行,也可以在两者之间的任何时候执行。
2.2 Servlet如何被初始化(Initialized)
Servlet Engine 加载好Servlet 后,必须要初始化它。初始化时Servlet 可以从数据库里读取初始数据,建立JDBC Connection,或者建立对其它有价值的资源的引用。
在初始化阶段,Init( )方法被调用。这个方法在javax.servlet.Serlet接口中定义。Init( )方法以一个Servlet 配置文件(ServletConfig 型)为参数。Servlet configuration 对象由Servlet Engine 实现,可以让Servlet 从中读取一些name-value对的参数值。ServletConfig对象还可以让Servlet Access 一个Servlet Context对象。
2.3 Servlet 如何处理请求
Servlet 被初始化以后,就处于能响应请求的就绪状态。每个对Servlet 的请求由一个Servlet Request 对象代表。Servlet 给客户端的响应由一个Servlet Response对象代表。
当客户端有一个请求时,Servlet Engine 将ServletRequest 和ServletResponse对象都转发给Servlet,这两个对象以参数的形式传给Service方法。这个方法由javax.servlet.Servlet定义、并由具体的Servlet 实现。
Servlet还可以实现 ServletRequest 和ServletResponse接口。ServletRequest接口可以让Servlet 获取客户端请求中的参数。如form data, request信息,协议类型等等。Servlet 可以从ServletInputStream流中读取request 数据。ServletResponse接口允许Servlet设置response headers和status codes 。实现这个接口可以使Servlet能访问ServletOutputStream流用来向客户端返回数据。
2.4 多线程和映射(Mapping)
在多线程环境中,大多数Servlet 必须能处理同时发生的多个请求。但一种情况例外,就是当一个Servlet 实现了 SingleThreadModel接口,这样的Servlet 只会响应同一时间的一个请求。
Servlet根据Servlet Engine 的Mapping 来响应客户端请求、Mapping将URL和Servlet实例相对应。比如:/hello/index.html可以对应HelloServlet。 然而,一个对应也可以将一个URL和多个Servlet实例相对应。比如,一个分布式的Servlet Engine 运行在多台机器上时, 同一个Servlet 可以有多个实例运行在不同的服务器上,以均衡处理的负载。作为一个Servlet 开发者。你不能假定Servlet将来只有一个实例。
2.5 Servlet如何被释放
Servlet Engine 没有必要在Servlet 生命周期的每一段时间内都保持Servlet的状态。Servlet Engine可以随时随意使用或释放Servlet。因此,你不能依赖Servlet class或其成员来存贮信息。
当Servlet Engine 判断一个Servlet应当被释放时,(比如说engine准备Shut down 或需要回收资源)engine必须让Servlet 能释放其正在使用的任何资源,并保存持续性的状态信息。这些可以通过调用Servlet的destroy方法来实现。
当Servlet Engine 释放一个servlet 以前必须让其完成当前实例的service方法或是等到timeout(如果engine定义了timeout)。当engine释放一个Servlet以后,engine将不能再将请求转发给它,engine必须彻底释放该servlet并将其标明为可回收的(给garbage collection)。
3 Servlet Mapping技术
作为一个Servlet Engine 开发者,你可以随意规定如何将客户端的请求映射到Servlets。Specification本身并不强制这种规则,然而你可以使用下面任何一种建议:
1. 你可以使一个servlet 只和一个URL对应。 如:URL/feedback/index.html对应feedBack class。
2. 可以认为指定的某些目录下全是Servlet。
3. 可以指定以特殊的后缀名结尾的请求为Servlet请求。 如:*.thtml认为是Servlet。
4. 使用特定的URL:/servlet/servlet_name.
5. 可以直接用Servlet的class名来激活它。 如:/servlet/com.foo.servlet.MailServlet.
4 Servlet Context ServletContext 接口
定义了一个Servlet context 对象,保存着Servlet engine 的信息。通过Servlet context, Servlet 可以记日志文件,可以获取资源和对象(比如RequestDispatcher)。一个Servlet 只能在一个Servlet context 下运行,但不同的Servlet能拥有Servlet Engine 的不同视图。
如果一个Servlet Engine支持虚拟主机,每个虚拟主机拥有一个Servlet context,它不能被多个虚拟主机共享。
Servlet Engine 可以让Servlet Context拥有自己的范围,就象作为URL的一部分。如一个Servlet Context 属于一个银行应用,可以被映射到/bank,这时一个getContext请求(由/bank/fooServlet发出)将返回/bank的Servlet Context。
5 HTTP Sessions
HTTP是一个stateless的协议,为了建立有效的Web Server Application, 你必须能识别来自远程客户端的众多请求中哪些是属于同一个客户端的。有许多追踪session的方法,但都很复杂,难于使用。
但是Java Servlet API提供了一个简单的接口,允许Servlet Engine来通过任何途径追踪一个用户的session。
5.1创建一个session
因为HTTP是一种"请求--应答"式的协议。一个session总是被认为是新的,直到有客户端join进来。Join意思是客户端向Server端返回了session的追踪信息,指明了session已经被建立。
如果客户端没有join一个session,你就不能假定接下来的客户端响应是属于当前的session。
如果有下述情况出现session就被认为是新的:
1.客户端还不知道任何关于此session的信息。
2. 客户端选择不加入session,比如客户端拒绝接受cookies。
作为一个servlet开发者,你必须设计Web Application能处理客户端没有或不能加入一个session的情况。Server将保持session对象一段时间,这个时间可以由Server或Servlet指定。当一个session过期后,Server将释放session对象和其它与之绑定在一起的所有对象。
5.2 绑定对象到一个session
如果有需要,比如能帮助你处理应用中的数据需要,你可能会绑定一些对象到一个session中。你可以绑定任何对象到HttpSession对象中,只要用唯一的标识名。任何绑定到session中的对象对其它任何一个处理同一个session中的请求的Servlet来讲,都是可见的。一些对象需要知道自己什么时候被放入或移出一个session,你可以通过HttpSession Binding Listener接口来获得这些信息。当你的servlet在session中存储或释放数据时,servlet engine检查对象是否通过实现Http Session Binding Listener的类来绑定,如果是,接口中的方法将通知对象,它已被绑定。
Servlet2.3 API小结
1.在Servlet2.3 API包含了两个包:Javax.servlet(通用servlet,提供 servlet/Web应用程序和Web容器之间的合同(contract);从开发者看,提供了处 理客户请求和开发基于servlet的Web应用程序的一个标准库(javax.servlet包 为开发一个跨平台、跨servlet容器的Web应用程序提供了基础))和javax.servlet.http(专用servlet,)
2.API包含了20个接口和16个类.(API指定了servlet请求和响应接口,而容器为他 们提供了基层的类实现)
3.javax.servlet接口
javax.servlet包由12个接口组成.Servlet容器提供了下列7个接口的实现:
.ServletConfig
.ServletContext
.ServletRequest
.ServletResponse
.RequestDispatcher
.FilterChain
.FilterConfig
这些是容器必须向servlet提供的对象,以便于像Web应用程序提供服务.
负责建立应用程序的程序员要实现剩下的5个接口:
.Servlet
.ServletContextListener
.ServletContextAttributeListener
.SingleThreadModel
.Filter
定义这些程序接口目的是使容器通过接口中定义的方法来调用相应的实现.
servlet容器只需要知道接口中定义的方法,而实现的细节则有开发者来完成.
4.javax.servlet类
在这个包中有7个类(加上两个异常类)
.GenericServlet
.ServletContextEvent
.ServletContextAttributeEvent
.ServletInputStream
.ServletOutputStream
.ServletRequestWrapper
.ServletResponseWrapper
GenericServlet抽象类可以由于开发独立于协议的servlet,并且只要求实现service()方法.
5.Servlet接口
所有的servlet必须实现Servlet接口.
6.servlet的存活期
Servlet接口定义了三个存活期方法,由servlet容器调用:
public void init(ServletConfig config)throws ServletException
public void service(ServletRequest req, ServletResponse res)throws ServletException,IOException
public void destroy()
7.获取初始化参数
Servlet接口定义了servlet必须实现的另一个方法:
public ServletConfig getServletConfig()
getServletConfig()方法设计用于返回面对ServletConfig对象的一个引用,其中包含着相应servlet的初始化和启动参数.
8.servlet线程问题
容器/服务器收到许多的请求,并且这些请求经常会同时或者几乎同时出现,因此容器必须负责为每个请求建立不同的线程.(service()方法可以由容器在不同的线程中调用,来处理众多的不同的请求).
9.有效的servlet存活期管理
当servlet实例被servlet容器从内存中泻出的时,该servlet容器将对该servlet调用destroy()方法.这个方法只在所有针对service()方法调用都完成或者超出时限的时候调用一次.
10.获取关于servlet的信息
在Servlet接口中有更多的方法需要有servlet实现:
public String getServletInfo() throws ServletException, IOException
getServletInfo()方法设计用于返回一个String对象,其中包含着关于该servlet的信息.
11.GenericServlet类
GenericServlet类是Servlet接口的一个抽象类的实现.
12.存活期方法
servlet初始化由一个init()方法完成.
public void init(ServletConfig config)
public void init()
init(ServletConfig)方法是Servlet接口要求的.当容器调用时,init(ServletConfig)方法的GenericServlet实现在servlet中存储对响应ServletConfig对象的一个引用,然后调用上面的第二个init()方法.在代码中调用超类(superclass)方法(通过super.init(config)).
Servlets在网站中的应用前景分析
CGI(通用网关接口)脚本编程在网络管理员的心目中一直牢牢地占据着重要的位置。目前, CGI脚本在很多网站上得到了应用,这种情况是否会一直持续下去?
我们现在将了解一下另一种在服务器端进行程序设计的方法,即采用Java语言。Java servlets是Sun Microsystems公司关于Java无处不在的战略的下一步的重大目标。
CGI FYI
获取从网页传送到客户的数据,用CGI实现很简单。通过解析服务器上的环境变量,CGI 脚本通过使用在HTTP协议中定义的标准事件(类似于POST事件),可以读取客户传送来的数据。
CGI的原理很简单,但在网络开发应用中,CGI程序设计需要专门的技巧,因为脚本语言,尤其是用于CGI的Perl语言,掌握起来相当有难度。不少网络浏览器的客户端,有界面友好的工具和脚本语言,但在服务器端的开发难度较大。微软的Active Server Pages,简称 ASP,可以简化服务器端的开发,它的语法是基于Visual Basic的VBScript.
缺省情况下,当每个用户查看一个网址时,就会调用一个CGI脚本,于是就会在服务器上启动一个新的进程或者程序。这样做,代价太昂贵,所以Netscape和微软分别推出NSAPI和ISAPI模块,这样就可以克服性能限制。使用这些模块,服务器端的功能可以包含在DLL格式的文件,多个客户可以使用同一可执行文件。同样,开发这样的程序需要高级的技能。
Java可以来解救
同单一的开发语言相结合,且又容易管理,还可以有效地使用服务器端的资源,这就是Java servlets所带来的好处。只要你熟悉Java,就可以很容易地写出容易扩充且富有效率的Java servlets代码,(在Java Servlet Developer´s Kit 中,Sun提供了一系列的类,为你做了大部分的工作,你可以从其网址http://www.javasoft.com/ 中下载)
Servlets在服务器上很容易配置。你可以得到一个方便的图形接口,来控制运行哪个servlets, 也可以容易地配置其它选项。这比管理CGI 脚本更容易,除此之外,你在更新servlets时,无需关闭服务器。
Servlets有其独特的优点,因为它们是用Java语言编写的,所以可以工作于流行的网络服务器上,包括:Netscape, Microsoft, Apache 和Sun公司自己开发的WebServer等服务器软件。 (现在,还有第三方的插件,可以让servlets运行在绝大部分平台上。你可以到Sun公司网站上去查询相关信息。) 这种跨平台的能力,对于那些在同一时间内,需要在不止一种平台上运行的网站来说,特别有用。你可以很容易地改变硬件平台,或者升级服务器,而无需改动服务器端的代码。
当然,在服务器上,你需要有Java虚拟机(JVM),Java虚拟机可以带来另外的好处,因为Java具有内在的垃圾搜集机制,你不会因出现servlet出错或者发生例外,而泄漏你的资源。从理论上讲,因为Java具有内在的安全机制,Java servlets比其竞争对手的同类产品更具健壮性。
另外一个依赖Java的原因是:Java可以访问数据库 (通过JDBC) 和进行分布式处理 (通过Java的远程方法调用,即RMI)。当然,你也可以不采用Java,可以在网站上的不同部分,采用多种语言和技术(用于创建动态HTML ,访问数据库,连接到不同的服务器)。而一旦使用Java,就可以完成上述的全部工作,这样Servlet模型就赋予Java一个崭新的,功能强大的角色,并且能够适应各种服务器。
创建一个Servlet
前面把Java servlet讲得这么动听,你也许会迫不急待地想试试servlet的用法。在这之前,你需要下载Sun公司的Servlet Developer´s Kit,之后再安装网络服务器,最后用Symantec的 Visual Cafe用来编译Java源代码,本文中,我们创建了一个典型的Java servlet样本. (你可下载JServlet.zip文件)
该servlet例子可以在支持servlet的网络服务器上运行,向假想的客户发布销售信息,为了便于管理,SalesInfoServlet自己记录数据,当然它也可以不这样做,通过JDBC 连接到“活动”的数据源上,但这就需要额外的部件,使得发布一个演示用的应用程序步骤更加复杂。
一旦把例子网页在网络服务器上安装完毕,用浏览器打开ProdUCtSalesDemo.html网页作为开始 (我们使用的是Netscape浏览器)。当客户调用一个servlet (在HTTP 中使用了标准的GET和POST事件),我们的ProductInfoServlet就根据客户的信息生成新的HTML 页面。这里的基本思想模仿的是一个简单的CGI-bin脚本的做法。事实上,为了保证向后的兼容性,Java servlets也可以运行CGI脚本,尽管它在Java中工作得更好。
让我们再来看一下ProductInfoServlet.java文件,以便了解Java servlets的一些细节。有人警告称:Sun公司已经推出JDK 1.2,所以servlets的一些细节,可能会随之而改变。回顾Java语言的简短历史,Java 开发者们一直具有开放性的思想,在新版本中,servlets的基本的工作原理不会改变。用户创建的servlet都需要通过Java关键字“extends”从HttpServlet 类中派生出来。HttpServer类及其相关类放在javax.servlet包中,该包中包含了额外的可以使用的服务器端的类。
你的servlet可具有很多有意义的功能,诸如具有内在的多任务机制,能够同网络服务器协同工作,配置灵活容易。对同一个Java小程序发生多次请求时,服务器的运行将更有效率。Servlet是由服务器负责加载和配置的。
创建网页
为了定制HTTP网页,我们需要重载或者定义doGet() 和 doPost() 方法,即裁剪这些方法。在这里,我们根据客户的选择,创建了一个新的网页,数据自身存储在Java小程序中的数组中,并且用定制的方法getSalesInfo()发送, clientArray 存储了一个客户记录的数组(实际上是个Java 向量容器),该数组存储基本的客户信息。在这里,我们使用clientID域,在salesArray容器(也是个向量)中进行“join”的编程操作,该容器存储单个的销售记录。把客户的数据同销售记录中的项目进行匹配,就可以构造出我们所要的数据。
在实际场合中,数据可以通过JDBC从数据库中获得。当客户端发送过来一个请求时,你可以使用Java的内在的String和 StringTokenizer类对经过servlet来回传输的数据,进行解析。通过使用String 和StringBuffer类,你可以创建新的HTML页。这里,我们构造了一个客户的基本信息的表单以及单个的货物销售记录清单。
采用server includes的方式,可以很容易地创建网页,我们可以在这些server includes填入客户数据,server includes所担任的角色是HTML的模板代码。(本例中使用的是SalesInfo.shtml)。一旦把定制的信息写到HTML模板文件中,我们可以立即创建客户数据,形成纯粹HTML语言格式文件,加上一些javascript脚本语言,没有在客户端使用Java语言。当然,如果在网络浏览器中使用Java部件,你可以完成功能更强的工作。
值得一提的是: servlets 并不仅仅适用于HTTP。 GenericServer类是个基本的servlet,可在页面中显示任何内容。Sun 的目标是让所有种类的网络服务,从标准的互联网协议,到特殊的协议,都可以采用servlets进行通信。但是,首先要让网络开发人员广泛接受servlets。我们的例子表明servlets的前景也许会很好,但是很难说开发者会放弃对CGI的喜爱。
有了servlets之后,Java的能力大大增强。作为在服务器端实现的技术,servlets速度快,功能强,适用于多种场合下的任务。一旦Java应用到服务器上,你会发现你的网站或者企业网中的程序的运行速度更快,也更容易维护。
Hibernate需要导入的jar包
使用Hibernate需要导入的一些jar包
hibernate2.jar
Hibernate的库,必须使用的jar包
cglib-full-2.0.2.jar
CGLIB库,Hibernate用它来实现PO字节码的动态生成,非常核心的库,必须使用的jar包
dom4j-1.4.jar
dom4j 是一个Java的XML API,类似于jdom,用来读写XML文件的。dom4j是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件,可以在SourceForge上找到它。在IBM developerWorks上面可以找到一篇文章,对主流的Java XML API进行的性能、功能和易用性的评测,dom4j无论在那个方面都是非常出色的。我早在将近两年之前就开始使用dom4j,直到现在。如今你可以看到越来越多的Java软件都在使用dom4j来读写XML,特别值得一提的是连Sun的JAXM也在用dom4j。这是必须使用的jar 包,Hibernate用它来读写配置文件。
odmg-3.0.jar
ODMG是一个ORM的规范,Hibernate实现了ODMG规范,这是一个核心的库,必须使用的jar包。
commons-collections-2.1.1.jar
Apache Commons包中的一个,包含了一些Apache开发的集合类,功能比java.util.*强大。必须使用的jar包。
commons-beanutils.jar
Apache Commons包中的一个,包含了一些Bean工具类类。必须使用的jar包。
*注:我没有在Hibernate的lib中看到这个包,不过在Struts中看到这个包,在网上查了一下,这个包提供了易用的java反射。我没有用这个包,也没有出问题(从这里看到的:http://www.blogjava.net/kobe09/archive/2006/06/14/52745.aspx )
commons-lang-1.0.1.jar
Apache Commons包中的一个,包含了一些数据类型工具类,是java.lang.*的扩展。必须使用的jar包。
commons-logging-1.0.4.jar
Apache Commons包中的一个,包含了日志功能,必须使用的jar包。
从网上查到的,以上为必需的包
anant-1.5.3.jar
Ant编译工具的jar包,用来编译Hibernate源代码的。如果你不准备修改和编译Hibernate源代码,那么就没有什么用,可选的jar包
ant-optional-1.5.3.jar
Ant的一个辅助包。
c3p0-0.8.4.5.jar
C3PO是一个数据库连接池,Hibernate可以配置为使用C3PO连接池。如果你准备用这个连接池,就需要这个jar包。
proxool-0.8.3.jar
也是一个连接池,同上。
commons-pool-1.2.jar, commons-dbcp-1.2.1.jar
DBCP数据库连接池,Apache的Jakarta组织开发的,Tomcat4的连接池也是DBCP。
实际上Hibernate自己也实现了一个非常非常简单的数据库连接池,加上上面3个,你实际上可以在Hibernate上选择4种不同的数据库连接池,选择哪一个看个人的偏好,不过DBCP可能更通用一些。另外强调一点,如果在EJB中使用Hibernate,一定要用App Server的连接池,不要用以上4种连接池,否则容器管理事务不起作用。
connector.jar
JCA 规范,如果你在App Server上把Hibernate配置为Connector的话,就需要这个jar。不过实际上一般App Server肯定会带上这个包,所以实际上是多余的包。
jaas.jar
JAAS是用来进行权限验证的,已经包含在JDK1.4里面了。所以实际上是多余的包。
jcs-1.0-dev.jar
如果你准备在Hibernate中使用JCS的话,那么必须包括它,否则就不用。
jdbc2_0-stdext.jar
JDBC2.0的扩展包,一般来说数据库连接池会用上它。不过App Server都会带上,所以也是多余的。
jta.jar
JTA规范,当Hibernate使用JTA的时候需要,不过App Server都会带上,所以也是多余的。
junit-3.8.1.jar
Junit包,当你运行Hibernate自带的测试代码的时候需要,否则就不用。
xalan-2.4.0.jar, xerces-2.4.0.jar, xml-apis.jar
Xerces 是XML解析器,Xalan是格式化器,xml-apis实际上是JAXP。一般App Server都会带上,JDK1.4也包含了解析器,不过不是Xerces,是Crimson,效率比较差,不过Hibernate用XML只不过是读取配置文件,性能没什么紧要的,所以也是多余的。
使用spring的hibernateTemplate的方法
1.管理SessionFactory
使用Spring整合Hibernate时我们不需要hibernate.cfg.xml文件。首先,在applicationContext.xml中配置数据源(dataSource)bean和session工厂(sessionFactory)bean。其中,在配置session工厂bean时,应该注入三个方面的信息:
●数据源bean
●所有持久化类的配置文件
●Hibernate的SessionFactory的属性
Hibernate的SessionFactory的属性信息又包括两个内容,一,Hibernate的连接方法;二,不同数据库连接,启动时的选择。
2.为HibernateTemplate注入SessionFactory对象,通过HibernateTemplate来持久化对象
Spring提供了HibernateTemplate,用于持久层访问,该模板无需打开Session及关闭Session。它只要获得SessionFactory的引用,将可以只能地打开Session,并在持久化访问结束后关闭Session,程序开发只需完成持久层逻辑,通用的操作(如对数据库中数据的增,删,改,查)则有HibernateTemplate完成。
HibernateTemplate有三个构造函数,不论是用哪一种构造,要使HibernateTemplate能完成持久化操作,都必须向其传入一个SessionFactory的引用。
HibernateTemplate的用法有两种,一种是常规的用法,另一种是复杂的用。
一,常规的用法
HibernateTemplate通过它自己的delete(Object entity) ,find(String queryString),save(Object entity)等等常用的方法即可完成大多数DAO对象的增,删,改,查等操作。
二,复杂的用法
HibernateTemplate的复杂的用法是通过如下的两个方法来完成的:
●Object execute(HibernateCallback action)
●List execute(HibernateCallback action)
这两个方法都需要一个HibernateCallback实例,程序开发者通过HibernateCallback,可以完全使用Hibernate灵活的方式来访问数据库,解决了Spring封装Hibernate后灵活不足的缺陷。HibernateCallback是一个接口,该接口只有一个方法doInHibernate(org.hibernate.Session session),该方法只有一个参数Session。
通常,程序中采用实现HibernateCallback的匿名内部类来获取HibernateCallback的实例,方法doInHibernate就是Spring执行的持久化操作。具体的代码实例如下:
public class PersonDaoImpl {
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public List findPersonByName(final String name) {
HibernateTemplate hibernateTemplate =new HibernateTemplate(this.sessionFactory);
return (List)hibernateTemplate.execute(
public Object doInHibernate(Session session) throws HibernateException {
List result =session.createCriteria(Person.clsss).add(Restrictions.like("name",name+"%")).list();
return result;
}
);
}
}
注:在方法doInHibernate内可以访问Session,该Session对象是绑定到该线程的Session实例,该方法内的持久层操作与不使用Spring时的持久层操作完全相同,这保证了对于复杂的持久层访问时,依然可以使用Hibernate的访问方式。
3.DAO的实现
DAO的实现有两种方式:一,继承HibernateDaoSupport实现DAO;二,基于Hibernate3.0实现DAO。
一,继承HibernateDaoSupport实现DAO
Spring为Hibernate的DAO提供了工具类HibernateDaoSupport。该类主要提供了如下两个方法来方便DAO的实现:
●public final HibernateTemplate getHibernateTemplate()
●public final void setSessionFactory(SessionFactory sessionFactory)
其中,setSessionFactory方法用来接收Spring的ApplicationContext依赖注入的SessionFactory实例;getHibernateTemplate方法则用来根据刚才的SessionFactory产生Session,最后由HibernateTemplate来完成数据库访问。
二,基于Hibernate3.0实现DAO
在Hibernate处于事务的管理下时(通常Spring为Hibernate提供事务管理),通过SessionFactory的getCurrentSession()方法可以返回当前的Session,如果当前的JTA事务关联的Session不存在,则系统打开一次新的Session,并关联到当前的JTA事务;如果当前JTA事务关联的Session已经存在,则直接返回该Session。获得了当前的Session后就可以进行持久化操作了。
可见,不论使用上面的哪一种方式实现DAO都需要用Spring来注入SessionFactory实例。
4.事务的管理
Hibernate建议所有的对数据库的访问都应放在事务内进行,即使进行的只是读操作。Spring同时支持编程式事务和声明式事务。通常推荐使用声明式事务。
编程式事务管理:
编程式事务提供了TransactionTemplate模板类,用的时候必须向其体提供一个PlatformTransactionManager实例。只要TransactionTemplate获取了PlatformTransactionManager的引用,TransactionTemplate就可以完成事务操作了。TransactionTemplate提供了一个execute方法,它接收一个TransactionCallback实例。TransactionCallback包含如下方法:
●Object doInTransaction(TransactionStatus status)
这是需要有返回值的情况。如果不需要有返回值的话,我们可以用TransactionCallbackWithOutResult类来代替TransactionCallback类,它也有一个方法:
●void doInTransaction(TransactionStatus status)
在这个两个方法中,在出现异常时,TransactionStatus的实例status可以调用setRollbackOnly()方法进行回滚。
一般情况下,向execute方法传入TransactionCallback或TransactionCallbackWithOutResult实例时,采用的是匿名内部类的形式。
声明式事务管理:
声明式事务管理的配置方式通常有三种:
●使用TransactionProxyFactoryBean为目标bean生成事务代理的配置。
●使用BeanNameAutoProxyCreator,根据bean name自动生成事务代理的方式,这是直接利用Spring的AOP框架配置事务代理的方式,需要对Spring的AOP框架有所了解。
●使用DefaultAdvisorAutoProxyCreator,这也是直接利用Spring的AOP框架配置事务代理的方式,只是这种配置方式的可读性不如使用BeanNameAutoProxyCreator的配置方式。
------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost/test</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>8093</value>
</property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="dataSource"/>
</property>
<property name="mappingResources">
<list>
<value>user.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="userDAO" class="com.dang.action.UserDAOImpl">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
<bean name="/regedit" class="com.dang.action.RegeditAction">
<property name="userDAO">
<ref bean="userDAO"/>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
<bean id="userDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="target">
<ref local="userDAO" />
</property>
<property name="transactionAttributes">
<props>
<prop key="create*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
- 默认分类(20)
- J2EE(25)
- Java(56)
- PHP(55)
- SEO(10)
- 网页设计(20)
- 网站建设(37)
- 数据库(7)
- JavaScript(17)
- JQuery(6)
- MySQL(20)
- SQL Server(6)
- Access(1)
- Oracle(6)
- office(6)
- Dreamweaver(4)
- Photoshop(12)
- Flash(9)
- Fireworks(13)
- CSS(14)
- HTML(4)
- .NET(7)
- ASP(2)
- DB2(1)
- Ajax(2)
- Linux(12)
- Struts(7)
- Hibernate(8)
- Spring(2)
- Jsp(22)
- Asp(8)
- C#(3)
- C++(1)
- 网络安全(5)
- 软件工程(7)
- XML(1)
- English(2)
- 计算机等级考试(2)
- 计算机病毒(4)
- 个人日志(76)
- 互联网(15)
- ActionScript(10)
- Android(3)
- 数据结构与算法(1)
- 游戏策略(3)
- 美文翻译(2)
- 编程开发(19)
- 计算机应用(4)
- 计算机(10)
- Unity3d(6)
- 其他(1)
- egret(1)