﻿<?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-飞艳小屋-文章分类-hibernate</title><link>http://www.blogjava.net/songfei/category/10306.html</link><description>程序--人生--哲学___________________欢迎艳儿的加入</description><language>zh-cn</language><lastBuildDate>Mon, 02 Apr 2007 05:54:04 GMT</lastBuildDate><pubDate>Mon, 02 Apr 2007 05:54:04 GMT</pubDate><ttl>60</ttl><item><title>Hibernate技术全面学习 </title><link>http://www.blogjava.net/songfei/articles/107696.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Sat, 31 Mar 2007 14:00:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/107696.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/107696.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/107696.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/107696.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/107696.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Hibernate技术全面学习																																																																																																																																																															...&nbsp;&nbsp;<a href='http://www.blogjava.net/songfei/articles/107696.html'>阅读全文</a><img src ="http://www.blogjava.net/songfei/aggbug/107696.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2007-03-31 22:00 <a href="http://www.blogjava.net/songfei/articles/107696.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Hibernate中使用多表查询的一种实现 </title><link>http://www.blogjava.net/songfei/articles/107686.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Sat, 31 Mar 2007 13:20:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/107686.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/107686.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/107686.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/107686.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/107686.html</trackback:ping><description><![CDATA[Hibernate是典型的OPM工具，它将每一个物理表格（Table）映射成为对象（Object），这发挥了面向对象的优势，使设计和开发人员可以从面向对象的角度来进行对数据库的管理。<br />    在设计到多表操作时，Hibernate提供了与数据库表关系相对应的对象映射关系，一对一、一对多和多对多在这里都可以通过Hibernate的对象映射关系（Set等）来实现。这为一般情况下的数据库多表操作提供了便捷途径。关于这方面的介绍已经很多，在这里不再复述。<br />    但是，在有些情况下的多表操作，比如一个统计顾客在2005年的消费总金额的SQL操作如下：<br />select b.name, count(a.fee) mix(a.chargeBeginTime) max(a.chargeEndTime) from charge a, customer b where a.idCustomer = b.idCustomer and a.chargeBeginTime &gt;= '2005-01-01' and a.chargeEndTime &lt; '2005-12-31' gourp by a.idCustomer<br />customer表和charge结构如下：<br /><br />customer表结构：<br />+------------+-------------+------+-----+---------+-------+<br />| Field      | Type        | Null | Key | Default | Extra |<br />+------------+-------------+------+-----+---------+-------+<br />| IdCustomer | varchar(32) |      | PRI |         |       |<br />| Name       | varchar(30) |      |     |         |       |<br />+------------+-------------+------+-----+---------+-------+<br /><br />charge表结构：<br />+-----------------+-------------+------+-----+---------+-------+<br />| Field           | Type        | Null | Key | Default | Extra |<br />+-----------------+-------------+------+-----+---------+-------+<br />| IdCharge        | varchar(32) |      | PRI |         |       |<br />| Fee             | double      | YES  |     | NULL    |       |<br />| ChargeTimeBegin | datetime    | YES  |     | NULL    |       |<br />| ChargeTimeEnd   | datetime    | YES  |     | NULL    |       |<br />+-----------------+-------------+------+-----+---------+-------+<br /><br />在Hibernate的自带文档中有类似下面的多表查询操作提示：<br />“select new OjbectC(field1, field2,...) from ObjectA a, ObjectB b ...”，<br />分析一下可以看出这个操作有两个缺点：<br />    1）必须声明并创建类ObjectC，根据Hibernate的特点，需要写一个ObjectC.hbm.xml的PO映射，在只用到创建查询结果的新对象的时候，这个映射可以是个虚的，即可以没有一个真正的数据库表和ObjectC对应，但是这样的一个虚设的逻辑显然已经违背了Hibernate的思想初衷；<br />    2）这个办法只能查询出但条结果记录并只能创建单个的ObjectC对象，这是很局限的，因此在某些情况下根本不能使用（比如本例）。<br />    所以，对于本例，上面的方法是行不通的。<br /><br />其实，仔细看看Hibernate的API，就会发现这个问题很好解决。在net.sf.hibernate包中有下面三个对我们很有用的接口：<br /><br />1、Interface ScrollableResults<br />    这个接口类似JDBC中的ResultSet一样，提供了对返回结果集合的遍历和字段访问方法，如：<br />    public boolean <strong>next</strong>()    游标后移<br />    public boolean <strong>previous</strong>() 游标前移<br />    public boolean <strong>scroll</strong>(int i) 游标移动到指定未知<br />    public void <strong>beforeFirst</strong>() 游标在首记录前<br />    public void <strong>afterLast</strong>() 游标在末记录后<br />    public <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html"><font color="#002c99">Object</font></a>[] <strong>get</strong>() 将当前记录的字段值以Object对象数组形式返回<br />    public <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html"><font color="#002c99">Object</font></a><strong>get</strong>(int i) 将当前记录的特定字段值以Object对象形式返回<br />    public <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Integer.html"><font color="#002c99">Integer</font></a><strong>getInteger</strong>(int col) 将当前记录的特定字段值以Integer对象返回<br />    public <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Long.html"><font color="#002c99">Long</font></a><strong>getLong</strong>(int col) 将当前记录的特定字段值以Long对象返回<br />    public <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html"><font color="#002c99">String</font></a><strong>getText</strong>(int col) 将当前记录的特定字段值以Text对象返回<br />    public <a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html"><font color="#002c99">String</font></a><strong>getString</strong>(int col) 将当前记录的特定字段值以String对象返回<br />    ...等等<br /><br />2、Interface Query<br />    Query接口封装了对数据库的查询等操作，在这里，我们使用到它的原因是在于它的scroll()方法可以返回一个ScrollableResults实例：<br />    public <a title="interface in net.sf.hibernate" href="file:///E:/share/doc/hibernate-2.1/doc/api/net/sf/hibernate/ScrollableResults.html"><font color="#002c99">ScrollableResults</font></a><strong>scroll</strong>() 将查询结果以ScrollableResults实例返回，但需要注意的是查询返回的结果其实只是一些id，当需要的时候（比如我们使用ScrollableResults.next()方法后移游标时）这条需要用到的记录才会被真正初始化（这种技术可以称作：延时初始化）<br /><br />3、Interface Session<br />    Session是Hibernate的核心中的核心，通过Session的createQuery()方法，我们能生成一个Query实例：<br />    public <a title="interface in net.sf.hibernate" href="file:///E:/share/doc/hibernate-2.1/doc/api/net/sf/hibernate/Query.html"><font color="#002c99">Query</font></a><strong>createQuery</strong>(<a title="class or interface in java.lang" href="http://java.sun.com/j2se/1.3/docs/api/java/lang/String.html"><font color="#002c99">String</font></a> queryString) 用给出的HQL查询串创建一个Query实例<br /><br />好了，了解了上面的三个接口，问题就能够很好的解决了。需要如下几个文件：<br />Customer.java                            PO对象<br />Charge.java                                PO对象<br />TotalCharge.java                        用于保存统计结果Bean<br />Customer.hbm.xml                      PO映射<br />Charge.hbm.xml                          PO映射<br />TotalChargeDao.java                  统计Dao定义<br />TotalChargeDaoImpl.java           统计Dao定义实现<br />DaoFactory.java                         Dao工厂<br />HibernateSessionFactory.java     Session工厂<br /><br />因为这里主要讨论的重点是对Customer和Charge的联合查询，所以Customer.java、Charge.java、Customer.hbm.xml、Charge.hbm.xml四个文件以及TotalChargeDao.java、DaoFactory.java、HibernateSessionFactory.java的源代码在这里省略掉。<br /><br />TotalCharge.java 的源代码：<br /><table style="WIDTH: 656px; HEIGHT: 1011px" height="1011" cellspacing="0" cellpadding="0" width="656" border="1"><tbody><tr><td width="100%">package test.bean;<br /><br />/**<br /> *作者：孙星<br /> **/<br />public class TotalCharge {<br />  private String name;<br />  private Double fee;<br />  private java.util.Date chargeTimeBegin;<br />  private java.util.Date chargeTimeEnd;<br />  public TotalCharge() {<br />  } 
<p align="justify">  public String getName() {<br />    return name;<br />  }</p><p align="justify">  public TotalCharge(String name, Double fee, java.util.Date chargeTimeBegin,<br />                     java.util.Date chargeTimeEnd) {<br />    this.name = name;<br />    this.fee = fee;<br />    this.chargeTimeBegin = chargeTimeBegin;<br />    this.chargeTimeEnd = chargeTimeEnd;<br />  }</p><p align="justify">  public void setName(String name) {<br />    this.name = name;<br />  }</p><p align="justify">  public Double getFee() {<br />    return fee;<br />  }</p><p align="justify">  public void setFee(Double fee) {<br />    this.fee = fee;<br />  }</p><p align="justify">  public java.util.Date getChargeTimeBegin() {<br />    return chargeTimeBegin;<br />  }</p><p align="justify">  public void setChargeTimeBegin(java.util.Date chargeTimeBegin) {<br />    this.chargeTimeBegin = chargeTimeBegin;<br />  }</p><p align="justify">  public java.util.Date getChargeTimeEnd() {<br />    return chargeTimeEnd;<br />  }</p><p align="justify">  public void setChargeTimeEnd(java.util.Date chargeTimeEnd) {<br />    this.chargeTimeEnd = chargeTimeEnd;<br />  }<br />}</p></td></tr></tbody></table><br />TotalChargeDaoImpl.java 代码：<br /><table style="WIDTH: 657px; HEIGHT: 878px" height="878" cellspacing="0" cellpadding="0" width="657" border="1"><tbody><tr><td>package test.dao.impl;<br /><br />import java.util.*;<br />import test.bean.*;<br />import test.dao.*;<br />import net.sf.hibernate.*;<br /><br />/**<br /> *作者：孙星<br /> **/<br />public class TotalChargeDaoImple extends TotalChargeDao{<br />    <br />    //下面方法集成自TotalChargeDao<br />    public List statTotalCharge(Date statTimeBegin, Date statTimeEnd) throws DaoException{<br />        List res = new Vector();//将用于存放保存的结果集合<br />        Session session = null;<br />        ScrollableResults srs ＝ null;<br />        try{<br />            session = HibernateSessionFactory.openSession();//得到一个Hibernate Session<br />            //下面创建一个匿名Query实例并调用它的scroll()方法返回以ScrollableResults形式组织的查询结果<br />            srs = session.createQuery(“select b.name, count(a.fee) mix(a.chargeBeginTime) max(a.chargeEndTime) from charge a, customer b where a.idCustomer = b.idCustomer and a.chargeBeginTime &gt;= ? and a.chargeEndTime &lt; ? gourp by a.idCustomer“).setDate(0, statTimeBegin).setDate(1, statTimeEnd).scroll();<br />            //将查询结果放入List保存<br />            while(srs.next()){<br />                res.add(new TotalCharge(srs.getString(0), srs,getDouble(1), srs.getDate(2), srs.getDate(3)));<br />            }<br />        }catch(HibernateException he){<br />            ;//loging err.....<br />            if(srs!=null){<br />                try{<br />                    srs.close();<br />                }catch(Exception e){<br />                    ;<br />                }<br />            }<br />        }finally{<br />            try{<br />                session.close();<br />            }catch(Exception e){<br />                ;<br />            }<br />        }<br />        return res;<br />    }<br />}</td></tr></tbody></table><br />    看，现在问题解决了。坐下来，喝杯Java吧！ <br /><br /><img src ="http://www.blogjava.net/songfei/aggbug/107686.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2007-03-31 21:20 <a href="http://www.blogjava.net/songfei/articles/107686.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于hibernate中保存Blob数据的问题</title><link>http://www.blogjava.net/songfei/articles/107685.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Sat, 31 Mar 2007 13:18:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/107685.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/107685.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/107685.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/107685.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/107685.html</trackback:ping><description><![CDATA[
		<h1>关于hibernate中保存Blob数据的问题</h1>
		<p class="Articleinfo">我在bean和.hbm.xml中用的是java.sql.Blob<br />以下是我的程序,在//1的地方正常通过，在//2地方抱类型转换错误，java.lang.ClassCastException，<br />请各位指点，应该怎么改？<br />import java.io.FileInputStream;<br />import java.io.OutputStream;<br />import java.text.SimpleDateFormat;<br />import java.util.ArrayList;<br />import java.util.Date;<br />import java.util.List;<br />import oracle.sql.BLOB;<br />import org.hibernate.*;<br />import org.hibernate.cfg.Configuration;<br />public void insert()<br />{<br />Transaction tran = null;<br />try<br />{<br />tran = session.beginTransaction();<br />StyleSheetPicture pic = new StyleSheetPicture();<br />pic.setCmtorderno("JCHI-2000");<br />pic.setTitle("ht1");<br />pic.setType(new Integer(1));<br />pic.setFilename("f1");<br />pic.setKeyword("k1");<br />pic.setRawstream(BLOB.empty_lob());<br />pic.setDescription("d1");<br />pic.setSourceflag(new Integer(1));<br />pic.setUpdatedate(strtoSqlDate("2006-06-06"));<br />pic.setActiveflag(new Integer(1));<br />session.save(pic);//1<br />session.flush();<br /><br />session.refresh(pic,LockMode.UPGRADE);<br /><br />oracle.sql.BLOB blob = ((oracle.sql.BLOB)pic.getRawstream());//2<br />OutputStream os = blob.getBinaryOutputStream();<br />FileInputStream fis = new FileInputStream("C:\\hb1.jpg");<br />byte[] buf = new byte[10240];<br />int len = 0;<br />while((len = fis.read(buf)) &gt; 0)<br />{<br />os.write(buf,0,len);<br />}<br />fis.close();<br />os.close();<br />session.save(pic);<br /><br />tran.commit();<br />}<br />catch (HibernateException e)<br />{<br />e.printStackTrace();<br />if(tran != null)<br />{<br />try<br />{<br />tran.rollback();<br />}<br />catch(HibernateException e1)<br />{<br />e1.printStackTrace();<br />}<br />}<br />}<br />catch (Exception e)<br />{<br />e.printStackTrace();<br />if(tran != null)<br />{<br />try<br />{<br />tran.rollback();<br />}<br />catch(Exception e1)<br />{<br />e1.printStackTrace();<br />}<br />}<br />}<br />finally<br />{<br />tran = null;<br />}<br />}<br /></p>
		<p class="replycontent">你可以跟踪一下程序，看看到//2的位置时，取出的pic.getRawstream()是什么类型<br /></p>
		<p class="replycontent">pic.getRawstream()的类型是org.hibernate.lob.SerializableBlob<br /></p>
		<p class="replycontent">(oracle.sql.BLOB) 那你用这个转型肯定会ClassCastException<br /><br />你查一下SerializableBlob的API，看看这个有没有其他的转换方法<br /></p>
		<p class="replycontent">oracle.sql.BLOB blob = (org.hibernate.lob.SerializableBlob)pic.getRawstream();//2<br />OutputStream os = blob.setBinaryStream(long pos);<br /><br />SerializableBlob的setBinaryStream(long pos) 方法就是返回你所需要的OutputStream<br /><br />但是这个long参数不知道该传什么，API上没有明确指明<br /><br /><br />http://www.hibernate.org/hib_docs/v3/api/org/hibernate/lob/SerializableBlob.html#setBinaryStream(long)<br /></p>
<img src ="http://www.blogjava.net/songfei/aggbug/107685.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2007-03-31 21:18 <a href="http://www.blogjava.net/songfei/articles/107685.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MyEclipse+struts+Hibernate配置和开发手册</title><link>http://www.blogjava.net/songfei/articles/100703.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Mon, 26 Feb 2007 03:13:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/100703.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/100703.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/100703.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/100703.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/100703.html</trackback:ping><description><![CDATA[
		<table cellspacing="0" cellpadding="0" align="center" border="0">
				<tbody>
						<tr>
								<td align="middle">
										<div align="left">
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/5.JPG" target="_blank">
														</a>说明：<br />    这个手册只是为初学者制作的环境配置和快速开发的一些基本方法，为的是广大爱好者能快速上手，少走我走过的弯路，里面没有任何关于java模式和其他相关的说明。本人水平有限，也没有能力去讨论关于模式设计和开发细节的一些内容。 
</p>
												<p>建议：<br />    如果你还不清楚struts和hibernate的一些基本原理，希望能先去了解一下这方面的相关内容。 
</p>
												<p>推荐：<br />    《Hibernate中文手册》作者认为要学Hibernate看这个就足够了，里面几乎包括了所有的细节，不过可能不太适合快速入门。<br />地址：<a href="http://www.hibernate.org/hib_docs/v3/reference/zh-cn/html_single/">http://www.hibernate.org/hib_docs/v3/reference/zh- cn/html_single/</a><br />    关于struts的资料就很多了，这里推荐一个可以下载一些入门教程的网站。<br />地址：<a href="http://www.wnetw.com/jclub/index.jsp">http://www.wnetw.com/jclub/index.jsp</a><br />&amp;nbs p;   强烈建议入门的朋友先了解一下基本的原理！否则本文章可能对你没有任何帮助。 
</p>
												<p>相关工具下载：（注意版本）<br />    mysql5.0 <a href="http://www.mysql.org/">http://www.mysql.org</a><br />    eclipse 3.1.1 <a href="http://www.eclipse.org/" target="_blank">http://www.eclipse.org</a><br />    myeclipse4.0.3 <a href="http://www.myeclipseide.com/">http://www.myeclipseide.com</a><br />   &amp;nb sp;tomcat5.5 
</p>
												<p>安装：<br />    关于tomcat和mysql的安装就不多说了，需要注意的是最好保证你的 jdk是1.5的版本，并配置好你的环境变量，不然可能会遇到一些问题。<br /> 把eclipse解开，再去安装刚下载的myeclipse，在安装的时候需要把路径指定到刚才解开的eclipse上，由于myeclipse是个收费软件，所以需要注册。不过一般按照Chinese的习惯，去google一个注册码就可以了:} 
</p>
												<p>开发环境部署：<br /> 好了，现在保证你的mysql和tomcat服务能够正常启动，myeclipse能够正常打开（如果不能，可以去找一下相关的说明或者给作者留言）。下面我们就要开始真正的开始部署一个传说中的tomcat+struts+hibernate+mysql结构的工程了！（faint!前言就写的我好累）<br /> 首先，在myeclipse里新建一个工程。在左边的Package Exporler面版里点右键选择new-&gt;project… <br /> 在跳出菜单里选择MyEclipse-&gt;J2EE Projects-&gt;Web Project。<br /> 点击next后进入如下画面： 
</p>
												<p>
														<img src="http://blog.sina.com.cn/pic/3fa10d830200006m" />
												</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/1.JPG" target="_blank">
														</a>
												</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/1.JPG" target="_blank">
														</a>
												</p>
												<p> 工程名为：test<br /> 结束后点击Finish。<br /> 好了，如果成功的话你就会在 Package Exporler里看到一个新的test工程！现在我们先配置一下数据库方面的东西。首先在你的mysql 里建立一个数据库webases，再在里面新建一个表admin，里面三个字段分别为id,name,password其中id为自动取值的主键（mysql具体的操作可以自己找资料，不是本文涉及范围）。<br /> 再回到myeclipse ，选中window-&gt;Open Perspective-&gt;Other…<br /> 可以看到现在跳出一个名为Select Perspective的菜单，在里面选中MyEclipse Databases Exporler，可以看到现在到了下面的页面。 
</p>
												<p>
														<img src="http://blog.sina.com.cn/pic/3fa10d830200006n" />
												</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/2.JPG" target="_blank">
														</a>
												</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/2.JPG" target="_blank">
														</a>
												</p>
												<p>按以上图示输入相关字段后点击Finish便建立了一个数据库连接，在新出现的JDBC for Mysql上点右键，选择Open connection…，确认用户名和密码正确后点OK，如果一切顺利的话你会看到下面的画面： 
</p>
												<p>
														<img src="http://blog.sina.com.cn/pic/3fa10d830200006o" />
												</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/3.JPG" target="_blank">
														</a>
												</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/3.JPG" target="_blank">
														</a>
												</p>
												<p> 这说明你已经和数据库建立了正确的连接。现在我们再回到window-&gt;Open Perspective- &gt;Other…里的MyEclipse，也就是我们刚进来的时候看到的画面。<br /> 右键点击你刚建立的工程 test并选择MyEclipse-&gt;Add struts Capabilities…在跳出的菜单里按照如下输入并确定： 
</p>
												<p>
														<img src="http://blog.sina.com.cn/pic/3fa10d830200006p" />
												</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/4.JPG" target="_blank">
														</a>
												</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/4.JPG" target="_blank">
														</a>
												</p>
												<p> 好了，现在你已经为你的工程增加了struts，接下来和上面一样在右键工程后选择MyEclipse- &gt;Add Hibernate Capabilities…一路确定下来为你的工程添加Hibernate。（为方便起见我们在选择路径时把HibernateSessionFactory.java放在了src/com下面，其实最好建立个单独的目录如 src/com/hibernate）<br /> 为了更好的演示我们不建立通常的登陆页面而是建立个注册页面。选择 src目录下的hibernate.cfg.xml文件。照如下填写并保存。这样hibernate就为你建立了数据库的连接池。 
</p>
												<p>
														<img src="http://blog.sina.com.cn/pic/3fa10d830200006q" />
												</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/5.JPG" target="_blank">
														</a>
												</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/5.JPG" target="_blank">
														</a>
												</p>
												<p> 下面我们再选择WebRoot/WEB-INF/struts-config.xml文件，在画面中点击右键选择new- &gt;Form, Action and JSP。如下填写 
</p>
												<p>
														<img src="http://blog.sina.com.cn/pic/3fa10d830200006r" />
												</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/6.JPG" target="_blank">
														</a>
												</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/6.JPG" target="_blank">
														</a>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/5.JPG" target="_blank">
														</a>
												</p>
												<p> 再选择JSP选项，如下 
</p>
												<p>
														<img src="http://blog.sina.com.cn/pic/3fa10d830200006s" />
												</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/7.JPG" target="_blank">
														</a>
												</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/7.JPG" target="_blank">
														</a>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/6.JPG" target="_blank">
														</a>
												</p>
												<p> 最后选择Finish。<br /> 再新建一个一个success.jsp的页面，<br /> 在刚才struts- config.xml文件里右键选择addAdmin选择Properties，在菜单里选择Forwords，再点add，如下图填写 
</p>
												<p>
														<img src="http://blog.sina.com.cn/pic/3fa10d830200006t" />
												</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/8.JPG" target="_blank">
														</a>
												</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/8.JPG" target="_blank">
														</a>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/7.JPG" target="_blank">
														</a>
												</p>
												<p> 最后你的struts-config.xml就是下面这个样子： 
</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/9.JPG" target="_blank">
														</a>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/8.JPG" target="_blank">
														</a>
												</p>
												<p>
														<img src="http://blog.sina.com.cn/pic/3fa10d830200006u" />
														<br /> 下面我们转到hibernate。换到刚才我们建立数据库的页面，选择你的admin的表点右键选择Create Hibernate Mapping。选择好打包路径后选择Finish。如图： 
</p>
												<p>
														<img src="http://blog.sina.com.cn/pic/3fa10d830200006v" />
												</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/10.JPG" target="_blank">
														</a>
												</p>
												<p> 在你刚才选择的路径下（我为方便是src/com/yourcompanyname/）下新建立的文件 AdminDAOFactory.java文件并输入以下内容： 
</p>
												<p>package com.yourcompanyname; 
</p>
												<p>import java.util.Iterator; 
</p>
												<p>import org.hibernate.HibernateException;<br />import org.hibernate.Query;<br />import org.hibernate.Session;<br />import org.hibernate.Transaction; 
</p>
												<p>import com.hibernate.SessionFactory; 
</p>
												<p>public class AdminDAOFactory {<br /> Session session;<br /> Transaction tx;<br /> public void add(Admin admin) throws HibernateException {<br />  /**<br />   * Creation Date: 11-17-2005<br />   * TODO Add a new admin user.<br />   * @param An object of Admin<br />   * @return void<br />   * @author Coder Guo<br />   */<br />  try {<br />   session = SessionFactory.currentSession();<br />   tx = session.beginTransaction();<br />   //Add a new admin<br />   session.save(admin);<br />   tx.commit ();<br />  }catch(HibernateException e){<br />   throw e;<br />  }finally{<br />   if (tx!=null) {<br />    tx.rollback();<br />   } <br />   SessionFactory.closeSession();<br />  }<br /> }<br />} 
</p>
												<p> 再打开com.yourcompany.struts.action下的AddAdminAction.java添加（其中如果有错误选中好按ctrl+shift+o自动添加包） 
</p>
												<p>public class AddAdminAction extends Action { 
</p>
												<p> // --------------------------------------------------------- Instance Variables 
</p>
												<p> // --------------------------------------------------------- Methods 
</p>
												<p> /** <br />  * Method execute<br />  * @param mapping<br />  * @param form<br />  * @param request<br />  * @param response<br />  * @return ActionForward<br />  * @author Coder Guo<br />  */<br /> public ActionForward execute(<br />  ActionMapping mapping,<br />  ActionForm form,<br />  HttpServletRequest request,<br />  HttpServletResponse response) {<br />  AddAdminForm addAdminForm = (AddAdminForm) form;<br />  <br />  // TODO Add a new admin<br />  Admin admin = new Admin();<br />  admin.setName(addAdminForm.getName ());<br />  admin.setPassword(addAdminForm.getPassword ());<br />  AdminDAOFactory adminDAO = new AdminDAOFactory ();<br />  adminDAO.add(admin);<br />  <br />  return mapping.findForward("success");<br /> } 
</p>
												<p>} 
</p>
												<p> 再打开com.yourcompanyname.struts.form下的AddAdminForm.java，修改（如果有错误按照上面说的方法导入包）<br /> public ActionErrors validate(<br />  ActionMapping mapping,<br />  HttpServletRequest request) { 
</p>
												<p>  // TODO Auto-generated method stub<br />  ActionErrors errors = new ActionErrors();<br />  <br />  Session session = SessionFactory.currentSession();<br />  Transaction tx = session.beginTransaction ();<br />  Query query = session.createQuery("select admin from Admin as admin where admin.name = '" + this.name + "'");<br />  Iterator it = query.iterate ();<br />  if (it.hasNext()){<br />   errors.add ("addAdmin.err.name",new ActionMessage("form.addAdmin.err.name"));<br />  } <br />  tx.commit();<br />  SessionFactory.closeSession ();<br />  return errors;<br /> } 
</p>
												<p> public void reset(ActionMapping mapping, HttpServletRequest request) { 
</p>
												<p>  // TODO Auto-generated method stub<br />  this.name=null;<br />  this.password=null;<br /> } 
</p>
												<p>再打开com\yourcompanyname\struts下的ApplicationResource.properties在这里面添加错误信息： <br />Form.addAdmin.err.name=err 
</p>
												<p>最后，（汗，好累啊-_-!）打开addAdmin.jsp修改成如下：<br />&lt;%@ page contentType="text/html; charset=utf-8"%&gt; <br />&lt;%@ page language="java"%&gt;<br />&lt;%@ taglib uri="<a href="http://jakarta.apache.org/struts/tags-bean">http://jakarta.apache.org/struts/tags-bean</a>" prefix="bean"%&gt; <br />&lt;%@ taglib uri="<a href="http://jakarta.apache.org/struts/tags-html">http://jakarta.apache.org/struts/tags-html</a>" prefix="html"%&gt; 
</p>
												<p>&lt;script language = "javascript"&gt;<br />&lt;!--<br />function check(){<br /> if (loginForm.userName.value == "" || loginForm.password.value == ""){<br />  alert("请输入完整的信息！");<br />  loginForm.userName.focus();<br />  return false;<br /> }<br />}<br />//--&gt;<br />&lt;/script&gt;<br /> <br /> &lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt;<br />&lt;html:html&gt;<br />  &lt;head&gt;<br />    &lt;html:base /&gt;<br />    <br />    &lt;title&gt;login.jsp&lt;/title&gt;<br />    &lt;link href="css/webcss.css" rel="stylesheet" type="text/css"&gt;<br />    <br />    &lt;meta http-equiv="pragma" content="no- cache"&gt;<br />    &lt;meta http-equiv="cache-control" content="no- cache"&gt;<br />    &lt;meta http-equiv="expires" content="0"&gt;    <br />    &lt;meta http-equiv="keywords" content="keyword1,keyword2,keyword3"&gt;<br />    &lt;meta http- equiv="description" content="This is my page"&gt;<br />  &lt;/head&gt;<br />  
</p>
												<p>  &lt;body&gt;<br />  &lt;center&gt;<br />   &lt;p&gt;&amp;nbsp;&lt;/p&gt;<br />   &lt;p&gt;&amp;nbsp;&lt;/p&gt;<br />   &lt;table width="300" border="0" cellpadding="0" cellspacing="0"&gt;<br />   &lt;html:form action="/addAdmin" focus="name" method="GET"&gt;<br />     &lt;tr align="center" valign="middle"&gt;<br />       &lt;td colspan="2" class="typt_normal"&gt;新增管理员&lt;/td&gt;<br />     &lt;/tr&gt;<br />     &lt;tr&gt;<br />       &lt;td width="100" align="center" valign="middle" class="typt_normal"&gt;名称： &lt;/td&gt;<br />       &lt;td width="200" align="left"&gt;&lt;html:text property="name" styleClass="text_s"/&gt;&lt;html:errors property="addAdmin.err.name"/&gt;&lt;/td&gt;<br />     &lt;/tr&gt;<br />     &lt;tr&gt;<br />       &lt;td width="100" align="center" valign="middle" class="typt_normal"&gt;密码： &lt;/td&gt;<br />       &lt;td width="200" align="left"&gt;&lt;html:password property="password" styleClass="text_s"/&gt;&lt;/td&gt;<br />     &lt;/tr&gt;<br />     &lt;tr&gt; <br />       &lt;td colspan="2" align="center" valign="middle"&gt;&lt;html:submit value="提交" onclick="return check ();"/&gt;&lt;html:reset value="重置"&gt;&lt;/html:reset&gt;&lt;/td&gt;<br />       &lt;/tr&gt;<br /> &lt;/html:form&gt;<br />   &lt;/table&gt;<br /> &lt;/center&gt;<br /> &lt;/body&gt; 
</p>
												<p>&lt;/html:html&gt;<br />其中可以看到如何在struts的标签中使用javascript的方法。<br /> 配置好myeclipse于tomcat的连接。在window-&gt;Preferences做如下设定： 
</p>
												<p>
														<img src="http://blog.sina.com.cn/pic/3fa10d830200006w" />
												</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/11.JPG" target="_blank">
														</a>
												</p>
												<p> 在项目文件点右键－&gt;“myeclipse”－&gt;“Add and remove project deployment”，如下图： 
</p>
												<p>
														<img src="http://blog.sina.com.cn/pic/3fa10d830200006x" />
												</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/12.JPG" target="_blank">
														</a>
												</p>
												<p> 好了，我们的配置工作基本结束了,在myeclipse上开启tomcat服务 
</p>
												<p>
														<img height="260" src="http://blog.sina.com.cn/pic/3fa10d830200006y" width="448" p="100" h="260" w="448" />
												</p>
												<p>
														<a href="file:///E:/我的文章/MyEclipse+TomCat+struts+Hibernate+Mysql环境配置手册和快速开发实例/pic/13.JPG" target="_blank">
														</a>
												</p>
												<p>现在打开浏览器，输入<br /><a href="http://127.0.0.1:8080/test/addAdmin.jsp">http://127.0.0.1:8080/test/addAdmin.jsp</a><b>就可以看到你的jsp页面了！</b></p>
										</div>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<br />
		<br />
		<br />
<img src ="http://www.blogjava.net/songfei/aggbug/100703.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2007-02-26 11:13 <a href="http://www.blogjava.net/songfei/articles/100703.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate 的原理与配置快速入门</title><link>http://www.blogjava.net/songfei/articles/42169.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Thu, 20 Apr 2006 07:15:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/42169.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/42169.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/42169.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/42169.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/42169.html</trackback:ping><description><![CDATA[
		<div class="left fontsize2">Hibernate 的原理与配置快速入门</div>
		<div class="fontclear">
		</div>
		<div class="fontclear">
		</div>
		<div class="left fontsize3">在本文中，我向大家重点介绍Hibernate的核心API调用库，并讲解一下它的基本配置</div>
		<div class="fontclear">
		</div>
		<hr class="hr1" />
		<center>
				<span id="ad9">
				</span>
		</center>
		<div class="left fontsize4">
				<div class="guanggao">
						<span id="ad3">
						</span>
				</div>
				<div class="guanggao">
						<span id="contentAdv">
						</span>
				</div>
				<img onerror="this.src='http://www.yesky.com/image20010518/189695.gif';" hspace="3" src="http://www.yesky.com/image20010518/189695.gif" align="left" vspace="1" border="0" />　　也许你听说过<a class="bluekey" href="http://www.yesky.com/key/845/5845.html" target="_blank">Hibernate</a>的大名，但可能一直不了解它，也许你一直渴望使用它进行开发，那么本文正是你所需要的！在本文中，我向大家重点介绍Hibernate的核心API调用库，并讲解一下它的基本配置。<br /><br />　　看完本文后，我相信你对什么是ORM（对像/关系映射）以及它的优点会有一个深刻的认识，我们先通过一个简单的例子开始来展现它的威力。<br /><br />　　正如一些传统的经典计算机文章大都会通过一个“<a class="bluekey" href="http://www.yesky.com/key/2822/592822.html" target="_blank">hello</a>,world”的例子开始讲解一样，我们也不例外，我们也将从一个相对简单的例子来阐述Hibernate的开发方法，但如果要真正阐述Hibernate的一些重要思想，仅仅靠在屏幕上打印一些字符是远远不够的，在我们的示例程序中，我们将创建一些对象，并将其保存在数据库中，然后对它们进行更新和查询。<br /><br /><table bordercolor="#ffcc00" cellspacing="4" width="90%" align="center" border="1"><tbody><tr><td colspan="2"><div align="center"><font color="#ff0000"><strong>阅读导航</strong></font></div></td></tr><tr><td width="35%"><a href="http://dev.yesky.com/SoftChannel/72342371961929728/20041026/1868578_1.shtml" target="_blank"><font color="#0000ff">“Hello World”</font></a></td><td width="65%">“<a class="bluekey" href="http://www.yesky.com/key/3290/8290.html" target="_blank">Hello</a> world”示例程序让您对Hibernate有一个简单的认识<strong>。</strong></td></tr><tr><td><a href="http://dev.yesky.com/SoftChannel/72342371961929728/20041026/1868578_2.shtml" target="_blank"><font color="#0000ff">理解Hibernate的架构</font></a></td><td>介绍Hibernate接口的主要功能。</td></tr><tr><td><a href="http://dev.yesky.com/SoftChannel/72342371961929728/20041026/1868578_2.shtml" target="_blank"><font color="#0000ff">核心接口</font></a></td><td>Hibernate有5个核心接口，通过这几个接口开发人员可以存储和获得持久对象，并且能够进行事务控制</td></tr><tr><td><a href="http://dev.yesky.com/SoftChannel/72342371961929728/20041026/1868578_3.shtml" target="_blank"><font color="#0000ff">一个重要的术语：Type</font></a></td><td>Type是Hibernate发明者发明的一个术语，它在整个构架中是一个非常基础、有着强大功能的元素，一个Type对象能将一个Java类型映射到数据库中一个表的字段中去。</td></tr><tr><td><a href="http://dev.yesky.com/SoftChannel/72342371961929728/20041026/1868578_3.shtml" target="_blank"><font color="#0000ff">策略接口</font></a></td><td>Hibernate与某些其它开源软件不同的还有一点――高度的可扩展性，这通过它的内置策略机制来实现。</td></tr><tr><td><a href="http://dev.yesky.com/SoftChannel/72342371961929728/20041026/1868578_3.shtml" target="_blank"><font color="#0000ff">基础配置</font></a></td><td>Hibernate可以配置成可在任何Java环境中运行，一般说来，它通常被用在2－3层的<a class="bluekey" href="http://www.yesky.com/key/4191/544191.html" target="_blank">C/S</a>模式的项目中，并被部署在<a class="bluekey" href="http://www.yesky.com/key/1011/541011.html" target="_blank">服务端</a>。</td></tr><tr><td height="36"><a href="http://dev.yesky.com/SoftChannel/72342371961929728/20041026/1868578_4.shtml" target="_blank"><font color="#0000ff">创建一个SessionFactory对象</font></a></td><td>要创建一个SessionFactory对象，必须在Hibernate初始化时创建一个Configuration类的实例，并将已写好的映射文件交由它处理。</td></tr></tbody></table><br /><div class="left fontsize2">Hibernate 的原理与配置快速入门</div><div class="fontclear"></div><br /><div class="left"><span class="span">作者：罗小虎编译</span><span class="span">出处：天极网</span><span class="span">责任编辑：<a title="向本编辑提问" href="http://comments.yesky.com/t/%B7%BD%D6%DB/6,324/1868578.shtml"> 方舟 </a></span><span class="span">[ 2004-10-26 16:22 ]</span></div><div class="fontclear"></div><div class="left fontsize3">在本文中，我向大家重点介绍Hibernate的核心API调用库，并讲解一下它的基本配置</div><div class="fontclear"></div><hr class="hr1" /><center><span id="ad9"></span></center><div class="left fontsize4"><div class="guanggao"><span id="ad3"></span></div>　　<strong>“Hello World”</strong><br /><br />　　Hibernate应用程序定义了一些持久类，并且定义了这些类与数据库表格的映射关系。在我们这个“Hello world”示例程序中包含了一个类和一个映射文件。让我们看看这个简单的持久类包含有一些什么？映射文件是怎样定义的？另外，我们该怎样用Hibernate来操作这个持久类。<br /><br />　　我们这个简单示例程序的目的是将一些持久类存储在数据库中，然后从数据库取出来，并将其信息正文显示给用户。其中Message正是一个简单的持久类：，它包含我们要显示的信息，其源代码如下：<br /><br />　　列表1　Message.Java　一个简单的持久类<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>package hello;<br />public class Message {<br />　private Long id;<br />　private String text;<br />　private Message nextMessage;<br />　private Message() {}<br />　public Message(String text) {<br />　　this.text = text;<br />　}<br />　public Long getId() {<br />　　return id;<br />　}<br />　private void setId(Long id) {<br />　　this.id = id;<br />　}<br />　public String getText() {<br />　　return text; <br />　}<br />　public void setText(String text) {<br />　　this.text = text;<br />　}<br />　public Message getNextMessage() {<br />　　return nextMessage;<br />　}<br />　public void setNextMessage(Message nextMessage) {<br />　　this.nextMessage = nextMessage;<br />　}<br />} </td></tr></tbody></table><br />　　Message类有三个属性：Message的id 、消息正文、以及一个指向下一条消息的指针。其中id属性让我们的应用程序能够唯一的识别这条消息，通常它等同于数据库中的主键，如果多个Message类的实例对象拥有相同的id，那它们代表数据库某个表的同一个记录。在这里我们选择了长整型作为我们的id值，但这不是必需的。Hibernate允许我们使用任意的类型来作为对象的id值，在后面我们会对此作详细描述。<br /><br />　　你可能注意到Message类的代码类似于JavaBean的代码风格，并且它有一个没有参数的构造函数，在我们以后的代码中我将继续使用这种风格来编写持久类的代码。<br /><br />　　Hibernate会自动管理Message类的实例，并通过内部机制使其持久化，但实际上Message对象并没有实现任何关于Hibernate的类或接口，因此我们也可以将它作为一个普通的Java类来使用：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>Message message = new Message("Hello World");<br />System.out.println( message.getText() ); </td></tr></tbody></table><br />　　以上这段代码正是我们所期望的结果：它打印“hello world”到屏幕上。但这并不是我们的最终目标；实际上Hibernate与诸如EJB容器这样的环境在持久层实现的方式上有很大的不同。我们的持久类(Message类)可以用在与容器无关的环境中，不像EJB必须要有EJB容器才能执行。为了能更清楚地表现这点，以下代码将我们的一个新消息保存到数据库中去：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>Session session = getSessionFactory().openSession();<br />Transaction tx = session.beginTransaction();<br />Message message = new Message("Hello World");<br />session.save(message);<br />tx.commit();<br />session.close(); </td></tr></tbody></table><br />　　以上这段代码调用了Hibernate的Session和Transaction接口（关于getSessionFactory()方法我们将会马上提到）。它相当于我们执行了以下SQL语句：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID)<br />values (1, 'Hello World', null) </td></tr></tbody></table><br />　　在以上的SQL语句中，MESSAGE_ID字段到底被初始化成了什么值呢？由于我们并没有在先前的代码中为message对象的id属性赋与初始值，那它是否为null呢？实际上Hibernate对id属性作了特殊处理：由于它是一个对象的唯一标识，因此当我们进行save()调用时，Hibernate会为它自动赋予一个唯一的值（我们将在后面内容中讲述它是如何生成这个值的）。<br /><br />　　我们假设你已经在数据库中创建了一个名为MESSAGE的表，那么既然前面这段代码让我们将Message对象存入了数据库中，那么现在我们就要将它们一一取出来。下面这段代码将按照字母顺序，将数据库中的所有Message对象取出来，并将它们的消息正文打印到屏幕上：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>Session newSession = getSessionFactory().openSession();<br />Transaction newTransaction = newSession.beginTransaction();<br />List messages =newSession.find("from Message as m order by m.text asc");<br />System.out.println( messages.size() + " message(s) found:" );<br />for ( Iterator iter = messages.iterator(); iter.hasNext(); ) {<br />　Message message = (Message) iter.next();<br />　System.out.println( message.getText() );<br />}<br />newTransaction.commit();<br />newSession.close(); </td></tr></tbody></table><br />　　在以上这段代码中，你可能被find()方法的这个参数困扰着："from Message as m order by m.text asc"，其实它是Hibernate自己定义的查询语言，全称叫Hibernate Query Language(HQL)。通俗地讲HQL与SQL的关系差不多就是方言与普通话之间的关系，咋一看，你会觉得它有点类似于SQL语句。其实在find()调用时，Hibernate会将这段HQL语言翻译成如下的SQL语句：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>select m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_ID<br />from MESSAGES m<br />order by m.MESSAGE_TEXT asc </td></tr></tbody></table><br />　　以下就是运行结果： <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>1 message(s) found:<br />Hello World </td></tr></tbody></table><br />　　如果你以前没有ORM（对象－关系映射）的开发经验，那你可能想在代码的某个地方去寻找这段SQL语句，但在Hibernate中你可能会失望：它根本不存在！所有就SQL语句都是Hibernate动态生成的。 <br /><br />　　也许你会觉得还缺点什么，对！仅凭以上代码Hibernate是无法将我们的Message类持久化的。我们还需要一些更多的信息，这就是映射定义表！这个表在Hibernate中是以XML格式来体现的，它定义了Message类的属性是怎样与数据库中的MESSAGES表的字段进行一一对应的，列表2是这个示例程序的映射配置文件清单：<br /><br />　　列表2：示例程序的对象－关系映射表 <br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>＜?xml version="1.0"?＞<br />＜!DOCTYPE hibernate-mapping PUBLIC<br />"-//Hibernate/Hibernate Mapping DTD//EN"<br />"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"＞<br />＜hibernate-mapping＞<br />＜class name="hello.Message" table="MESSAGES"＞<br />　＜id name="id" column="MESSAGE_ID"＞<br />　　＜generator class="increment"/＞<br />　＜/id＞<br />　＜property name="text" column="MESSAGE_TEXT"/＞<br />　＜many-to-one name="nextMessage" cascade="all" column="NEXT_MESSAGE_ID"/＞<br />＜/class＞<br />＜/hibernate-mapping＞ </td></tr></tbody></table><br />　　以上这个文档告诉Hibernate怎样将Message类映射到MESSAGES表中，其中Message类的id属性与表的MESSAGE_ID字段对应，text属性与表的MESSAGE_TEXT字段对应，nextMessage属性是一个多对一的关系，它与表中的NEXT_MESSAGE_ID相对应。 <br /><br />　　相对于有些开源项目来说，Hibernate的配置文件其实是很容易理解的。你可以轻松地修改与维护它。只要你定义好了持久类与数据库中表字段的对应关系就行了，Hibernate会自动帮你生成SQL语句来对Message对象进行插入、更新、删除、查找工作，你可以不写一句SQL语句，甚至不需要懂得SQL语言！<br /><br />　　现在让我们做一个新的试验，我们先取出第一个Message对象，然后修改它的消息正文，最后我们再生成一个新的Message对象，并将它作为第一个Message对象的下一条消息，其代码如下：<br /><br />　　列表3　更新一条消息<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>Session session = getSessionFactory().openSession();<br />Transaction tx = session.beginTransaction();<br />// 1 is the generated id of the first message<br />Message message =(Message) session.load( Message.class, new Long(1) );<br />message.setText("Greetings Earthling");<br />Message nextMessage = new Message("Take me to your leader (please)");<br />message.setNextMessage( nextMessage );<br />tx.commit();<br />session.close(); </td></tr></tbody></table><br />　　以上这段代码在调用时，Hibernate内部自动生成如下的SQL语句：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>select m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_ID<br />from MESSAGES m<br />where m.MESSAGE_ID = 1<br /><br />insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID)<br />values (2, 'Take me to your leader (please)', null)<br /><br />update MESSAGES<br />set MESSAGE_TEXT = 'Greetings Earthling', NEXT_MESSAGE_ID = 2<br />where MESSAGE_ID = 1 </td></tr></tbody></table><br />　　当第一个Message对象的text属性和nextMessage被程序修改时，请注意Hibernate是如何检测到这种变化，并如何在数据库中自动对它更新的。这实际上是Hibernate的一个很有价值的特色，我们把它称为“自动脏数据检测”，Hibernate的这个特色使得当我们修改一个持久对象的属性后，不必显式地通知Hibernate去将它在数据库中进行更新。同样的，当第一个Message对象调用setNextMessage()方法将第二个Message对象作为它的下一条消息的引用时，第二条消息会无需调用save()方法，便可以自动地保存在数据库中。这种特色被称为“级联保存”，它也免去了我们显式地对第二个Message对象调用save()方法之苦。<br /><br />　　如果我们再运行先前的那段将数据库中所有的Message对象都打印出来的代码，那它的运行结果如下：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>2 message(s) found:<br />Greetings Earthling<br />Take me to your leader (please) </td></tr></tbody></table><br />　　“Hello world”示例程序现在介绍完毕。我们总算对Hibernate有了一个简单的认识，下面我们将回过头来，对Hibernate的主要API调用作一下简要的介绍：<br /><br />　<strong>理解Hibernate的架构</strong><br /><br />　　当你想用Hibernate开发自己的基于持久层的应用时，第一件事情应当是熟悉它的编程接口。Hibernate的API接口设计得尽量简洁明了，以方便开发人员。然而实际上由于ORM的复杂性，它的API一般都不可能设计得很简单。但是别担心，你没有必要一下子了解所有的Hibernate的API接口。下面这张图描述了Hibernate在应用层和持久层中的一些重要的接口类：<br /><br /><table width="90%" align="center" border="0"><tbody><tr><td><div align="center"><img onerror="this.src='http://www.yesky.com/image20010518/189639.jpg';" hspace="3" src="http://www.yesky.com/image20010518/189639.jpg" align="center" vspace="1" border="1" /></div></td></tr></tbody></table><br />　　在上图中，我们将应用层放在了持久层的上部，实际上在传统的项目中，应用层充当着持久层的一个客户端角色。但对于一些简单的项目来说，应用层和持久层并没有区分得那么清楚，这也没什么，在这种情况下你可以将应用层和持久层合并成了一层。<br /><br />　　在上图中，Hibernate的接口大致可以分为以下几种类型：<br /><br />　　· 一些被用户的应用程序调用的，用来完成基本的创建、读取、更新、删除操作以及查询操作的接口。这些接口是Hibernate实现用户程序的商业逻辑的主要接口，它们包括Session、Transaction和Query。<br /><br />　　· Hibernate用来读取诸如映射表这类配置文件的接口，典型的代表有Configuration类。<br /><br />　　· 回调(Callback)接口。它允许应用程序能对一些事件的发生作出相应的操作，例如Interceptor、Lifecycle和Validatable都是这一类接口。<br /><br />　　· 一些可以用来扩展Hibernate的映射机制的接口，例如UserType、CompositeUserType和IdentifierGenerator。这些接口可由用户程序来实现（如果有必要）。<br /><br />　　Hibernate使用了J2EE架构中的如下技术：JDBC、JTA、JNDI。其中JDBC是一个支持关系数据库操作的一个基础层；它与JNDI和JTA一起结合，使得Hibernate可以方便地集成到J2EE应用服务器中去。<br /><br />　　在这里，我们不会详细地去讨论Hibernate API接口中的所有方法，我们只简要讲一下每个主要接口的功能，如果你想了解得更多的话，你可以在Hibernate的源码包中的net.sf.hibernate子包中去查看这些接口的源代码。下面我们依次讲一下所有的主要接口：<br /><br />　　<strong>核心接口</strong><br /><br />　　以下5个核心接口几乎在任何实际开发中都会用到。通过这些接口，你不仅可以存储和获得持久对象，并且能够进行事务控制。<br /><br />　　Session接口<br /><br />　　Session接口对于Hibernate 开发人员来说是一个最重要的接口。然而在Hibernate中，实例化的Session是一个轻量级的类，创建和销毁它都不会占用很多资源。这在实际项目中确实很重要，因为在客户程序中，可能会不断地创建以及销毁Session对象，如果Session的开销太大，会给系统带来不良影响。但值得注意的是Session对象是非线程安全的，因此在你的设计中，最好是一个线程只创建一个Session对象。<br /><br />　　在Hibernate的设计者的头脑中，他们将session看作介于数据连接与事务管理一种中间接口。我们可以将session想象成一个持久对象的缓冲区，Hibernate能检测到这些持久对象的改变，并及时刷新数据库。我们有时也称Session是一个持久层管理器，因为它包含这一些持久层相关的操作，诸如存储持久对象至数据库，以及从数据库从获得它们。请注意，Hibernate 的session不同于JSP应用中的HttpSession。当我们使用session这个术语时，我们指的是Hibernate中的session，而我们以后会将HttpSesion对象称为用户session。<br /><br />　　SessionFactory 接口<br /><br />　　这里用到了一个设计模式――工厂模式，用户程序从工厂类SessionFactory中取得Session的实例。<br /><br />　　令你感到奇怪的是SessionFactory并不是轻量级的！实际上它的设计者的意图是让它能在整个应用中共享。典型地来说，一个项目通常只需要一个SessionFactory就够了，但是当你的项目要操作多个数据库时，那你必须为每个数据库指定一个SessionFactory。<br />SessionFactory在Hibernate中实际起到了一个缓冲区的作用，它缓冲了Hibernate自动生成的SQL语句和一些其它的映射数据，还缓冲了一些将来有可能重复利用的数据。<br /><br />　　Configuration 接口<br /><br />　　Configuration接口的作用是对Hibernate进行配置，以及对它进行启动。在Hibernate的启动过程中，Configuration类的实例首先定位映射文档的位置，读取这些配置，然后创建一个SessionFactory对象。<br /><br />　　虽然Configuration接口在整个Hibernate项目中只扮演着一个很小的角色，但它是启动hibernate时你所遇到的每一个对象。<br /><br />　　Transaction 接口<br /><br />　　Transaction接口是一个可选的API，你可以选择不使用这个接口，取而代之的是Hibernate的设计者自己写的底层事务处理代码。 Transaction接口是对实际事务实现的一个抽象，这些实现包括JDBC的事务、JTA中的UserTransaction、甚至可以是CORBA事务。之所以这样设计是能让开发者能够使用一个统一事务的操作界面，使得自己的项目可以在不同的环境和容器之间方便地移值。<br /><br />　　Query和Criteria接口<br /><br />　　Query接口让你方便地对数据库及持久对象进行查询，它可以有两种表达方式：HQL语言或本地数据库的SQL语句。Query经常被用来绑定查询参数、限制查询记录数量，并最终执行查询操作。<br /><br />　　Criteria接口与Query接口非常类似，它允许你创建并执行面向对象的标准化查询。<br /><br />　　值得注意的是Query接口也是轻量级的，它不能在Session之外使用。<br /><br />　　Callback 接口 <br /><br />　　当一些有用的事件发生时――例如持久对象的载入、存储、删除时，Callback接口会通知Hibernate去接收一个通知消息。一般而言，Callback接口在用户程序中并不是必须的，但你要在你的项目中创建审计日志时，你可能会用到它。<br /><strong>一个重要的术语：Type<br /><br /></strong>　　Hibernate的设计者们发明了一个术语：Type，它在整个构架中是一个非常基础、有着强大功能的元素。一个Type对象能将一个Java类型映射到数据库中一个表的字段中去（实际上，它可以映射到表的多个字段中去）。持久类的所有属性都对应一个type。这种设计思想使用Hibernate有着高度的灵活性和扩展性。<br /><br />　　Hibernate内置很多type类型，几乎包括所有的Java基本类型，例如Java.util.Currency、Java.util.calendar、byte[]和Java.io.Serializable。<br /><br />　　不仅如此，Hibernate还支持用户自定义的type，通过实现接口UserType和接口CompositeUserType，你可以加入自己的type。你可以利用这种特色让你的项目中使用自定义的诸如Address、Name这样的type，这样你就可以获得更大的便利，让你的代码更优雅。自定义type在Hibernate中是一项核心特色，它的设计者鼓励你多多使用它来创建一个灵活、优雅的项目！<br /><br />　　<strong>策略接口</strong><br /><br />　　Hibernate与某些其它开源软件不同的还有一点――高度的可扩展性，这通过它的内置策略机制来实现。当你感觉到Hibernate的某些功能不足，或者有某些缺陷时，你可以开发一个自己的策略来替换它，而你所要做的仅仅只是继承它的某个策略接口，然后实现你的新策略就可以了，以下是它的策略接口：<br /><br />　　· 主键的生成 (IdentifierGenerator 接口) <br /><br />　　· 本地SQL语言支持 (Dialect 抽象类) <br /><br />　　· 缓冲机制 (Cache 和CacheProvider 接口) <br /><br />　　· JDBC 连接管理 (ConnectionProvider接口) <br /><br />　　· 事务管理 (TransactionFactory, Transaction, 和 TransactionManagerLookup 接口) <br /><br />　　· ORM 策略 (ClassPersister 接口) <br /><br />　　· 属性访问策略 (PropertyAccessor 接口) <br /><br />　　· 代理对象的创建 (ProxyFactory接口)<br /><br />　　Hibernate为以上所列的机制分别创建了一个缺省的实现，因此如果你只是要增强它的某个策略的功能的话，只需简单地继承这个类就可以了，没有必要从头开始写代码。<br /><br />　　以上就是Hibernate的一些核心接口，但当我们真正开始用它进行开发时，你的脑海里可能总会有一个疑问：我是通过什么方式，并从哪里取得Session的呢？以下我们就解答这个问题。<br /><br />　　<strong>基础配置</strong><br /><br />　　现在回顾一下我们先前的内容：我们写出了一个示例程序，并简要地讲解了Hibernate的一些核心类。但要真正使你的项目运行起来，还有一件事必须要做：配置。Hibernate可以配置成可在任何Java环境中运行，一般说来，它通常被用在2－3层的C/S模式的项目中，并被部署在服务端。在这种项目中，Web浏览器、或Java GUI程序充当者客户端。尽管我们的焦点主要是集中在多层web应用，但实际上在一些基于命令行的应用中也可以使用Hibernate。并且，对Hibernate的配置在不同的环境下都会不同，Hibernate运行在两种环境下：可管理环境和不可管理环境<br /><br />　　· 可管理环境――这种环境可管理如下资源：池资源管理，诸如数据库连接池和，还有事务管理、安全定义。一些典型的J2EE服务器（JBoss、Weblogic、WebSphere）已经实现了这些。<br /><br />　　· 不可管理环境――只是提供了一些基本的功能，诸如像Jetty或Tomcat这样的servlet容器环境。一个普通的Java桌面应用或命令行程序也可以认为是处于这种环境下。这种环境不能提供自动事务处理、资源管理或安全管理，这些都必须由应用程序自己来定义。<br /><br />　　Hibernate的设计者们将这两种环境设计了一个统一的抽象界面，因此对于开发者来说只有一种环境：可管理环境。如果实际项目是建立在诸如Tomcat这类不可管理的环境中时，那Hibernate将会使用它自己的事务处理代码和JDBC连接池，使其变为一个可管理环境。<br />对于可管理的环境而言，Hibernate会将自己集成在这种环境中。对于开发者而言，你所要做的工作非常简单：只需从一个Configuration类中创建一个SessionFactory类就可以了。<br /><br /><strong>创建一个SessionFactory对象<br /><br /></strong>　　为了能创建一个SessionFactory对象，你必须在Hibernate初始化时创建一个Configuration类的实例，并将已写好的映射文件交由它处理。这样，Configuration对象就可以创建一个SessionFactory对象，当SessionFactory对象创建成功后，Configuration对象就没有用了，你可以简单地抛弃它。如下是示例代码：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>Configuration cfg = new Configuration();<br />cfg.addResource("hello/Message.hbm.xml");<br />cfg.setProperties( System.getProperties() );<br />SessionFactory sessions = cfg.buildSessionFactory(); </td></tr></tbody></table><br />　　在以上代码中，Message.hb.xml这个映射文件的位置比较特殊，它与当前的classpath相关。例如classpath包含当前目录，那在上述代码中的Message.hbm.xml映射文件就可以保存在当前目录下的hello目录中。<br /><br />　　作为一种约定，Hibernate的映射文件默认以.htm.xml作为其扩展名。另一个约定是坚持为每一个持久类写一个配置文件，想一想如果你将所有持久类的映射写入一个单独的配置文件中的话，那这个配置文件肯定非常庞大，不易维护。但这里又出现了一个新问题：如果为每个类写一个配置文件的话，这么多的配置文件应该存放在哪里呢？<br /><br />　　Hibernate推荐你将每个映射文件保存在与持久类相同的目录下，并且与持久类同名。例如我们第一个示例程序中的Message持久类放在hello目录下，那你必须在这个目录下存放名为Message.hbm.xml的映射文件。这样一个持久类都有自己的一个映射文件，避免了出现像struts项目中的“struts-config.xml地狱”的情况。如果你不遵循这种规定，那你必须手动地用addResource()方法将一个个的映射文件载入；但你如果遵循这种规定，那你可以方便地用addClass()方法同时将持久类和它的映射文件载入，以下是体现这种便利性的示例代码：<br /><br /><table bordercolor="#ffcc66" width="90%" align="center" bgcolor="#e6e4dd" border="1"><tbody><tr><td>SessionFactory sessions = new Configuration()<br />.addClass(org.hibernate.auction.model.Item.class)<br />.addClass(org.hibernate.auction.model.Category.class)<br />.addClass(org.hibernate.auction.model.Bid.class)<br />.setProperties( System.getProperties() )<br />.buildSessionFactory(); </td></tr></tbody></table><br />　　当然，Hibernate的映射文件还有很多其它的配置选项，比如数据库连接的设定，或是能够改变Hibernate运行时行为的一些设定。所有的设置可能是非常庞杂的，足以让你喘不过气来，但是不必担心，因为Hibernate为绝大多数值都设定了一个合理缺省值，你只需要修改这些配置文件中的极小一部分值。<br /><br />　　你可以通过以下几种方式来修改Hibernate的系统配置参数：<br /><br />　　· 将一个Java.util.Properties实例作为参数传给Configuration类的setProperties()方法。<br /><br />　　· 在Hibernate启动时用Java –Dproperty=value的方式设置值。<br /><br />　　· 在classpath可以找到的路径下创建一个名为hibernate.properties的配置文件。 <br /><br />　　· 在classpath可以找到的路径下创建一个名为hibernate.cfg.xml的文件，并在其＜property＞标签中定义属性值。<br /><br />　　以上就是对Hibernate的一个大致介绍，如果你想知道得更多，那本文还是远远不够的，我将陆续推出更多关于Hibernate的资料。但有一点是毫无疑问的：它的确是一个非常优秀的持久层解决方案！<br /><br /></div></div>
<img src ="http://www.blogjava.net/songfei/aggbug/42169.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2006-04-20 15:15 <a href="http://www.blogjava.net/songfei/articles/42169.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>