﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Java Stop Here-文章分类-Hibernate</title><link>http://www.blogjava.net/faithwind/category/7314.html</link><description>Love Java ,because you are my first lady !^_^</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 12:04:49 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 12:04:49 GMT</pubDate><ttl>60</ttl><item><title>Hibernate 延迟初始化错误（ERROR LazyInitializer）是如何产生的?</title><link>http://www.blogjava.net/faithwind/articles/30129.html</link><dc:creator>黑咖啡</dc:creator><author>黑咖啡</author><pubDate>Fri, 10 Feb 2006 05:53:00 GMT</pubDate><guid>http://www.blogjava.net/faithwind/articles/30129.html</guid><wfw:comment>http://www.blogjava.net/faithwind/comments/30129.html</wfw:comment><comments>http://www.blogjava.net/faithwind/articles/30129.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/faithwind/comments/commentRss/30129.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/faithwind/services/trackbacks/30129.html</trackback:ping><description><![CDATA[<DIV class=center>
<H4>摘要:</H4>延迟初始化错误是运用Hibernate开发项目时最常见的错误。如果对一个类或者集合配置了延迟检索策略，那么必须当代理类实例或代理集合处于持久化状态（即处于Session范围内）时，才能初始化它。如果在游离状态时才初始化它，就会产生延迟初始化错误。 <BR></DIV><!-- end of summary line -->
<DIV class=overflow id=text>延迟初始化错误（ERROR LazyInitializer）是如何产生的?<BR><BR>选自&lt;&lt;精通Hibernate：Java对象持久化技术详解&gt;&gt; 作者：孙卫琴 来源:www.javathinker.org<BR><BR>延迟初始化错误是运用Hibernate开发项目时最常见的错误。如果对一个类或者集合配置了延迟检索策略，那么必须当代理类实例或代理集合处于持久化状态（即处于Session范围内）时，才能初始化它。如果在游离状态时才初始化它，就会产生延迟初始化错误。<BR><BR>下面把Customer.hbm.xml文件的&lt;class&gt;元素的lazy属性设为true，表示使用延迟检索策略：<BR>&lt;class name="mypack.Customer" table="CUSTOMERS" lazy="true"&gt;<BR>当执行Session的load()方法时，Hibernate不会立即执行查询CUSTOMERS表的select语句，仅仅返回Customer类的代理类的实例，这个代理类具由以下特征：<BR>（1） 由Hibernate在运行时动态生成，它扩展了Customer类，因此它继承了Customer类的所有属性和方法，但它的实现对于应用程序是透明的。<BR>（2） 当Hibernate创建Customer代理类实例时，仅仅初始化了它的OID属性，其他属性都为null，因此这个代理类实例占用的内存很少。<BR>（3） 当应用程序第一次访问Customer代理类实例时（例如调用customer.getXXX()或customer.setXXX()方法），Hibernate会初始化代理类实例，在初始化过程中执行select语句，真正从数据库中加载Customer对象的所有数据。但有个例外，那就是当应用程序访问Customer代理类实例的getId()方法时，Hibernate不会初始化代理类实例，因为在创建代理类实例时OID就存在了，不必到数据库中去查询。<BR><BR>提示：Hibernate采用CGLIB工具来生成持久化类的代理类。CGLIB是一个功能强大的Java字节码生成工具，它能够在程序运行时动态生成扩展Java类或者实现Java接口的代理类。关于CGLIB的更多知识，请参考：http://cglib.sourceforge.net/。<BR>以下代码先通过Session的load()方法加载Customer对象，然后访问它的name属性： <BR><PRE class=overflow>tx = session.beginTransaction();<BR>Customer customer=(Customer)session.load(Customer.class,new Long(1));<BR>customer.getName();<BR>tx.commit();</PRE><BR><BR>在运行session.load()方法时Hibernate不执行任何select语句，仅仅返回Customer类的代理类的实例，它的OID为1，这是由load()方法的第二个参数指定的。当应用程序调用customer.getName()方法时，Hibernate会初始化Customer代理类实例，从数据库中加载Customer对象的数据，执行以下select语句：<BR><PRE class=overflow>select * from CUSTOMERS where ID=1;<BR>select * from ORDERS where CUSTOMER_ID=1;</PRE><BR><BR>当&lt;class&gt;元素的lazy属性为true，会影响Session的load()方法的各种运行时行为，下面举例说明。<BR><BR>1．如果加载的Customer对象在数据库中不存在，Session的load()方法不会抛出异常，只有当运行customer.getName()方法时才会抛出以下异常：<BR><PRE class=overflow>ERROR LazyInitializer:63 - Exception initializing proxy<BR>net.sf.hibernate.ObjectNotFoundException: No row with the given identifier exists: 1, of class: <BR>mypack.Customer</PRE><BR><BR>2．如果在整个Session范围内，应用程序没有访问过Customer对象，那么Customer代理类的实例一直不会被初始化，Hibernate不会执行任何select语句。以下代码试图在关闭Session后访问Customer游离对象：<BR><PRE class=overflow>tx = session.beginTransaction();<BR>Customer customer=(Customer)session.load(Customer.class,new Long(1));<BR>tx.commit();<BR>session.close();<BR>customer.getName();</PRE><BR><BR>由于引用变量customer引用的Customer代理类的实例在Session范围内始终没有被初始化，因此在执行customer.getName()方法时，Hibernate会抛出以下异常：<BR><PRE class=overflow>ERROR LazyInitializer:63 - Exception initializing proxy<BR>net.sf.hibernate.HibernateException: Could not initialize proxy - the owning Session was closed</PRE><BR>由此可见，Customer代理类的实例只有在当前Session范围内才能被初始化。<BR><BR>3．net.sf.hibernate.Hibernate类的initialize()静态方法用于在Session范围内显式初始化代理类实例，isInitialized()方法用于判断代理类实例是否已经被初始化。例如：<BR><PRE class=overflow>tx = session.beginTransaction();<BR>Customer customer=(Customer)session.load(Customer.class,new Long(1));<BR>if(!Hibernate.isInitialized(customer)) <BR>Hibernate.initialize(customer);<BR>tx.commit();<BR>session.close();<BR>customer.getName();</PRE><BR>以上代码在Session范围内通过Hibernate类的initialize()方法显式初始化了Customer代理类实例，因此当Session关闭后，可以正常访问Customer游离对象。<BR><BR>4．当应用程序访问代理类实例的getId()方法时，不会触发Hibernate初始化代理类实例的行为，例如：<BR><PRE class=overflow>tx = session.beginTransaction();<BR>Customer customer=(Customer)session.load(Customer.class,new Long(1));<BR>customer.getId();<BR>tx.commit();<BR>session.close();<BR>customer.getName();</PRE><BR><BR>当应用程序访问customer.getId()方法时，该方法直接返回Customer代理类实例的OID值，无需查询数据库。由于引用变量customer始终引用的是没有被初始化的Customer代理类实例，因此当Session关闭后再执行customer.getName()方法，Hibernate会抛出以下异常：<BR><PRE class=overflow>ERROR LazyInitializer:63 - Exception initializing proxy<BR>net.sf.hibernate.HibernateException: Could not initialize proxy - the owning Session was closed</PRE></DIV><img src ="http://www.blogjava.net/faithwind/aggbug/30129.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/faithwind/" target="_blank">黑咖啡</a> 2006-02-10 13:53 <a href="http://www.blogjava.net/faithwind/articles/30129.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从零开始创建基于struts1.2 + Hibernate3.0 Web工程</title><link>http://www.blogjava.net/faithwind/articles/30007.html</link><dc:creator>黑咖啡</dc:creator><author>黑咖啡</author><pubDate>Thu, 09 Feb 2006 03:42:00 GMT</pubDate><guid>http://www.blogjava.net/faithwind/articles/30007.html</guid><wfw:comment>http://www.blogjava.net/faithwind/comments/30007.html</wfw:comment><comments>http://www.blogjava.net/faithwind/articles/30007.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/faithwind/comments/commentRss/30007.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/faithwind/services/trackbacks/30007.html</trackback:ping><description><![CDATA[<UL>
<LI>1. <A href="http://dev2dev.bea.com.cn/bbsdoc/2005111503.html#1">环境说明</A> 
<LI>2. <A href="http://dev2dev.bea.com.cn/bbsdoc/2005111503.html#2">例子工程说明</A> 
<LI>3. <A href="http://dev2dev.bea.com.cn/bbsdoc/2005111503.html#3">建立工程</A> 
<UL>
<LI>3.1 <A href="http://dev2dev.bea.com.cn/bbsdoc/2005111503.html#4">创建新的Web Project</A> 
<LI>3.2 <A href="http://dev2dev.bea.com.cn/bbsdoc/2005111503.html#5">加载Struts</A> </LI></UL>
<LI>4. <A href="http://dev2dev.bea.com.cn/bbsdoc/2005111503.html#_Toc112057961">完善工程</A> 
<UL>
<LI>4.1 <A href="http://dev2dev.bea.com.cn/bbsdoc/2005111503.html#_Toc112057962">添加index画面</A> 
<LI>4.2 <A href="http://dev2dev.bea.com.cn/bbsdoc/2005111503.html#_Toc112057963">添加logon画面</A> 
<LI>4.3 <A href="http://dev2dev.bea.com.cn/bbsdoc/2005111503.html#_Toc112057964">修改WEB-INF/struts-config.xm</A>l 
<LI>4.4 <A href="http://dev2dev.bea.com.cn/bbsdoc/2005111503.html#_Toc112057965">添加formbean和actionbean</A> 
<LI>4.5 <A href="http://dev2dev.bea.com.cn/bbsdoc/2005111503.html#_Toc112057966">添加menu画面</A> </LI></UL></LI></UL>
<P><STRONG><A name=1></A>1. 环境说明</STRONG></P>
<P>　　安装Eclipse和安装MyEclipse组件的过程在这里不进行介绍。可以参考其它资料完成Eclipse环境的安装与资源的配置。</P>
<P>　　接下来的篇幅将给出一个在MyEclipse开发环境下的一个Web工程实例。说明在MyEclipse的集成开发环境下，如何利用Struts进行Web工程开发。</P>
<P>例子工程的环境：</P>
<P>Windows 2000 Professional或者更高的版本。<BR>J2SDK 5.0<BR>Apache Tomcat 5.0<BR>MySQL 4.0.14b<BR>Eclipse-SDK-3.1<BR>MyEclipse 4.0<BR>SQLyog407(可选)</P>
<P><STRONG><A name=2>2. 例子工程说明</A></STRONG></P>
<P>　　本例子是利用struts架构，实现用户logon的Web工程。在这个工程中，用户可以访问三个页面，index.jsp、logon.jsp、menu.jsp。他们的关系如下图所示：</P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111503b01.jpg" target=_blank><IMG height=126 src="http://dev2dev.bea.com.cn/images/051115/0511150301.jpg" width=216 border=0></A> </P>
<P>　　其中，左上角的方框代表struts结构中/WEB-INF/struts-config.xml中定义的，&lt;global-forwards&gt;，也就是在整个Web工程中，只要有logon的动作发生，都会使画面转移到logon.jsp。那么处理logon.jsp画面的formbeen是上图上放右侧的模块表示的formbean来完成——logonForm。</P>
<P>　　LogonFrom处理后会有两个结果，“success”的时候，画面会转移到menu.jsp，失败的话，回到logon画面。</P>
<P>　　在logon画面，用户需要输入用户名和密码，点击submit，进行登录认证。输入内容的检测是在logonForm的bean中检查。判断操作在logonAction的bean中完成，在logonAction的bean中，需要访问MySql数据库的Account表格，进行用户和密码的查询。查询成功的话，证明用户认证通过。 </P>
<P><STRONG><A name=3>3. 建立工程</A></STRONG></P>
<P><STRONG><A name=4>3.1 v创建新的Web Project</A></STRONG></P>
<P>　　启动MyEclipse，通过Wizard，建立一个Web工程。如下图：</P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111503b02.jpg" target=_blank><IMG height=235 src="http://dev2dev.bea.com.cn/images/051115/0511150302.jpg" width=232 border=0></A> </P>
<P>　　点击project后，MyEclipse弹出工程的对话框，我们在所罗列的工程中选中MyEclipse下面的J2EE Projects的Web Project。如下图所示：</P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111503b03.jpg" target=_blank><IMG height=273 src="http://dev2dev.bea.com.cn/images/051115/0511150303.jpg" width=276 border=0></A> </P>
<P>　　在Wizard的下一页，必要的输入信息是Project Name、Context root URL。最后点击finish，一个空的WebProject就已经建立起来了</P>
<P><STRONG><A id=5 name=5>3.2 加载Struts</A></STRONG></P>
<P>　　在新创建的Web Project中加载struts。</P>
<P>　　在MyEclipse集成开发环境下，已经集成了struts开发的环境，用户可以根据自己的实际需要，加载struts的环境。加载过程如下图：</P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111503b04.jpg" target=_blank><IMG height=265 src="http://dev2dev.bea.com.cn/images/051115/0511150304.jpg" width=219 border=0></A> </P>
<P>　　右键点击刚刚创建好的工程，点击MyEclipse属性，在扩展的右键菜单里面，选择Add Struts Capabilities。</P>
<P>　　MyEclipse集成环境就会自动将Struts所需要的目录结构进行创建，并将需要的环境资源自动引用到相应的目录中去。</P>
<P>　　我们还要对自动生成的Struts进行修正，首先，修改WEB-INF/web.xml 将&lt;web-app&gt;标签中的属性删除。&lt;web-app XXXXXXXXXXXXXXX&gt; -&gt; &lt;web-app&gt;</P>
<P>　　其次要添加本工程的标签定义库，添加&lt;taglib&gt;&lt;/taglib&gt; </P><PRE class=code>&lt;taglib&gt;
    &lt;taglib-uri&gt;/WEB-INF/app.tld&lt;/taglib-uri&gt;
    &lt;taglib-location&gt;/WEB-INF/app.tld&lt;/taglib-location&gt;
  &lt;/taglib&gt;
  &lt;taglib&gt;
    &lt;taglib-uri&gt;/WEB-INF/struts-bean.tld&lt;/taglib-uri&gt;
    &lt;taglib-location&gt;/WEB-INF/struts-bean.tld<BR>&lt;/taglib-location&gt;
  &lt;/taglib&gt;
  &lt;taglib&gt;
    &lt;taglib-uri&gt;/WEB-INF/struts-html.tld&lt;/taglib-uri&gt;
    &lt;taglib-location&gt;/WEB-INF/struts-html.tld<BR>&lt;/taglib-location&gt;
  &lt;/taglib&gt;
  &lt;taglib&gt;
    &lt;taglib-uri&gt;/WEB-INF/struts-logic.tld&lt;/taglib-uri&gt;
    &lt;taglib-location&gt;/WEB-INF/struts-logic.tld<BR>&lt;/taglib-location&gt;
  &lt;/taglib&gt;
</PRE>
<P><STRONG><A name=_Toc112057961>4. 完善工程</A></STRONG></P>
<P><STRONG><A name=_Toc112057962>4.1 添加index画面</A></STRONG></P>
<P>　　在加载完Struts结构之后，就可以在这个工程中添加内容了。我们可以添加一个画面JSP。添加JSP很简单，点击工程的右键，添加JSP。Wizard会弹出一个添加的对话框。如下图： </P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111503b05.jpg" target=_blank><IMG height=196 src="http://dev2dev.bea.com.cn/images/051115/0511150305.jpg" width=252 border=0></A> </P>
<P>　　在File Name栏中改变文件名称，改成index.jsp把这个jsp作为Web工程的第一个画面。</P>
<P>　　Template To Use 栏可以选择第五项（选择选择其他项也可以）。</P>
<P>　　对于新生成的jsp文件进行必要的修改。</P>
<P>Index.jsp文件：</P><PRE class=code>&lt;taglib&gt;
&lt;%@ page language="java" pageEncoding="UTF-8"%&gt;

&lt;%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %&gt;
&lt;%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %&gt;
&lt;%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %&gt;

&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;My JSP 'index.jsp' starting page&lt;/title&gt;
    
    <SPAN class=style1>&lt;meta http-equiv="pragma" content="no-cache"&gt;
    &lt;meta http-equiv="cache-control" content="no-cache"&gt;
    &lt;meta http-equiv="expires" content="0"&gt;
    &lt;meta http-equiv="keywords" content="<BR>keyword1,keyword2,keyword3"&gt;
    &lt;meta http-equiv="description" content="This is my page"&gt;
</SPAN>    
    &lt;!--
    &lt;link rel="stylesheet" type="text/css" href="styles.css"&gt;
    --&gt;
  &lt;/head&gt;
  
  &lt;body&gt;
  <SPAN class=style2>&lt;h3&gt;&lt;bean:message key="index.heading"/&gt;&lt;/h3&gt;
	&lt;html:link page="/logon.jsp"&gt;&lt;bean:message key="index.logon"/&gt;&lt;/html:link&gt;</SPAN>
&lt;/body&gt;
&lt;/html&gt;</PRE>
<P>　其中蓝色和橙色部分是修改的内容，蓝色部分是今后自动添加jsp文件必须修改的地方，让这个页面用到的tag都能在这个工程中定义的tag集合中找到。</P>
<P>　　橙色部分是画面的主要显示内容。&lt;h3&gt;&lt;/h3&gt;的内容是一段文本，内容被struts结构的静态文本集合中的index.heading给替换掉了。这个文本的内容可以在工程的src\com\yourcompany\struts\ApplicationResources.properties文件中找到。Struts结构推荐用户将页面上的静态文本用ApplicationResources的形式替换。这样可以在大量的维护页面文字时候，感到便捷很多，同时，也大大减轻了多国语言版本网页的维护。</P>
<P>　　&lt;html:link page="/logon.jsp"&gt;相当于html语言中的&lt;a herf=xxxxx&gt;。这个tag是在/WEB-INF/struts-html.tld中可以找到并在显示页面的时候，被转义成&lt;a herf=xxxxx&gt; </P>
<P><STRONG><A name=_Toc112057963>4.2 添加logon画面</A></STRONG></P>
<P>　　添加方法跟添加index画面相同。修改内容稍微有些差别。</P>
<P>Logon.jsp的内容：</P><PRE class=code>&lt;taglib&gt;
&lt;%@ page language="java" pageEncoding="UTF-8"%&gt;

<SPAN class=style1>&lt;%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %&gt;
&lt;%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %&gt;
&lt;%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %&gt;</SPAN>

&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt;
&lt;html:html locale="true"&gt;
  &lt;head&gt;
    &lt;html:base /&gt;
    
    &lt;title&gt;logon.jsp&lt;/title&gt;
    
    &lt;meta http-equiv="pragma" content="no-cache"&gt;
    &lt;meta http-equiv="cache-control" content="no-cache"&gt;
    &lt;meta http-equiv="expires" content="0"&gt;    
    &lt;meta http-equiv="keywords" <BR>content="keyword1,keyword2,keyword3"&gt;
    &lt;meta http-equiv="description" content="This is my page"&gt;
  &lt;/head&gt;
  
  &lt;body&gt;
    &lt;html:form <SPAN class=style2>action="/logon.do"</SPAN> method="post"  <SPAN class=style2>focus="userName"</SPAN>&gt;
      &lt;table border="0"&gt;
        &lt;tr&gt;
          &lt;td&gt;&lt;bean:message key="prompt.username"/&gt;&lt;/td&gt;
          &lt;td&gt;&lt;html:text <SPAN class=style2>property="userName"</SPAN> /&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td&gt;Password:&lt;/td&gt;
          &lt;td&gt;&lt;html:password property="password" /&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td colspan="2" align="center"&gt;&lt;html:submit /&gt;&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/table&gt;
    &lt;/html:form&gt;
  &lt;/body&gt;
&lt;/html:html&gt;</PRE>
<P>　　其中，蓝色部分是引用本工程的tag标示库，红色的部分是表单属性名称的修改，和指定action动作的名称。</P>
<P><STRONG><A name=_Toc112057964>4.3 修改WEB-INF/struts-config.xml</A></STRONG></P>
<P>　　画面上出现了form，那么根据struts的结构要求，就必须在WEB-INF/struts-config.xml中明确这个form的formbean（表单内容校验的java class）是什么。执行这个form的action（表单执行的内部逻辑）是什么，以及action的结果会产生怎样的画面迁移。这些都是在WEB-INF/struts-config.xml中定义的。也就是标准的MVC架构所要求的。 </P><PRE class=code><SPAN class=style1>&lt;taglib&gt;
&lt;struts-config&gt;
  &lt;form-beans &gt;
    &lt;form-bean name="logonForm" type="com.yourcompany.forms.<BR>LogonForm" /&gt;
  &lt;/form-beans&gt;</SPAN>

  <SPAN class=style2>&lt;global-forwards &gt;
    &lt;forward name="logon" path="/logon.jsp" /&gt;
  &lt;/global-forwards&gt;</SPAN>

  <SPAN class=style3>&lt;action-mappings &gt;
    &lt;action
      path="/logon"
      type="com.yourcompany.actions.LogonAction"
      name="logonForm"
      scope="request"
      input="/logon.jsp"&gt;
      &lt;forward name="success" path="/menu.jsp" /&gt;
      &lt;forward name="fails" path="/logon.jsp" /&gt;
    &lt;/action&gt;
  &lt;/action-mappings&gt;

</SPAN>  &lt;message-resources parameter="com.yourcompany.struts.<BR>ApplicationResources" /&gt;
&lt;/struts-config&gt;

</PRE>
<P>　　其中&lt;action&gt;部分是说明action的属性。</P>
<P>　　Path 指定Action处理的URL</P>
<P>　　Type 指定Action的类名</P>
<P>　　Name 指定Action主力的ActionForm名，与&lt;form-beans &gt;元素的name属性匹配。</P>
<P>　　Scope 指定ActionForm存在的范围</P>
<P>　　Input 指定包含客户提交表单的网页，如果ActionForm的Validate方法返回错误，则因该把用户请求转发到这个网页。</P>
<P>　　Validate 如果取值为true，则表示ActionServlet应该调用ActionForm的validate方法</P>
<P>　　Forward 就是Action的execute方法执行完毕后，把客户请求在转发给相应的页面。</P>
<P><STRONG><A name=_Toc112057965>4.4 添加formbean和actionbean</A></STRONG></P>
<P>　　添加方法跟JSP相同，但是在选择superclass的时候，formbean要选择ActionForm作为类的父类。Actionbean的父类是Action</P>
<P>　　下面是各自的代码</P>
<P>LogonForm.java文件内容:</P><PRE class=code>&lt;taglib&gt;
package com.yourcompany.forms;
import javax.servlet.http.HttpServletRequest;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;

public class LogonForm extends ActionForm {

	private static final long serialVersionUID <BR>= 7322786881443789688L;
	// ------------------------------<BR>--------------------------- Instance Variables
    private String username = null;
    private String password = null;

	// -------------------------<BR>-------------------------------- Methods
    public String getUserName() {
		return (this.username);
    }

    public void setUserName(String username) {
        this.username = username;
    }

    public String getPassword() {
		return (this.password);
    }

    public void setPassword(String password) {
        this.password = password;
    }

	public void reset(ActionMapping mapping, <BR>HttpServletRequest request) {
		this.password = null;
		this.username = null;
	}

}

LogonAction.java文件：
package com.yourcompany.actions;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.yourcompany.forms.LogonForm;

public class LogonAction extends Action {

	public ActionForward execute(ActionMapping <BR>mapping, ActionForm form,
			HttpServletRequest request, <BR>HttpServletResponse response) {

		String userName = null;
		String password = null;

		if (form != null) {
			userName = ((LogonForm) form).getUserName();
			password = ((LogonForm) form).getPassword();
		}
		if(userName.equals(“test1”) &amp;&amp; password. <BR>equals(“test1”)){
			return (mapping.findForward("success"));
}
else{
	return (mapping.findForward("fails"));
}
	}

}

</PRE>
<P><STRONG><A name=_Toc112057966>4.5 添加menu画面</A></STRONG></P>
<P>　　与添加index画面的方法相同。下面是menu.jsp文件的内容</P><PRE class=code>&lt;taglib&gt;
&lt;%@ page language="java" pageEncoding="UTF-8"%&gt;

&lt;%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %&gt;
&lt;%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %&gt;
&lt;%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %&gt;

&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt;
&lt;html:html locale="true"&gt;
  &lt;head&gt;
    &lt;html:base /&gt;
        &lt;title&gt;menu.jsp&lt;/title&gt;
        &lt;meta http-equiv="pragma" content="no-cache"&gt;
    &lt;meta http-equiv="cache-control" content="no-cache"&gt;
    &lt;meta http-equiv="expires" content="0"&gt;    
    &lt;meta http-equiv="keywords" content="keyword1,keyword2,keyword3"&gt;
    &lt;meta http-equiv="description" content="This is my page"&gt;
  &lt;/head&gt;
    &lt;body&gt;
	  &lt;h3&gt;&lt;bean:message key="menu.message"/&gt;&lt;/h3&gt;
  &lt;/body&gt;
&lt;/html:html&gt;</PRE>
<P align=left><STRONG>原帖出处</STRONG></P>
<P><A href="http://dev2dev.bea.com.cn/bbs/thread.jspa?forumID=121&amp;threadID=27383&amp;messageID=162564#162564" target=_blank>http://dev2dev.bea.com.cn/bbs/thread.jspa?forumID=121&amp;threadID=27383&amp;messageID=162564#162564</A></P>
<P align=left><STRONG>注:</STRONG>论坛集粹是从<A href="http://dev2dev.bea.com.cn/bbs/forum.jspa?forumID=122&amp;start=0" target=_blank>dev2dev论坛</A>摘录广大站友的原创、提问以及各种解答整理而来，如果您认为本文的内容已触犯了您的权益，请联系版主进行修改。<BR><BR></P>
<UL>
<LI>5. <A href="http://dev2dev.bea.com.cn/bbsdoc/2005111504.html#_Toc112057967">调试工程</A> 
<LI>6. <A href="http://dev2dev.bea.com.cn/bbsdoc/2005111504.html#_Toc112057968">Tomcat下如何配置mysql的数据库连接池</A> 
<UL>
<LI>6.1 <A href="http://dev2dev.bea.com.cn/bbsdoc/2005111504.html#_Toc112057969">配置server.xml</A> 
<LI>6.2 <A href="http://dev2dev.bea.com.cn/bbsdoc/2005111504.html#_Toc112057970">配置web.xm</A>l 
<LI>6.3 <A href="http://dev2dev.bea.com.cn/bbsdoc/2005111504.html#_Toc112057970">访问数据库的程序片段</A> 
<LI>6.4 <A href="http://dev2dev.bea.com.cn/bbsdoc/2005111504.html#_Toc112057972">Jsp页面(index.jsp)</A> </LI></UL>
<LI>7. <A href="http://dev2dev.bea.com.cn/bbsdoc/2005111504.html#_Toc112057973">Tomcat5.0下配置Hibernate3.0应用</A> 
<UL>
<LI>7.1 <A href="http://dev2dev.bea.com.cn/bbsdoc/2005111504.html#_Toc112057974">在Tomcat下建立数据库连接池，如6中所示</A> 
<LI>7.2 <A href="http://dev2dev.bea.com.cn/bbsdoc/2005111504.html#_Toc112057975">在Struts应用中添加Hibernate3.0支持</A> </LI></UL></LI></UL>
<P><STRONG><A name=_Toc112057967>5. 调试工程</A></STRONG></P>
<P>如果本地机器已经安装了Tomcat5，那么可以在MyEclilpse的环境下调试工程了。</P>
<P>指定Tomcat5 的web application service 如下图：</P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111504b01.jpg" target=_blank><IMG height=183 src="http://dev2dev.bea.com.cn/images/051115/0511150401.jpg" width=264 border=0></A> </P>
<P>将Enable选项打开，并且指定Tomcat的安装目录。</P>
<P>配置目前的工程到Tomcat中去。</P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111504b02.jpg" target=_blank><IMG height=31 src="http://dev2dev.bea.com.cn/images/051115/0511150402.jpg" width=264 border=0></A> </P>
<P>点选工具栏上的被红线圈出的按钮</P>
<P>在弹出来的对话框中选择，我们创建的工程，和添加Tomcat5 的web application service</P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111504b03.jpg" target=_blank><IMG height=208 src="http://dev2dev.bea.com.cn/images/051115/0511150403.jpg" width=240 border=0></A> </P>
<P>然后就可以按下工具栏上的启动服务按钮，调试这个Web工程了。</P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111504b04.jpg" target=_blank><IMG height=29 src="http://dev2dev.bea.com.cn/images/051115/0511150404.jpg" width=240 border=0></A> </P>
<P>每一次改动工程中的文件后，要想看看改动后的效果，那么就在配置工程中，重新发布这个工程到tomecat5去。</P>
<P><STRONG><A name=_Toc112057968></A>6. Tomcat下如何配置mysql的数据库连接池</STRONG></P>
<P><STRONG><A name=_Toc112057969></A>6.1 配置server.xml</STRONG></P>
<P>配置Tomcat的server.xml文件，路径：【TOMCAT_HOME】\common\lib下的server.xml文件在&lt;/host&gt;之前加入以下内容以添加JNDI数据源： </P><PRE class=code>&lt;taglib&gt;
&lt;Context path="/<SPAN class=style1>DBTest</SPAN>" docBase="<SPAN class=style1>DBTest</SPAN>"
        debug="5" reloadable="true" crossContext="true"&gt;
  &lt;Logger className="org.apache.catalina.logger.FileLogger"
             prefix="localhost_DBTest_log." suffix=".txt"
             timestamp="true"/&gt;
  &lt;Resource name="<SPAN class=style2>jdbc/TestDB</SPAN>"
               auth="Container"
               type="javax.sql.DataSource"/&gt;
  &lt;ResourceParams name="<SPAN class=style2>jdbc/TestDB</SPAN>"&gt;
    &lt;parameter&gt;
      &lt;name&gt;factory&lt;/name&gt;
    &lt;value&gt;org.apache.commons.dbcp.BasicDataSourceFactory&lt;/value&gt;
    &lt;/parameter&gt;
    &lt;!-- Maximum number of dB connections in pool. Make sure you
         configure your mysqld max_connections large enough to handle
         all of your db connections. Set to 0 for no limit.
         --&gt;
    &lt;parameter&gt;
      &lt;name&gt;maxActive&lt;/name&gt;
      &lt;value&gt;100&lt;/value&gt;
    &lt;/parameter&gt;
    &lt;!-- Maximum number of idle dB connections to retain in pool.
         Set to 0 for no limit.
         --&gt;
    &lt;parameter&gt;
      &lt;name&gt;maxIdle&lt;/name&gt;
      &lt;value&gt;30&lt;/value&gt;
    &lt;/parameter&gt;
    &lt;!-- Maximum time to wait for a dB connection to become available
         in ms, in this example 10 seconds. An Exception is thrown if
         this timeout is exceeded.  Set to -1 to wait indefinitely.
         --&gt;
    &lt;parameter&gt;
      &lt;name&gt;maxWait&lt;/name&gt;
      &lt;value&gt;10000&lt;/value&gt;
    &lt;/parameter&gt;
    &lt;!-- MySQL dB username and password for dB connections  --&gt;
    &lt;parameter&gt;
     &lt;name&gt;username&lt;/name&gt;
     &lt;value&gt;root&lt;/value&gt;
    &lt;/parameter&gt;
    &lt;parameter&gt;
     &lt;name&gt;password&lt;/name&gt;
     &lt;value&gt; &lt;/value&gt;
    &lt;/parameter&gt;
    &lt;!-- Class name for mm.mysql JDBC driver --&gt;
    &lt;parameter&gt;
       &lt;name&gt;driverClassName&lt;/name&gt;
       &lt;value&gt;org.gjt.mm.mysql.Driver&lt;/value&gt;
    &lt;/parameter&gt;
    &lt;!-- The JDBC connection url for connecting to your MySQL dB.
         The autoReconnect=true argument to the url makes sure that the
         mm.mysql JDBC Driver will automatically reconnect if mysqld closed the
         connection.  mysqld by default closes idle connections after 8 hours.
         --&gt;
    &lt;parameter&gt;
      &lt;name&gt;url&lt;/name&gt; &lt;value&gt;jdbc:mysql://192.168.0.208:3306<BR>/db_test_account?autoReconnect=true&lt;/value&gt;
    &lt;/parameter&gt;
  &lt;/ResourceParams&gt;
&lt;/Context&gt;
</PRE>
<P>注意:</P>
<P>*其中蓝色字体表示你这个应用的路径和别名,也就是你访问自己配置的这个web站点的名字,注意区分大小写,必须一致,否则系统无法正常运行(例:http://localhost:8080/DBTest)</P>
<P>*其中红色字体表示数据源的名字,注意将会被web.xml和你访问数据库的程序调用</P>
<P><STRONG><A name=_Toc112057970></A>6.2 配置web.xml</STRONG></P>
<P>配置Web用程序的web.xml文件 </P><PRE class=code>&lt;taglib&gt;
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
    &lt;!DOCTYPE web-app PUBLIC
    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd"&gt;
&lt;web-app&gt;
  &lt;description&gt;MySQL Test App&lt;/description&gt;
  &lt;resource-ref&gt;
      &lt;description&gt;DB Connection&lt;/description&gt;
      &lt;res-ref-name&gt;jdbc/TestDB&lt;/res-ref-name&gt;
      &lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;
      &lt;res-auth&gt;Container&lt;/res-auth&gt;
  &lt;/resource-ref&gt;
&lt;/web-app&gt;
</PRE>
<P><STRONG><A name=_Toc112057971></A>6.3 访问数据库的程序片段</STRONG></P><PRE class=code>&lt;taglib&gt;
package swt.db.DBUtility;

import javax.naming.*; 
import javax.sql.*; 
import java.sql.*; 

public class DBTest { 

  String foo = "Not Connected"; 
  int bar = -1; 
     
  public void init() { 
    try{ 
      Context ctx = new InitialContext(); 
      if(ctx == null )  
          throw new Exception("Boom - No Context"); 
      DataSource ds =  
            (DataSource)ctx.lookup( 
               "java:comp/env/jdbc/TestDB"); 
      if (ds != null) { 
        Connection conn = ds.getConnection();      
        if(conn != null)  { 
            foo = "Got Connection "+conn.toString(); 
            Statement stmt = conn.createStatement(); 
            ResultSet rst =  
                stmt.executeQuery( 
                  " select UserName from t_account "); 
            if(rst.next()) { 
               foo=rst.getString(1); 
               bar=208; 
            } 
            conn.close(); 
        } 
      } 
    }catch(Exception e) { 
      e.printStackTrace(); 
    } 
 } 
 public String getFoo() { return foo; } 
 public int getBar() { return bar;} 
}</PRE>
<P><STRONG><A name=_Toc112057972></A>6.4 Jsp页面(index.jsp)</STRONG></P><PRE class=code>&lt;taglib&gt;
&lt;%@ page language="java" pageEncoding="UTF-8"%&gt;
&lt;%@ page import ="swt.db.DBUtility.*" %&gt;
&lt;html&gt; 
  &lt;head&gt; 
    &lt;title&gt;DB Test&lt;/title&gt; 
  &lt;/head&gt; 
  &lt;body&gt; 
  &lt;% 
    DBTest tst = new DBTest();
    tst.init(); 
  %&gt; 
  &lt;h2&gt;Results&lt;/h2&gt; 
    Foo &lt;%= tst.getFoo() %&gt;&lt;br&gt; 
    Bar &lt;%= tst.getBar() %&gt; 
  &lt;/body&gt; 
&lt;/html&gt;</PRE>
<P>启动Tomcat在浏览器上输入<A href="http://localhost:8080/DBTest" target=_blank>http://localhost:8080/DBTest</A><BR><BR>备注：</P>
<P>连接池配置(Database&nbsp;Connection&nbsp;Pool&nbsp;(DBCP)&nbsp;Configurations)<BR>DBCP使用的是Jakarta-Commons&nbsp;Database&nbsp;Connection&nbsp;Pool&nbsp;要使用连接池需要如下的组件即jar文件</P>
<P>Jakarta-Commons&nbsp;DBCP&nbsp;1.1&nbsp;对应commons-dbcp-1.1.jar。<BR>Jakarta-Commons&nbsp;Collections&nbsp;2.0&nbsp;对应commons-collections.jar。<BR>Jakarta-Commons&nbsp;Pool&nbsp;1.1&nbsp;对应commons-pool-1.1.jar。<BR>这三个jar文件要与你的JDBC驱动程序一起放到【TOMCAT_HOME】\common\lib目录下以便让tomcat和你的web应用都能够找到。</P>
<P><STRONG><A name=_Toc112057973></A>7. Tomcat5.0下配置Hibernate3.0应用</STRONG></P>
<P><STRONG><A name=_Toc112057974></A>7.1 在Tomcat下建立数据库连接池，如6中所示</STRONG></P>
<P><A name=_Toc112057975><STRONG>7.2 在Struts应用中添加Hibernate3.0支持</STRONG></A> </P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111504b05.jpg" target=_blank><IMG height=125 src="http://dev2dev.bea.com.cn/images/051115/0511150405.jpg" width=300 border=0></A> </P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111504b06.jpg" target=_blank><IMG height=197 src="http://dev2dev.bea.com.cn/images/051115/0511150406.jpg" width=240 border=0></A> </P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111504b07.jpg" target=_blank><IMG height=207 src="http://dev2dev.bea.com.cn/images/051115/0511150407.jpg" width=252 border=0></A> </P>
<P>注意：hibernate.cfg.xml文件一定要存放到跟目录下，默认的也就是/web应用/src,这个部署这个应用的时候hibernate.cfg.xml才会出现在classes目录下，也就是hibernate存放配置文件的默认录入下. </P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111504b08.jpg" target=_blank><IMG height=208 src="http://dev2dev.bea.com.cn/images/051115/0511150408.jpg" width=252 border=0></A> </P>
<P>由于我们采用Tomcat提供的数据库连接池，所以这里我们将是用自己创建的SessionFactory类。点击完成MyEclipse会自动把Hibernate所需的的类库加入到当前应用中。接下来就是配置Hibernate连接数据库的所需的参数，以及性能参数（可选）。 </P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111504b09.jpg" target=_blank><IMG height=166 src="http://dev2dev.bea.com.cn/images/051115/0511150409.jpg" width=216 border=0></A> </P>
<P>既然我们选用应用服务器所提供的数据库连接池，那么在这里我们只须要指定数据源的名字：java:comp/env/jdbc/TestDB，其中jdbc/TestDB就是我们在Tomcat中配置的数据源，也就是我们上面提到的jdbc/TestDB，资源名称一定要匹配。其他的参数由于已经在Tomcat中配置过了，所以在这里就不用配置了，Dialect一定要指定跟我们数据库匹配的语言。 既然我们选用应用服务器所提供的数据库连接池，那么在这里我们只须要指定数据源的名字：java:comp/env/jdbc/TestDB，其中jdbc/TestDB就是我们在Tomcat中配置的数据源，也就是我们上面提到的jdbc/TestDB，资源名称一定要匹配。其他的参数由于已经在Tomcat中配置过了，所以在这里就不用配置了，Dialect一定要指定跟我们数据库匹配的语言。</P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111504b10.jpg" target=_blank><IMG height=111 src="http://dev2dev.bea.com.cn/images/051115/0511150410.jpg" width=240 border=0></A> </P>
<P>我们可以在这里配置Hibernate一些调整性能的参数（针对不同的数据库有些属性可能无效）。 </P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111504b11.jpg" target=_blank><IMG height=141 src="http://dev2dev.bea.com.cn/images/051115/0511150411.jpg" width=252 border=0></A> </P>
<P>在这里我们设置show_sql为true，这样在开发调试过程成控制台可以打印真正在数据库端执行的sql语句便于查找问题。其他一些属性可以参阅<A href="http://www.hibernate.org/" target=_blank>http://www.hibernate.org</A>。<BR>到这里Hibernate的配置已经基本完成，下面创建SessionFactory用来和数据库进行交互（Hibernate官方文档提供）。 </P><PRE class=code>package com.db;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {

    private static Log log = <BR>LogFactory.getLog(HibernateUtil.class);

    private static final SessionFactory sessionFactory;

    static {
        try {
            sessionFactory = new Configuration().configure().<BR>buildSessionFactory();
        } catch (Throwable ex) {
            log.error("Initial SessionFactory <BR>creation failed.", ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static final ThreadLocal session = new ThreadLocal();

    public static Session currentSession()  {
        Session s = (Session) session.get();
        if (s == null) {
            s = sessionFactory.openSession();
            session.set(s);
        }
        return s;
    }

    public static void closeSession() {
        Session s = (Session) session.get();
        if (s != null)
            s.close();
        session.set(null);
    }
}
</PRE>
<P>后面将会提到如何使用HibernateUtil,下面建立我们所需的数据库<BR>（略）我们可以使用208上的db_test_account这个数据库中的表message来测试我们的Hibernate配置是否成功。数据库样例： </P>
<P><IMG height=55 src="http://dev2dev.bea.com.cn/images/051115/0511150412.jpg" width=221> </P>
<P>建表语句： </P><PRE class=code>CREATE TABLE `message` (              
           `Id` varchar(50) NOT NULL default '0',   
           `text` varchar(50) default NULL,    
           `nextMessage` int(4) default NULL,  
           PRIMARY KEY  (`Id`)                 
          ) TYPE=MyISAM
</PRE>
<P>创建O/R Mapping:</P>
<P><IMG height=249 src="http://dev2dev.bea.com.cn/images/051115/0511150413.jpg" width=166> </P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111504b14.jpg" target=_blank><IMG height=313 src="http://dev2dev.bea.com.cn/images/051115/0511150414.jpg" width=282 border=0></A> </P>
<P>点击Edit </P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111504b15.jpg" target=_blank><IMG height=260 src="http://dev2dev.bea.com.cn/images/051115/0511150415.jpg" width=312 border=0></A></P>
<P>点击New添加MySQL的驱动，保存 </P>
<P><IMG height=249 src="http://dev2dev.bea.com.cn/images/051115/0511150416.jpg" width=165> </P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111504b17.jpg" target=_blank><IMG height=174 src="http://dev2dev.bea.com.cn/images/051115/0511150417.jpg" width=228 border=0></A> </P>
<P>激活Database Explorer，保存。 </P>
<P><IMG height=100 src="http://dev2dev.bea.com.cn/images/051115/0511150418.jpg" width=210> </P>
<P>选择Database Explorer，创建数据库链接： </P>
<P><IMG height=110 src="http://dev2dev.bea.com.cn/images/051115/05111504_clip19.jpg" width=316> </P>
<P>点击创建新的数据库,添加所需必要的参数 </P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111504b20.jpg" target=_blank><IMG height=169 src="http://dev2dev.bea.com.cn/images/051115/0511150420.jpg" width=216 border=0></A> </P>
<P>保存，然后右键点击该数据库选择open database，测试是否配置成功，如果不能连接查看该连接的配置参数。<BR></P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111504b21.jpg" target=_blank><IMG height=247 src="http://dev2dev.bea.com.cn/images/051115/0511150421.jpg" width=211 border=0></A> </P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111504b22.jpg" target=_blank><IMG height=199 src="http://dev2dev.bea.com.cn/images/051115/0511150422.jpg" width=252 border=0></A></P>
<P align=left>点击完成后MyEclipse会自动生成POJO和Map文件，并更新Hibernate的配置文件（主要是加载Map文件）。ID Generator选项可以根据你的需要进行选择，具体含义请参阅hibernate官方文档。下面建立一个测试用的jsp页面来看看Hibernate是否好用。<BR>//MyJsp.jsp</P><PRE class=code>&lt;%@ page language="java" import="com.db.*" pageEncoding="UTF-8"%&gt;
&lt;%
String path = request.getContextPath();
String basePath = request.getScheme()+":<BR>//"+request.getServerName()+":"+request.getServerPort()+path+"/";
%&gt;

&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;base href="&lt;%=basePath%&gt;"&gt;
    
    &lt;title&gt;My JSP 'MyJsp.jsp' starting page&lt;/title&gt;
    
    &lt;meta http-equiv="pragma" content="no-cache"&gt;
    &lt;meta http-equiv="cache-control" content="no-cache"&gt;
    &lt;meta http-equiv="expires" content="0"&gt;
    &lt;meta http-equiv="keywords" content="<BR>keyword1,keyword2,keyword3"&gt;
    &lt;meta http-equiv="description" content="This is my page"&gt;
    
    &lt;!--
    &lt;link rel="stylesheet" type="text/css" href="styles.css"&gt;
    --&gt;
  &lt;/head&gt;
  
  &lt;body&gt;
    &lt;%    
		org.hibernate.Session s = HibernateUtil.currentSession();
		String hql = " from Message where text='b'";
		try {
			org.hibernate.Query query = s.createQuery(hql);
			java.util.List msgList = query.list();
			hello.Message msg = (hello.Message) msgList.get(0);
			out.println(msg.getId());
			out.println(msg.getText());
			out.println(msg.getNextmessage());			
		} catch (org.hibernate.HibernateException e) {
			e.printStackTrace();
		}		
		HibernateUtil.closeSession();		
    %&gt;
  &lt;/body&gt;
&lt;/html&gt;

</PRE>
<P>正常的结果如下： </P>
<P><A href="http://dev2dev.bea.com.cn/images/051115/05111504b23.jpg" target=_blank><IMG height=57 src="http://dev2dev.bea.com.cn/images/051115/0511150423.jpg" width=252 border=0></A> </P>
<P align=left><STRONG>原帖出处</STRONG></P>
<P><A href="http://dev2dev.bea.com.cn/bbs/thread.jspa?forumID=121&amp;threadID=27383&amp;messageID=162564#162564" target=_blank>http://dev2dev.bea.com.cn/bbs/thread.jspa?forumID=121&amp;threadID=27383&amp;messageID=162564#162564</A></P>
<P><STRONG>注:</STRONG>论坛集粹是从<A href="http://dev2dev.bea.com.cn/bbs/forum.jspa?forumID=122&amp;start=0" target=_blank>dev2dev论坛</A>摘录广大站友的原创、提问以及各种解答整理而来，如果您认为本文的内容已触犯了您的权益，请联系版主进行修改。 </P><img src ="http://www.blogjava.net/faithwind/aggbug/30007.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/faithwind/" target="_blank">黑咖啡</a> 2006-02-09 11:42 <a href="http://www.blogjava.net/faithwind/articles/30007.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何从Hibernate2.1升级到Hibernate3.0？</title><link>http://www.blogjava.net/faithwind/articles/29998.html</link><dc:creator>黑咖啡</dc:creator><author>黑咖啡</author><pubDate>Thu, 09 Feb 2006 01:39:00 GMT</pubDate><guid>http://www.blogjava.net/faithwind/articles/29998.html</guid><wfw:comment>http://www.blogjava.net/faithwind/comments/29998.html</wfw:comment><comments>http://www.blogjava.net/faithwind/articles/29998.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/faithwind/comments/commentRss/29998.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/faithwind/services/trackbacks/29998.html</trackback:ping><description><![CDATA[<P>选自《精通Hibernate：Java对象持久化技术详解》 作者：孙卫琴 来源: www.javathinker.org <BR>如果转载，请标明出处，谢谢 </P>
<P>1.1 Hibernate API 变化 <BR>1.1.1 包名 <BR>1.1.2 org.hibernate.classic包 <BR>1.1.3 Hibernate所依赖的第三方软件包 <BR>1.1.4 异常模型 <BR>1.1.5 Session接口 <BR>1.1.6 createSQLQuery() <BR>1.1.7 Lifecycle 和 Validatable 接口 <BR>1.1.8 Interceptor接口 <BR>1.1.9 UserType和CompositeUserType接口 <BR>1.1.10 FetchMode类 <BR>1.1.11 PersistentEnum类 <BR>1.1.12 对Blob 和Clob的支持 <BR>1.1.13 Hibernate中供扩展的API的变化 <BR>1.2 元数据的变化 <BR>1.2.1 检索策略 <BR>1.2.2 对象标识符的映射 <BR>1.2.3 集合映射 <BR>1.2.4 DTD <BR>1.3 查询语句的变化 <BR>1.3.1 indices()和elements()函数 <BR></P>
<DIV id=a000854more>
<DIV id=more>
<P>尽管Hibernate 3.0 与Hibernate2.1的源代码是不兼容的，但是当Hibernate开发小组在设计Hibernate3.0时，为简化升级Hibernate版本作了周到的考虑。对于现有的基于Hibernate2.1的Java项目，可以很方便的把它升级到Hibernate3.0。 </P>
<P>本文描述了Hibernate3.0版本的新变化，Hibernate3.0版本的变化包括三个方面： <BR>（1）API的变化，它将影响到Java程序代码。 <BR>（2）元数据，它将影响到对象-关系映射文件。 <BR>（3）HQL查询语句。 </P>
<P>值得注意的是， Hibernate3.0并不会完全取代Hibernate2.1。在同一个应用程序中，允许Hibernate3.0和Hibernate2.1并存。 </P>
<P>1.1 Hibernate API 变化 </P>
<P>1.1.1 包名 </P>
<P>Hibernate3.0的包的根路径为: “org.hibernate” ，而在Hibernate2.1中为“net.sf.hibernate”。这一命名变化使得Hibernate2.1和Hibernate3.0能够同时在同一个应用程序中运行。 </P>
<P>如果希望把已有的应用升级到Hibernate3.0，那么升级的第一步是把Java源程序中的所有“net.sf.hibernate”替换为“org.hibernate”。 </P>
<P>Hibernate2.1中的“net.sf.hibernate.expression”包被改名为“org.hibernate.criterion”。假如应用程序使用了Criteria API，那么在升级的过程中，必须把Java源程序中的所有“net.sf.hibernate.expression”替换为“org.hibernate.criterion”。 </P>
<P>如果应用使用了除Hibernate以外的其他外部软件，而这个外部软件又引用了Hibernate的接口，那么在升级时必须十分小心。例如EHCache拥有自己的CacheProvider： net.sf.ehcache.hibernate.Provider，在这个类中引用了Hibernate2.1中的接口，在升级应用时，可以采用以下办法之一来升级EHCache: </P>
<P>（1）手工修改net.sf.ehcache.hibernate.Provider类，使它引用Hibernate3.0中的接口。 <BR>（2）等到EHCache软件本身升级为使用Hibernate3.0后，使用新的EHCache软件。 <BR>（3）使用Hibernate3.0中内置的CacheProvider：org.hibernate.cache.EhCacheProvider。 </P>
<P>1.1.2 org.hibernate.classic包 </P>
<P>Hibernate3.0把一些被废弃的接口都转移到org.hibernate.classic中。 </P>
<P>1.1.3 Hibernate所依赖的第三方软件包 </P>
<P>在Hibernate3.0的软件包的lib目录下的README.txt文件中，描述了Hibernate3.0所依赖的第三方软件包的变化。 </P>
<P>1.1.4 异常模型 </P>
<P>在Hibernate3.0中，HibernateException异常以及它的所有子类都继承了java.lang.RuntimeException。因此在编译时，编译器不会再检查HibernateException。 </P>
<P>1.1.5 Session接口 </P>
<P>在Hibernate3.0中，原来Hibernate2.1的Session接口中的有些基本方法也被废弃，但为了简化升级，这些方法依然是可用的，可以通过org.hibernate.classic.Session子接口来访问它们，例如： <BR>org.hibernate.classic.Session session=sessionFactory.openSession(); <BR>session.delete("delete from Customer "); <BR>在Hibernate3.0中，org.hibernate.classic.Session接口继承了org.hibernate.Session接口，在org.hibernate.classic.Session接口中包含了一系列被废弃的方法，如find()、interate()等。SessionFactory接口的openSession()方法返回org.hibernate.classic.Session类型的实例。如果希望在程序中完全使用Hibernate3.0，可以采用以下方式创建Session实例： </P>
<P>org.hibernate.Session session=sessionFactory.openSession(); </P>
<P>如果是对已有的程序进行简单的升级，并且希望仍然调用Hibernate2.1中Session的一些接口，可以采用以下方式创建Session实例： </P>
<P>org.hibernate.classic.Session session=sessionFactory.openSession(); </P>
<P>在Hibernate3.0中，Session接口中被废弃的方法包括： <BR>* 执行查询的方法：find()、iterate()、filter()和delete(String hqlSelectQuery) <BR>* saveOrUpdateCopy() </P>
<P>Hibernate3.0一律采用createQuery()方法来执行所有的查询语句，采用DELETE 查询语句来执行批量删除，采用merge()方法来替代 saveOrUpdateCopy()方法。 </P>
<P>提示：在Hibernate2.1中，Session的delete()方法有几种重载形式，其中参数为HQL查询语句的delete()方法在Hibernate3.0中被废弃，而参数为Ojbect类型的的delete()方法依然被支持。delete(Object o)方法用于删除参数指定的对象，该方法支持级联删除。 <BR>Hibernate2.1没有对批量更新和批量删除提供很好的支持，参见&lt;&lt;精通Hibernate&gt;&gt;一书的第13章的13.1.1节（批量更新和批量删除），而Hibernate3.0对批量更新和批量删除提供了支持，能够直接执行批量更新或批量删除语句，无需把被更新或删除的对象先加载到内存中。以下是通过Hibernate3.0执行批量更新的程序代码： <BR>Session session = sessionFactory.openSession(); <BR>Transaction tx = session.beginTransaction(); <BR>String hqlUpdate = "update Customer set name = :newName where name = :oldName"; <BR>int updatedEntities = s.createQuery( hqlUpdate ) <BR>.setString( "newName", newName ) <BR>.setString( "oldName", oldName ) <BR>.executeUpdate(); <BR>tx.commit(); <BR>session.close(); <BR>以下是通过Hibernate3.0执行批量删除的程序代码： <BR>Session session = sessionFactory.openSession(); <BR>Transaction tx = session.beginTransaction(); <BR>String hqlDelete = "delete Customer where name = :oldName"; <BR>int deletedEntities = s.createQuery( hqlDelete ) <BR>.setString( "oldName", oldName ) <BR>.executeUpdate(); <BR>tx.commit(); <BR>session.close(); </P>
<P>1.1.6 createSQLQuery() </P>
<P>在Hibernate3.0中，Session接口的createSQLQuery()方法被废弃，被移到org.hibernate.classic.Session接口中。Hibernate3.0采用新的SQLQuery接口来完成相同的功能。 </P>
<P>1.1.7 Lifecycle 和 Validatable 接口 </P>
<P>Lifecycle和Validatable 接口被废弃，并且被移到org.hibernate.classic包中。 </P>
<P>1.1.8 Interceptor接口 </P>
<P>在Interceptor 接口中加入了两个新的方法。 用户创建的Interceptor实现类在升级的过程中，需要为这两个新方法提供方法体为空的实现。此外，instantiate()方法的参数作了修改，isUnsaved()方法被改名为isTransient()。 </P>
<P>1.1.9 UserType和CompositeUserType接口 </P>
<P>在UserType和CompositeUserType接口中都加入了一些新的方法，这两个接口被移到org.hibernate.usertype包中，用户定义的UserType和CompositeUserType实现类必须实现这些新方法。 <BR>Hibernate3.0提供了ParameterizedType接口，用于更好的重用用户自定义的类型。 <BR>1.1.10 FetchMode类 </P>
<P>FetchMode.LAZY 和 FetchMode.EAGER被废弃。取而代之的分别为FetchMode.SELECT 和FetchMode.JOIN。 </P>
<P>1.1.11 PersistentEnum类 </P>
<P>PersistentEnum被废弃并删除。已经存在的应用应该采用UserType来处理枚举类型。 </P>
<P>1.1.12 对Blob 和Clob的支持 </P>
<P>Hibernate对Blob和Clob实例进行了包装，使得那些拥有Blob或Clob类型的属性的类的实例可以被游离、序列化或反序列化，以及传递到merge()方法中。 </P>
<P>1.1.13 Hibernate中供扩展的API的变化 </P>
<P>org.hibernate.criterion、 org.hibernate.mapping、 org.hibernate.persister和org.hibernate.collection 包的结构和实现发生了重大的变化。多数基于Hibernate <BR>2.1 的应用不依赖于这些包，因此不会被影响。如果你的应用扩展了这些包中的类，那么必须非常小心的对受影响的程序代码进行升级。 </P>
<P>1.2 元数据的变化 </P>
<P>1.2.1 检索策略 </P>
<P>在Hibernate2.1中，lazy属性的默认值为“false”，而在Hibernate3.0中，lazy属性的默认值为“true”。在升级映射文件时，如果原来的映射文件中的有关元素，如<SET>、<CLASS>等没有显式设置lazy属性，那么必须把它们都显式的设置为lazy=“true”。如果觉得这种升级方式很麻烦，可以采取另一简单的升级方式：在<HIBERNATE-MAPPING>元素中设置: default-lazy=“false”。 </P>
<P>1.2.2 对象标识符的映射 </P>
<P>unsaved-value属性是可选的，在多数情况下，Hibernate3.0将把unsaved-value="0" 作为默认值。 </P>
<P>在Hibernate3.0中，当使用自然主键和游离对象时，不再强迫实现Interceptor.isUnsaved()方法。 如果没有设置这个方法，当Hibernate3.0无法区分对象的状态时，会查询数据库，来判断这个对象到底是临时对象，还是游离对象。不过，显式的使用Interceptor.isUnsaved()方法会获得更好的性能，因为这可以减少Hibernate直接访问数据库的次数。 </P>
<P>1.2.3 集合映射 </P>
<P><INDEX>元素在某些情况下被<LIST-INDEX>和<MAP-KEY>元素替代。此外，Hibernate3.0用<MAP-KEY-MANY-TO-MANY> 元素来替代原来的<KEY-MANY-TO-MANY>.元素，用<COMPOSITE-MAP-KEY>元素来替代原来的<COMPOSITE-INDEX>元素。 </P>
<P>1.2.4 DTD </P>
<P>对象-关系映射文件中的DTD文档，由原来的： <BR>http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd <BR>改为： <BR>http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd </P>
<P>1.3 查询语句的变化 </P>
<P>Hibernate3.0 采用新的基于ANTLR的HQL/SQL查询翻译器，不过，Hibernate2.1的查询翻译器也依然存在。在Hibernate的配置文件中，hibernate.query.factory_class属性用来选择查询翻译器。例如： <BR>（1）选择Hibernate3.0的查询翻译器： <BR>hibernate.query.factory_class= org.hibernate.hql.ast.ASTQueryTranslatorFactory <BR>（2）选择Hibernate2.1的查询翻译器 <BR>hibernate.query.factory_class= org.hibernate.hql.classic.ClassicQueryTranslatorFactory </P>
<P>提示：ANTLR是用纯Java语言编写出来的一个编译工具，它可生成Java语言或者是C++的词法和语法分析器，并可产生语法分析树并对该树进行遍历。ANTLR由于是纯Java的，因此可以安装在任意平台上，但是需要JDK的支持。 <BR>Hibernate开发小组尽力保证Hibernate3.0的查询翻译器能够支持Hibernate2.1的所有查询语句。不过，对于许多已经存在的应用，在升级过程中，也不妨仍然使用Hibernate2.1的查询翻译器。 <BR>值得注意的是， Hibernate3.0的查询翻译器存在一个Bug：不支持某些theta-style连结查询方言：如Oracle8i的OracleDialect方言、Sybase11Dialect。解决这一问题的办法有两种：（1）改为使用支持ANSI-style连结查询的方言，如 Oracle9Dialect,（2）如果升级的时候遇到这一问题，那么还是改为使用Hibernate2.1的查询翻译器。 </P>
<P>1.3.1 indices()和elements()函数 </P>
<P>在HQL的select子句中废弃了indices()和elements()函数，因为这两个函数的语法很让用户费解，可以用显式的连接查询语句来替代 select elements(...) 。而在HQL的where子句中，仍然可以使用elements()函数。</P></DIV></DIV><img src ="http://www.blogjava.net/faithwind/aggbug/29998.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/faithwind/" target="_blank">黑咖啡</a> 2006-02-09 09:39 <a href="http://www.blogjava.net/faithwind/articles/29998.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>