??xml version="1.0" encoding="utf-8" standalone="yes"?> 安装Eclipse和安装MyEclipselg的过E在q里不进行介l。可以参考其它资料完成Eclipse环境的安装与资源的配|?/P>
接下来的幅给Z个在MyEclipse开发环境下的一个Web工程实例。说明在MyEclipse的集成开发环境下Q如何利用Strutsq行Web工程开发?/P>
例子工程的环境: Windows 2000 Professional或者更高的版本?BR>J2SDK 5.0 本例子是利用struts架构Q实现用户logon的Web工程。在q个工程中,用户可以讉K三个面Qindex.jsp、logon.jsp、menu.jsp。他们的关系如下图所C: 其中Q左上角的方框代表strutsl构?WEB-INF/struts-config.xml中定义的Q?lt;global-forwards>Q也是在整个Web工程中,只要有logon的动作发生,都会使画面{Udlogon.jsp。那么处理logon.jsp画面的formbeen是上图上攑֏侧的模块表示的formbean来完成——logonForm?/P>
LogonFrom处理后会有两个结果,“success”的时候,画面会{Udmenu.jspQ失败的话,回到logon画面?/P>
在logon画面Q用户需要输入用户名和密码,点击submitQ进行登录认证。输入内容的是在logonForm的bean中检查。判断操作在logonAction的bean中完成,在logonAction的bean中,需要访问MySql数据库的Account表格Q进行用户和密码的查询。查询成功的话,证明用户认证通过? 启动MyEclipseQ通过WizardQ徏立一个Web工程。如下图Q?/P>
点击project后,MyEclipse弹出工程的对话框Q我们在所|列的工E中选中MyEclipse下面的J2EE Projects的Web Project。如下图所C: 在Wizard的下一,必要的输入信息是Project Name、Context root URL。最后点击finishQ一个空的WebProject已l徏立v来了 在新创徏的Web Project中加载struts?/P>
在MyEclipse集成开发环境下Q已l集成了struts开发的环境Q用户可以根据自q实际需要,加蝲struts的环境。加载过E如下图Q?/P>
右键点击刚刚创徏好的工程Q点击MyEclipse属性,在扩展的右键菜单里面Q选择Add Struts Capabilities?/P>
MyEclipse集成环境׃自动Struts所需要的目录l构q行创徏Qƈ需要的环境资源自动引用到相应的目录中去?/P>
我们q要对自动生成的Strutsq行修正Q首先,修改WEB-INF/web.xml ?lt;web-app>标签中的属性删除?lt;web-app XXXXXXXXXXXXXXX> -> <web-app> 其次要添加本工程的标{֮义库Q添?lt;taglib></taglib> 在加载完Strutsl构之后Q就可以在这个工E中d内容了。我们可以添加一个画面JSP。添加JSP很简单,点击工程的右键,dJSP。Wizard会弹Z个添加的对话框。如下图Q? 在File Name栏中改变文g名称Q改成index.jsp把这个jsp作ؓWeb工程的第一个画面?/P>
Template To Use 栏可以选择W五(选择选择其他也可以Q?/P>
对于新生成的jsp文gq行必要的修攏V?/P>
Index.jsp文gQ?/P> 其中蓝色和橙色部分是修改的内容,蓝色部分是今后自动添加jsp文g必须修改的地方,让这个页面用到的tag都能在这个工E中定义的tag集合中找到?/P>
色部分是画面的主要昄内容?lt;h3></h3>的内Ҏ一D|本,内容被strutsl构的静态文本集合中的index.headingl替换掉了。这个文本的内容可以在工E的src\com\yourcompany\struts\ApplicationResources.properties文g中找到。Strutsl构推荐用户页面上的静态文本用ApplicationResources的Ş式替换。这样可以在大量的维护页面文字时候,感到便捷很多Q同Ӟ也大大减M多国语言版本|页的维护?/P>
<html:link page="/logon.jsp">相当于html语言中的<a herf=xxxxx>。这个tag是在/WEB-INF/struts-html.tld中可以找到ƈ在显C页面的时候,被{义成<a herf=xxxxx> dҎ跟添加index画面相同。修改内容稍微有些差别?/P>
Logon.jsp的内容: 其中Q蓝色部分是引用本工E的tag标示库,U色的部分是表单属性名U的修改Q和指定action动作的名U?/P>
4.3 修改WEB-INF/struts-config.xml 画面上出CformQ那么根据struts的结构要求,必dWEB-INF/struts-config.xml中明这个form的formbeanQ表单内Ҏ验的java classQ是什么。执行这个form的actionQ表单执行的内部逻辑Q是什么,以及action的结果会产生怎样的画面迁UR这些都是在WEB-INF/struts-config.xml中定义的。也是标准的MVC架构所要求的? 其中<action>部分是说明action的属性?/P>
Path 指定Action处理的URL Type 指定Action的类?/P>
Name 指定Actiond的ActionForm名,?lt;form-beans >元素的name属性匹配?/P>
Scope 指定ActionForm存在的范?/P>
Input 指定包含客户提交表单的网,如果ActionForm的ValidateҎq回错误Q则因该把用戯求{发到q个|页?/P>
Validate 如果取gؓtrueQ则表示ActionServlet应该调用ActionForm的validateҎ Forward 是Action的executeҎ执行完毕后,把客戯求在转发l相应的面?/P>
dҎ跟JSP相同Q但是在选择superclass的时候,formbean要选择ActionForm作ؓcȝ父类。Actionbean的父cLAction 下面是各自的代码 LogonForm.java文g内容: 与添加index画面的方法相同。下面是menu.jsp文g的内?/P> 原帖出处 http://dev2dev.bea.com.cn/bbs/thread.jspa?forumID=121&threadID=27383&messageID=162564#162564 ?论坛集a是从dev2dev论坛摘录q大站友的原创、提问以及各U解{整理而来Q如果您认ؓ本文的内容已触犯了您的权益,误pȝ主进行修攏V?BR> 如果本地机器已经安装了Tomcat5Q那么可以在MyEclilpse的环境下调试工程了?/P>
指定Tomcat5 的web application service 如下图: Enable选项打开Qƈ且指定Tomcat的安装目录?/P>
配置目前的工E到Tomcat中去?/P>
炚w工h上的被红U圈出的按钮 在弹出来的对话框中选择Q我们创建的工程Q和dTomcat5 的web application service 然后可以按下工h上的启动服务按钮Q调试这个Web工程了?/P>
每一ơ改动工E中的文件后Q要想看看改动后的效果,那么在配置工程中,重新发布q个工程到tomecat5厅R?/P>
6. Tomcat下如何配|mysql的数据库q接?/STRONG> 配置Tomcat的server.xml文gQ\径:【TOMCAT_HOME】\common\lib下的server.xml文g?lt;/host>之前加入以下内容以添加JNDI数据源: 注意: *其中蓝色字体表示你这个应用的路径和别?也就是你讉K自己配置的这个web站点的名?注意区分大小?必须一?否则pȝ无法正常q行(?http://localhost:8080/DBTest) *其中U色字体表示数据源的名字,注意会被web.xml和你讉K数据库的E序调用 配置Web用程序的web.xml文g 启动Tomcat在浏览器上输?A href="http://localhost:8080/DBTest" target=_blank>http://localhost:8080/DBTest q接池配|?Database Connection Pool (DBCP) Configurations) Jakarta-Commons DBCP 1.1 对应commons-dbcp-1.1.jar?BR>Jakarta-Commons Collections 2.0 对应commons-collections.jar?BR>Jakarta-Commons Pool 1.1 对应commons-pool-1.1.jar?BR>q三个jar文g要与你的JDBC驱动E序一h到【TOMCAT_HOME】\common\lib目录下以便让tomcat和你的web应用都能够找到?/P>
7.1 在Tomcat下徏立数据库q接池,?中所C?/STRONG> 7.2 在Struts应用中添加Hibernate3.0支持 注意Qhibernate.cfg.xml文g一定要存放到跟目录下,默认的也是/web应用/src,q个部vq个应用的时候hibernate.cfg.xml才会出现在classes目录下,也就是hibernate存放配置文g的默认录入下. ׃我们采用Tomcat提供的数据库q接池,所以这里我们将是用自己创徏的SessionFactorycR点d成MyEclipse会自动把Hibernate所需的的cd加入到当前应用中。接下来是配置Hibernateq接数据库的所需的参敎ͼ以及性能参数Q可选)? 既然我们选用应用服务器所提供的数据库q接池,那么在这里我们只要指定数据源的名字Qjava:comp/env/jdbc/TestDBQ其中jdbc/TestDB是我们在Tomcat中配|的数据源,也就是我们上面提到的jdbc/TestDBQ资源名UC定要匚w。其他的参数׃已经在Tomcat中配|过了,所以在q里׃用配|了QDialect一定要指定跟我们数据库匚w的语a?既然我们选用应用服务器所提供的数据库q接池,那么在这里我们只要指定数据源的名字Qjava:comp/env/jdbc/TestDBQ其中jdbc/TestDB是我们在Tomcat中配|的数据源,也就是我们上面提到的jdbc/TestDBQ资源名UC定要匚w。其他的参数׃已经在Tomcat中配|过了,所以在q里׃用配|了QDialect一定要指定跟我们数据库匚w的语a?/P>
我们可以在这里配|Hibernate一些调整性能的参敎ͼ针对不同的数据库有些属性可能无效)? 在这里我们设|show_sql为trueQ这样在开发调试过E成控制台可以打印真正在数据库端执行的sql语句便于查找问题。其他一些属性可以参?A target=_blank>http://www.hibernate.org?BR>到这里Hibernate的配|已l基本完成,下面创徏SessionFactory用来和数据库q行交互QHibernate官方文档提供Q? 后面会提到如何使用HibernateUtil,下面建立我们所需的数据库 语句Q? 创徏O/R Mapping: 点击Edit 点击NewdMySQL的驱动,保存 ȀzDatabase ExplorerQ保存? 选择Database ExplorerQ创建数据库链接Q? 点击创徏新的数据?d所需必要的参? 保存Q然后右键点击该数据库选择open databaseQ测试是否配|成功,如果不能q接查看该连接的配置参数?BR> 点击完成后MyEclipse会自动生成POJO和Map文gQƈ更新Hibernate的配|文Ӟ主要是加载Map文gQ。ID Generator选项可以Ҏ你的需要进行选择Q具体含义请参阅hibernate官方文档。下面徏立一个测试用的jsp面来看看Hibernate是否好用?BR>//MyJsp.jsp 正常的结果如下: 原帖出处 http://dev2dev.bea.com.cn/bbs/thread.jspa?forumID=121&threadID=27383&messageID=162564#162564 ?论坛集a是从dev2dev论坛摘录q大站友的原创、提问以及各U解{整理而来Q如果您认ؓ本文的内容已触犯了您的权益,误pȝ主进行修攏V?摘要:
延迟初始化错误是q用Hibernate开发项目时最常见的错误。如果对一个类或者集合配|了延迟索策略,那么必须当代理类实例或代理集合处于持久化状态(卛_于Session范围内)Ӟ才能初始化它。如果在游离状态时才初始化它,׃产生延迟初始化错误?
选自<<_NHibernateQJava对象持久化技术详?gt;> 作者:孙卫?来源:www.javathinker.org
延迟初始化错误是q用Hibernate开发项目时最常见的错误。如果对一个类或者集合配|了延迟索策略,那么必须当代理类实例或代理集合处于持久化状态(卛_于Session范围内)Ӟ才能初始化它。如果在游离状态时才初始化它,׃产生延迟初始化错误?BR>
下面把Customer.hbm.xml文g?lt;class>元素的lazy属性设为trueQ表CZ用gq检索策略:
<class name="mypack.Customer" table="CUSTOMERS" lazy="true">
当执行Session的load()ҎӞHibernate不会立即执行查询CUSTOMERS表的select语句Q仅仅返回Customercȝ代理cȝ实例Q这个代理类L以下特征Q?BR>Q?Q?由Hibernate在运行时动态生成,它扩展了Customerc,因此它承了Customercȝ所有属性和ҎQ但它的实现对于应用E序是透明的?BR>Q?Q?当Hibernate创徏Customer代理cd例时Q仅仅初始化了它的OID属性,其他属性都为nullQ因此这个代理类实例占用的内存很?BR>Q?Q?当应用程序第一ơ访问Customer代理cd例时Q例如调用customer.getXXX()或customer.setXXX()ҎQ,Hibernate会初始化代理cd例,在初始化q程中执行select语句Q真正从数据库中加蝲Customer对象的所有数据。但有个例外Q那是当应用程序访问Customer代理cd例的getId()ҎӞHibernate不会初始化代理类实例Q因为在创徏代理cd例时OID存在了Q不必到数据库中L询?BR>
提示QHibernate采用CGLIB工具来生成持久化cȝ代理cRCGLIB是一个功能强大的Java字节码生成工P它能够在E序q行时动态生成扩展JavacL者实现Java接口的代理类。关于CGLIB的更多知识,请参考:http://cglib.sourceforge.net/?BR>以下代码先通过Session的load()Ҏ加蝲Customer对象Q然后访问它的name属性: tx = session.beginTransaction();
Customer customer=(Customer)session.load(Customer.class,new Long(1));
customer.getName();
tx.commit();
在运行session.load()Ҏ时Hibernate不执行Q何select语句Q仅仅返回Customercȝ代理cȝ实例Q它的OID?Q这是由load()Ҏ的第二个参数指定的。当应用E序调用customer.getName()ҎӞHibernate会初始化Customer代理cd例,从数据库中加载Customer对象的数据,执行以下select语句Q?BR>select * from CUSTOMERS where ID=1;
select * from ORDERS where CUSTOMER_ID=1;
?lt;class>元素的lazy属性ؓtrueQ会影响Session的load()Ҏ的各U运行时行ؓQ下面D例说明?BR>
1Q如果加载的Customer对象在数据库中不存在QSession的load()Ҏ不会抛出异常Q只有当q行customer.getName()Ҏ时才会抛Z下异常:ERROR LazyInitializer:63 - Exception initializing proxy
net.sf.hibernate.ObjectNotFoundException: No row with the given identifier exists: 1, of class:
mypack.Customer
2Q如果在整个Session范围内,应用E序没有讉KqCustomer对象Q那么Customer代理cȝ实例一直不会被初始化,Hibernate不会执行Mselect语句。以下代码试囑֜关闭Session后访问Customer游离对象Q?BR>tx = session.beginTransaction();
Customer customer=(Customer)session.load(Customer.class,new Long(1));
tx.commit();
session.close();
customer.getName();
׃引用变量customer引用的Customer代理cȝ实例在Session范围内始l没有被初始化,因此在执行customer.getName()ҎӞHibernate会抛Z下异常:ERROR LazyInitializer:63 - Exception initializing proxy
net.sf.hibernate.HibernateException: Could not initialize proxy - the owning Session was closed
由此可见QCustomer代理cȝ实例只有在当前Session范围内才能被初始化?BR>
3Qnet.sf.hibernate.Hibernatecȝinitialize()静态方法用于在Session范围内显式初始化代理cd例,isInitialized()Ҏ用于判断代理cd例是否已l被初始化。例如:tx = session.beginTransaction();
Customer customer=(Customer)session.load(Customer.class,new Long(1));
if(!Hibernate.isInitialized(customer))
Hibernate.initialize(customer);
tx.commit();
session.close();
customer.getName();
以上代码在Session范围内通过Hibernatecȝinitialize()Ҏ昑ּ初始化了Customer代理cd例,因此当Session关闭后,可以正常讉KCustomer游离对象?BR>
4Q当应用E序讉K代理cd例的getId()ҎӞ不会触发Hibernate初始化代理类实例的行为,例如Q?BR>tx = session.beginTransaction();
Customer customer=(Customer)session.load(Customer.class,new Long(1));
customer.getId();
tx.commit();
session.close();
customer.getName();
当应用程序访问customer.getId()ҎӞ该方法直接返回Customer代理cd例的OID|无需查询数据库。由于引用变量customer始终引用的是没有被初始化的Customer代理cd例,因此当Session关闭后再执行customer.getName()ҎQHibernate会抛Z下异常:ERROR LazyInitializer:63 - Exception initializing proxy
net.sf.hibernate.HibernateException: Could not initialize proxy - the owning Session was closed
]]>
Apache Tomcat 5.0
MySQL 4.0.14b
Eclipse-SDK-3.1
MyEclipse 4.0
SQLyog407(可?<taglib>
<taglib-uri>/WEB-INF/app.tld</taglib-uri>
<taglib-location>/WEB-INF/app.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld
</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld
</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-logic.tld
</taglib-location>
</taglib>
<taglib>
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="
keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<h3><bean:message key="index.heading"/></h3>
<html:link page="/logon.jsp"><bean:message key="index.logon"/></html:link>
</body>
</html><taglib>
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html:html locale="true">
<head>
<html:base />
<title>logon.jsp</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords"
content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
<html:form action="/logon.do" method="post" focus="userName">
<table border="0">
<tr>
<td><bean:message key="prompt.username"/></td>
<td><html:text property="userName" /></td>
</tr>
<tr>
<td>Password:</td>
<td><html:password property="password" /></td>
</tr>
<tr>
<td colspan="2" align="center"><html:submit /></td>
</tr>
</table>
</html:form>
</body>
</html:html><taglib>
<struts-config>
<form-beans >
<form-bean name="logonForm" type="com.yourcompany.forms.
LogonForm" />
</form-beans>
<global-forwards >
<forward name="logon" path="/logon.jsp" />
</global-forwards>
<action-mappings >
<action
path="/logon"
type="com.yourcompany.actions.LogonAction"
name="logonForm"
scope="request"
input="/logon.jsp">
<forward name="success" path="/menu.jsp" />
<forward name="fails" path="/logon.jsp" />
</action>
</action-mappings>
<message-resources parameter="com.yourcompany.struts.
ApplicationResources" />
</struts-config>
<taglib>
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
= 7322786881443789688L;
// ------------------------------
--------------------------- Instance Variables
private String username = null;
private String password = null;
// -------------------------
-------------------------------- 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,
HttpServletRequest request) {
this.password = null;
this.username = null;
}
}
LogonAction.java文gQ?
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
mapping, ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
String userName = null;
String password = null;
if (form != null) {
userName = ((LogonForm) form).getUserName();
password = ((LogonForm) form).getPassword();
}
if(userName.equals(“test1? && password.
equals(“test1?){
return (mapping.findForward("success"));
}
else{
return (mapping.findForward("fails"));
}
}
}
<taglib>
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html:html locale="true">
<head>
<html:base />
<title>menu.jsp</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
<h3><bean:message key="menu.message"/></h3>
</body>
</html:html>
<taglib>
<Context path="/DBTest" docBase="DBTest"
debug="5" reloadable="true" crossContext="true">
<Logger className="org.apache.catalina.logger.FileLogger"
prefix="localhost_DBTest_log." suffix=".txt"
timestamp="true"/>
<Resource name="jdbc/TestDB"
auth="Container"
type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/TestDB">
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<!-- 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.
-->
<parameter>
<name>maxActive</name>
<value>100</value>
</parameter>
<!-- Maximum number of idle dB connections to retain in pool.
Set to 0 for no limit.
-->
<parameter>
<name>maxIdle</name>
<value>30</value>
</parameter>
<!-- 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.
-->
<parameter>
<name>maxWait</name>
<value>10000</value>
</parameter>
<!-- MySQL dB username and password for dB connections -->
<parameter>
<name>username</name>
<value>root</value>
</parameter>
<parameter>
<name>password</name>
<value> </value>
</parameter>
<!-- Class name for mm.mysql JDBC driver -->
<parameter>
<name>driverClassName</name>
<value>org.gjt.mm.mysql.Driver</value>
</parameter>
<!-- 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.
-->
<parameter>
<name>url</name> <value>jdbc:mysql://192.168.0.208:3306
/db_test_account?autoReconnect=true</value>
</parameter>
</ResourceParams>
</Context>
<taglib>
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<description>MySQL Test App</description>
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/TestDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
<taglib>
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;}
}
<taglib>
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ page import ="swt.db.DBUtility.*" %>
<html>
<head>
<title>DB Test</title>
</head>
<body>
<%
DBTest tst = new DBTest();
tst.init();
%>
<h2>Results</h2>
Foo <%= tst.getFoo() %><br>
Bar <%= tst.getBar() %>
</body>
</html>
备注Q?/P>
DBCP使用的是Jakarta-Commons Database Connection Pool 要用连接池需要如下的lg即jar文gpackage 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 =
LogFactory.getLog(HibernateUtil.class);
private static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new Configuration().configure().
buildSessionFactory();
} catch (Throwable ex) {
log.error("Initial SessionFactory
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);
}
}
Q略Q我们可以?08上的db_test_accountq个数据库中的表message来测试我们的Hibernate配置是否成功。数据库样例Q?
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
<%@ page language="java" import="com.db.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+":
//"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'MyJsp.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="
keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<%
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();
%>
</body>
</html>
]]>
如果转蝲Q请标明出处Q谢?
1.1 Hibernate API 变化
1.1.1 包名
1.1.2 org.hibernate.classic?
1.1.3 Hibernate所依赖的第三方软g?
1.1.4 异常模型
1.1.5 Session接口
1.1.6 createSQLQuery()
1.1.7 Lifecycle ?Validatable 接口
1.1.8 Interceptor接口
1.1.9 UserType和CompositeUserType接口
1.1.10 FetchModec?
1.1.11 PersistentEnumc?
1.1.12 对Blob 和Clob的支?
1.1.13 Hibernate中供扩展的API的变?
1.2 元数据的变化
1.2.1 索策?
1.2.2 对象标识W的映射
1.2.3 集合映射
1.2.4 DTD
1.3 查询语句的变?
1.3.1 indices()和elements()函数
管Hibernate 3.0 与Hibernate2.1的源代码是不兼容的,但是当Hibernate开发小l在设计Hibernate3.0Ӟ为简化升UHibernate版本作了周到的考虑。对于现有的ZHibernate2.1的Java目Q可以很方便的把它升U到Hibernate3.0?
本文描述了Hibernate3.0版本的新变化QHibernate3.0版本的变化包括三个方面:
Q?QAPI的变化,它将影响到JavaE序代码?
Q?Q元数据Q它媄响到对象-关系映射文g?
Q?QHQL查询语句?
值得注意的是Q?Hibernate3.0q不会完全取代Hibernate2.1。在同一个应用程序中Q允许Hibernate3.0和Hibernate2.1q存?
1.1 Hibernate API 变化
1.1.1 包名
Hibernate3.0的包的根路径? “org.hibernate?Q而在Hibernate2.1中ؓ“net.sf.hibernate”。这一命名变化使得Hibernate2.1和Hibernate3.0能够同时在同一个应用程序中q行?
如果希望把已有的应用升到Hibernate3.0Q那么升U的W一步是把Java源程序中的所有“net.sf.hibernate”替换ؓ“org.hibernate”?
Hibernate2.1中的“net.sf.hibernate.expression”包被改名ؓ“org.hibernate.criterion”。假如应用程序用了Criteria APIQ那么在升的过E中Q必LJava源程序中的所有“net.sf.hibernate.expression”替换ؓ“org.hibernate.criterion”?
如果应用使用了除Hibernate以外的其他外部YӞ而这个外部Y件又引用了Hibernate的接口,那么在升U时必须十分心。例如EHCache拥有自己的CacheProviderQ?net.sf.ehcache.hibernate.ProviderQ在q个cM引用了Hibernate2.1中的接口Q在升应用Ӟ可以采用以下办法之一来升UEHCache:
Q?Q手工修改net.sf.ehcache.hibernate.Providerc,使它引用Hibernate3.0中的接口?
Q?Q等到EHCache软g本n升Z用Hibernate3.0后,使用新的EHCache软g?
Q?Q用Hibernate3.0中内|的CacheProviderQorg.hibernate.cache.EhCacheProvider?
1.1.2 org.hibernate.classic?
Hibernate3.0把一些被废弃的接口都转移到org.hibernate.classic中?
1.1.3 Hibernate所依赖的第三方软g?
在Hibernate3.0的Y件包的lib目录下的README.txt文g中,描述了Hibernate3.0所依赖的第三方软g包的变化?
1.1.4 异常模型
在Hibernate3.0中,HibernateException异常以及它的所有子c都l承了java.lang.RuntimeException。因此在~译Ӟ~译器不会再查HibernateException?
1.1.5 Session接口
在Hibernate3.0中,原来Hibernate2.1的Session接口中的有些基本Ҏ也被废弃Q但Z化升U,q些Ҏ依然是可用的Q可以通过org.hibernate.classic.Session子接口来讉K它们Q例如:
org.hibernate.classic.Session session=sessionFactory.openSession();
session.delete("delete from Customer ");
在Hibernate3.0中,org.hibernate.classic.Session接口l承了org.hibernate.Session接口Q在org.hibernate.classic.Session接口中包含了一pd被废弃的ҎQ如find()、interate(){。SessionFactory接口的openSession()Ҏq回org.hibernate.classic.Sessioncd的实例。如果希望在E序中完全用Hibernate3.0Q可以采用以下方式创建Session实例Q?
org.hibernate.Session session=sessionFactory.openSession();
如果是对已有的程序进行简单的升Qƈ且希望仍然调用Hibernate2.1中Session的一些接口,可以采用以下方式创徏Session实例Q?
org.hibernate.classic.Session session=sessionFactory.openSession();
在Hibernate3.0中,Session接口中被废弃的方法包括:
* 执行查询的方法:find()、iterate()、filter()和delete(String hqlSelectQuery)
* saveOrUpdateCopy()
Hibernate3.0一律采用createQuery()Ҏ来执行所有的查询语句Q采用DELETE 查询语句来执行批量删除,采用merge()Ҏ来替?saveOrUpdateCopy()Ҏ?
提示Q在Hibernate2.1中,Session的delete()Ҏ有几U重载Ş式,其中参数为HQL查询语句的delete()Ҏ在Hibernate3.0中被废弃Q而参CؓOjbectcd的的delete()Ҏ依然被支持。delete(Object o)Ҏ用于删除参数指定的对象,该方法支持联删除?
Hibernate2.1没有Ҏ量更新和扚w删除提供很好的支持,参见<<_NHibernate>>一书的W?3章的13.1.1节(扚w更新和批量删除)Q而Hibernate3.0Ҏ量更新和扚w删除提供了支持,能够直接执行扚w更新或批量删除语句,无需把被更新或删除的对象先加载到内存中。以下是通过Hibernate3.0执行扚w更新的程序代码:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlUpdate = "update Customer set name = :newName where name = :oldName";
int updatedEntities = s.createQuery( hqlUpdate )
.setString( "newName", newName )
.setString( "oldName", oldName )
.executeUpdate();
tx.commit();
session.close();
以下是通过Hibernate3.0执行扚w删除的程序代码:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlDelete = "delete Customer where name = :oldName";
int deletedEntities = s.createQuery( hqlDelete )
.setString( "oldName", oldName )
.executeUpdate();
tx.commit();
session.close();
1.1.6 createSQLQuery()
在Hibernate3.0中,Session接口的createSQLQuery()Ҏ被废弃,被移到org.hibernate.classic.Session接口中。Hibernate3.0采用新的SQLQuery接口来完成相同的功能?
1.1.7 Lifecycle ?Validatable 接口
Lifecycle和Validatable 接口被废弃,q且被移到org.hibernate.classic包中?
1.1.8 Interceptor接口
在Interceptor 接口中加入了两个新的Ҏ?用户创徏的Interceptor实现cd升的过E中Q需要ؓq两个新Ҏ提供Ҏ体ؓI的实现。此外,instantiate()Ҏ的参C了修改,isUnsaved()Ҏ被改名ؓisTransient()?
1.1.9 UserType和CompositeUserType接口
在UserType和CompositeUserType接口中都加入了一些新的方法,q两个接口被Udorg.hibernate.usertype包中Q用户定义的UserType和CompositeUserType实现cdd现这些新Ҏ?
Hibernate3.0提供了ParameterizedType接口Q用于更好的重用用户自定义的cd?
1.1.10 FetchModec?
FetchMode.LAZY ?FetchMode.EAGER被废弃。取而代之的分别为FetchMode.SELECT 和FetchMode.JOIN?
1.1.11 PersistentEnumc?
PersistentEnum被废弃ƈ删除。已l存在的应用应该采用UserType来处理枚丄型?
1.1.12 对Blob 和Clob的支?
Hibernate对Blob和Clob实例q行了包装,使得那些拥有Blob或Clobcd的属性的cȝ实例可以被游R序列化或反序列化,以及传递到merge()Ҏ中?
1.1.13 Hibernate中供扩展的API的变?
org.hibernate.criterion?org.hibernate.mapping?org.hibernate.persister和org.hibernate.collection 包的l构和实现发生了重大的变化。多数基于Hibernate
2.1 的应用不依赖于这些包Q因此不会被影响。如果你的应用扩展了q些包中的类Q那么必非常小心的对受影响的程序代码进行升U?
1.2 元数据的变化
1.2.1 索策?
在Hibernate2.1中,lazy属性的默认gؓ“false”,而在Hibernate3.0中,lazy属性的默认gؓ“true”。在升映射文gӞ如果原来的映文件中的有兛_素,?SET>?CLASS>{没有显式设|lazy属性,那么必须把它们都昑ּ的设|ؓlazy=“true”。如果觉得这U升U方式很ȝQ可以采取另一单的升方式Q在
1.2.2 对象标识W的映射
unsaved-value属性是可选的Q在多数情况下,Hibernate3.0把unsaved-value="0" 作ؓ默认倹{?
在Hibernate3.0中,当用自然主键和游离对象Ӟ不再实现Interceptor.isUnsaved()Ҏ?如果没有讄q个ҎQ当Hibernate3.0无法区分对象的状态时Q会查询数据库,来判断这个对象到底是临时对象Q还是游d象。不q,昑ּ的用Interceptor.isUnsaved()Ҏ会获得更好的性能Q因可以减少Hibernate直接讉K数据库的ơ数?
1.2.3 集合映射
1.2.4 DTD
对象-关系映射文g中的DTD文档Q由原来的:
http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd
改ؓQ?
http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd
1.3 查询语句的变?
Hibernate3.0 采用新的ZANTLR的HQL/SQL查询译器,不过QHibernate2.1的查询翻译器也依然存在。在Hibernate的配|文件中Qhibernate.query.factory_class属性用来选择查询译器。例如:
Q?Q选择Hibernate3.0的查询翻译器Q?
hibernate.query.factory_class= org.hibernate.hql.ast.ASTQueryTranslatorFactory
Q?Q选择Hibernate2.1的查询翻译器
hibernate.query.factory_class= org.hibernate.hql.classic.ClassicQueryTranslatorFactory
提示QANTLR是用UJava语言~写出来的一个编译工P它可生成Java语言或者是C++的词法和语法分析器,q可产生语法分析树ƈ对该树进行遍历。ANTLR׃是纯Java的,因此可以安装在Q意^CQ但是需要JDK的支持?
Hibernate开发小l尽力保证Hibernate3.0的查询翻译器能够支持Hibernate2.1的所有查询语句。不q,对于许多已经存在的应用,在升U过E中Q也不妨仍然使用Hibernate2.1的查询翻译器?
值得注意的是Q?Hibernate3.0的查询翻译器存在一个BugQ不支持某些theta-styleq结查询方言Q如Oracle8i的OracleDialect方言、Sybase11Dialect。解册一问题的办法有两种Q(1Q改Z用支持ANSI-styleq结查询的方aQ如 Oracle9Dialect,Q?Q如果升U的时候遇到这一问题Q那么还是改Z用Hibernate2.1的查询翻译器?
1.3.1 indices()和elements()函数
在HQL的select子句中废弃了indices()和elements()函数Q因两个函数的语法很让用戯解,可以用显式的q接查询语句来替?select elements(...) 。而在HQL的where子句中,仍然可以使用elements()函数?/P>