﻿<?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/relax/category/546.html</link><description>记述我学习java的里程</description><language>zh-cn</language><lastBuildDate>Wed, 21 Oct 2009 12:56:42 GMT</lastBuildDate><pubDate>Wed, 21 Oct 2009 12:56:42 GMT</pubDate><ttl>60</ttl><item><title>hibernate注解方式实现复合主键</title><link>http://www.blogjava.net/relax/archive/2009/09/18/295587.html</link><dc:creator>轻松</dc:creator><author>轻松</author><pubDate>Fri, 18 Sep 2009 08:29:00 GMT</pubDate><guid>http://www.blogjava.net/relax/archive/2009/09/18/295587.html</guid><wfw:comment>http://www.blogjava.net/relax/comments/295587.html</wfw:comment><comments>http://www.blogjava.net/relax/archive/2009/09/18/295587.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/relax/comments/commentRss/295587.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/relax/services/trackbacks/295587.html</trackback:ping><description><![CDATA[<p>有时一个实体的主键可能同时为多个，例如同样是之前使用的&#8220;CustomerEO&#8221;实体，需要通过name和email来查找指定实体，当且仅当name和email的值完全相同时，才认为是相同的实体对象。要配置这样的复合主键，步骤如以下所示。</p>
<p>（1）编写一个复合主键的类CustomerPK，代码如下。</p>
<p>CustomerPK.java</p>
<p>import java.io.Serializable;</p>
<p>&nbsp;</p>
<p>public class CustomerPK implements Serializable {</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public CustomerPK() {</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public CustomerPK(String name, String email) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.name = name;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.email = email;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private String email;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getEmail() {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return email;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setEmail(String email) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.email = email;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private String name;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getName() {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return name;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setName(String name) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.name = name;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @Override</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int hashCode() {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final int PRIME = 31;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int result = 1;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result = PRIME * result + ((email == null) ? 0 : email.hashCode());</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result = PRIME * result + ((name == null) ? 0 : name.hashCode());</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return result;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @Override</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public boolean equals(Object obj) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (this == obj)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (obj == null)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (getClass() != obj.getClass())</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final CustomerPK other = (CustomerPK) obj;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (email == null) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (other.email != null)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (!email.equals(other.email))</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (name == null) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (other.name != null)</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (!name.equals(other.name))</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;</p>
<p>}</p>
<p>作为符合主键类，要满足以下几点要求。</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 必须实现Serializable接口。</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 必须有默认的public无参数的构造方法。</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 必须覆盖equals和hashCode方法。equals方法用于判断两个对象是否相同，EntityManger通过find方法来查找Entity时，是根据equals的返回值来判断的。本例中，只有对象的name和email值完全相同时或同一个对象时则返回true，否则返回false。hashCode方法返回当前对象的哈希码，生成的hashCode相同的概率越小越好，算法可以进行优化。</p>
<p>（2）通过@IdClass注释在实体中标注复合主键，实体代码如下。</p>
<p>@Entity</p>
<p>@Table(name = "customer")</p>
<p>@IdClass(CustomerPK.class)</p>
<p>public class CustomerEO implements java.io.Serializable {</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Integer id;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Integer getId() {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.id;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setId(Integer id) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.id = id;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private String name;</p>
<p>&nbsp;</p>
<p>@Id</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getName() {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.name;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setName(String name) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.name = name;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private String email;</p>
<p>@Id</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getEmail() {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return email;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setEmail(String email) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.email = email;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>}</p>
<p>标注复合主键时需要注意以下几个问题。</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @IdClass标注用于标注实体所使用主键规则的类。它的定义如下所示。</p>
<p>@Target({TYPE}) @Retention(RUNTIME)</p>
<p>public @interface IdClass {</p>
<p>Class value();</p>
<p>}</p>
<p>属性Class表示符合主键所使用的类，本例中使用CustomerPK这个复合主键类。</p>
<p>l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在实体中同时标注主键的属性。本例中在email和name的getter方法前标注@Id，表示符合主键使用这两个属性。</p>
<p>（3）这样定义实体的复合主键后，通过以下代码便可以获得指定的实体对象：</p>
<p>&nbsp;&nbsp;&nbsp; CustomerPK cpk = new CustomerPK("Janet","janetvsfei@yahoo.com.cn");</p>
<p>&nbsp;&nbsp;&nbsp; CustomerEO instance = entityManager.find(CustomerEO.class, cpk);</p>
<p>&nbsp;</p>
<p>本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/EJB_JPA/archive/2008/05/09/2422540.aspx</p>
<img src ="http://www.blogjava.net/relax/aggbug/295587.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/relax/" target="_blank">轻松</a> 2009-09-18 16:29 <a href="http://www.blogjava.net/relax/archive/2009/09/18/295587.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>eclipse中从数据库生成hibernate实体类</title><link>http://www.blogjava.net/relax/archive/2009/07/27/288537.html</link><dc:creator>轻松</dc:creator><author>轻松</author><pubDate>Mon, 27 Jul 2009 06:16:00 GMT</pubDate><guid>http://www.blogjava.net/relax/archive/2009/07/27/288537.html</guid><wfw:comment>http://www.blogjava.net/relax/comments/288537.html</wfw:comment><comments>http://www.blogjava.net/relax/archive/2009/07/27/288537.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/relax/comments/commentRss/288537.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/relax/services/trackbacks/288537.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 为什么写这篇BLOG，是因为经常有同事或网友问起我hiberante实体类的生成问题。所以下次再有人问我可以省一堆的话了，其实这个真的是很简单。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 现在hibernate在项目中的应用是越来过广泛了。我是从hibernate开始支持注释语法后才开始研究它的。说实在的，原来的hibernate生成的一堆堆的XML文件看着就头晕，还不如自己写的SQL语句来的舒服，所以一直听朋友和同事介绍，可自己一直不屑用之。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 可是现在有福了hibernate是JPA最常用的实现之一，而且hiberante自身也对注释语法进行了支持。现在再不用去看那一堆堆的XML映射了。而且eclipse还提供了从数据库直接生成Entity Class的工具。既然可以少写或不写SQL语句那合乐而为为呢。废话少说，开始做起来。</p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 还是从我们开始项目的第一步说起，新建项目。一般我们用java做web项目都是File-&gt;New-&gt;Dynamic Web Project，如下图：<br />
<img border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/relax/newProject.JPG" width="640" height="480" /><br />
然后会出现新建项目的对话框如图所示<br />
<img border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/relax/newProject2.JPG" width="480" height="471" /><br />
然后点击Modify按钮后如图<br />
<img style="width: 477px; height: 373px" border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/relax/modifyConfig.JPG" width="477" height="373" /><br />
将java persistence选中，这样就为项目增加了JPA的特性，其它特性根据项目需要自行修改。点击OK后。点击几次NEXT（忽略的几步根据自身情况而定）到JPA FACET窗口，如下图：<br />
<img border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/relax/jpafacet.JPG" width="658" height="647" /><br />
<br />
因为咱们用的是hibernate列表中没有所以platform选择Generic,Type选择disable library configuration,因为咱们把需要的jar文件直接放到WEB-INF下的lib目录中就可以了。所以不用配置。再下面的connection这个是必须要配置的要不我们怎么从数据库中生成啊。对不。<br />
如果以前配置过连接直接选择就可以了，如果没有配置过点击 add connection.如下图：<br />
<img border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/relax/newconnection.JPG" width="525" height="596" /><br />
选择要使用的数据库类型，然后下一步，如下图。其实这个类型也没啥作用只是个生成连接字符串的模版而以。<br />
<img border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/relax/configDriver.JPG" width="525" height="632" /><br />
选择已有的驱动，如果没有怎么办，废话，当然是继续新增了。这块不详述了，点击driver后面第一个按钮，根据提示选择对应的jar文件即可。<br />
做完上述操作点击Finish.回到JPA Facet窗口。选中Discover annotated classes automatically,把Create orm.xml钓掉。然后点Finish项目就建完了。<br />
然后在项目文件夹上右键选择JPA tools-&gt;Generate Entities from Tables.后如下图：<br />
<img border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/relax/generateEntityDalg.JPG" width="631" height="703" /><br />
选择建好的connection如果没有connect 就connect一下。就会如上图所示了（有时eclipse会有些小问题看不见表，可以重启一下试试，实在不行就直接建个JPA project ，生成实体后再拷到自己的项目中就可以了。）选中要生成实体的表，Next如下图：<br />
<img border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/relax/tableassociations.JPG" width="631" height="703" /><br />
上面是表之间的关系，如果可以做相应的修改（用的是ecipse 3.5貌似eclipse3.4还没这个功能，eclipse越来越强了），再Next后如下图：<br />
<img border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/relax/tableMapping.JPG" width="631" height="703" /><br />
（这个好像也是eclipse 3.5才加的）都能看明白吧。按照需要改改就可以了，这里不多啰嗦。再Next<br />
后，如下图：<br />
<img border="0" alt="" src="http://www.blogjava.net/images/blogjava_net/relax/individual.JPG" width="631" height="703" /><br />
这是一些表的每个属性的调整，一般也不用调了。Finish就好了。<br />
嘿嘿终于完成了。贴了这么多图，累死我了。不过为了大家能弄明白，还是图比文字更能说明情况，我辛苦点就辛苦点吧。。<br />
看看源码中生成的java文件是不是你想要的，具体这些类怎么用。就不是这篇文章要说的问题了。如果大家有需要，我下回接着写。
  <img src ="http://www.blogjava.net/relax/aggbug/288537.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/relax/" target="_blank">轻松</a> 2009-07-27 14:16 <a href="http://www.blogjava.net/relax/archive/2009/07/27/288537.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate中Criteria的完整用法（转载）</title><link>http://www.blogjava.net/relax/archive/2008/09/25/231138.html</link><dc:creator>轻松</dc:creator><author>轻松</author><pubDate>Thu, 25 Sep 2008 08:35:00 GMT</pubDate><guid>http://www.blogjava.net/relax/archive/2008/09/25/231138.html</guid><wfw:comment>http://www.blogjava.net/relax/comments/231138.html</wfw:comment><comments>http://www.blogjava.net/relax/archive/2008/09/25/231138.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/relax/comments/commentRss/231138.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/relax/services/trackbacks/231138.html</trackback:ping><description><![CDATA[说明：该文内容为转载，因对自己有用，故保留下来，但是因为当时没记录博客地址，所以无法说明来源了！之后的两篇关于面向接口编程的文章也是如此 ！<br />
<br />
Hibernate中Criteria的完整用法2008年07月09日 星期三 00:16最近在项目中使用 Spring 和 Hibernate 进行开发，有感于 Criteria 比较好用，在查询方法<br />
<br />
设计上可以灵活的根据 Criteria 的特点来方便地进行查询条件的组装。现在对 Hibernate的Criteria 的用法进行总结：<br />
&nbsp; Hibernate 设计了 CriteriaSpecification 作为 Criteria 的父接口，下面提供了 Criteria和DetachedCriteria 。 <br />
&nbsp; Criteria 和 DetachedCriteria 的主要区别在于创建的形式不一样， Criteria 是在线的，所<br />
以它是由 Hibernate Session 进行创建的；而 DetachedCriteria 是离线的，创建时无需 <br />
Session，DetachedCriteria 提供了 2 个静态方法 forClass(Class) 或 forEntityName(Name) <br />
进行DetachedCriteria 实例的创建。 Spring 的框架提供了getHibernateTemplate<br />
().findByCriteria(detachedCriteria) 方法可以很方便地根据DetachedCriteria 来返回查询结<br />
果。 <br />
&nbsp; Criteria 和 DetachedCriteria 均可使用 Criterion 和 Projection 设置查询条件。可以设<br />
置 FetchMode( 联合查询抓取的模式 ) ，设置排序方式。对于 Criteria 还可以设置 FlushModel <br />
（冲刷 Session 的方式）和 LockMode （数据库锁模式）。 <br />
下面对 Criterion 和 Projection 进行详细说明。<br />
&nbsp; Criterion 是 Criteria 的查询条件。Criteria 提供了 add(Criterion criterion) 方法来<br />
添加查询条件。<br />
&nbsp; Criterion 接口的主要实现包括： Example 、 Junction 和 SimpleExpression 。而 <br />
Junction 的实际使用是它的两个子类 conjunction 和 disjunction ，分别是使用 AND 和 OR 操<br />
作符进行来联结查询条件集合。<br />
&nbsp; Criterion 的实例可以通过 Restrictions 工具类来创建，Restrictions 提供了大量的静态<br />
方法，如 eq （等于）、 ge （大于等于）、 between 等来方法的创建 Criterion 查询条件 <br />
（SimpleExpression 实例）。除此之外， Restrictions 还提供了方法来创建 conjunction 和 <br />
disjunction 实例，通过往该实例的 add(Criteria) 方法来增加查询条件形成一个查询条件集合<br />
。<br />
&nbsp; 至于 Example 的创建有所不同， Example 本身提供了一个静态方法 create(Object <br />
entity) ，即根据一个对象（实际使用中一般是映射到数据库的对象）来创建。然后可以设置一些<br />
过滤条件： <br />
Example exampleUser =Example.create(u) <br />
.ignoreCase() // 忽略大小写 <br />
.enableLike(MatchMode.ANYWHERE); <br />
// 对 String 类型的属性，无论在那里值在那里都匹配。相当于 %value% <br />
Project 主要是让 Criteria 能够进行报表查询，并可以实现分组。 Project 主要有 <br />
SimpleProjection 、 ProjectionList 和 Property 三个实现。其中 SimpleProjection 和 <br />
ProjectionList 的实例化是由内建的 Projections 来完成，如提供的 avg 、 count 、 max 、 <br />
min 、 sum 可以让开发者很容易对某个字段进行统计查询。 <br />
&nbsp; &nbsp; Property 是对某个字段进行查询条件的设置，如通过Porperty.forName(&#8220;color&#8221;).in<br />
(new String[]{&#8220;black&#8221;,&#8221;red&#8221;,&#8221;write&#8221;}); 则可以创建一个 Project 实例。通过 <br />
criteria 的 add(Project) 方法加入到查询条件中去。 <br />
&nbsp; 使用 Criteria 进行查询，主要要清晰的是 Hibernate 提供了那些类和方法来满足开发中查<br />
询条件的创建和组装，下面介绍几种用法：<br />
1. 创建一个Criteria 实例<br />
org.hibernate.Criteria接口表示特定持久类的一个查询。Session是 Criteria实例的工厂。<br />
Criteria crit = sess.createCriteria(Cat.class);<br />
crit.setMaxResults(50);<br />
List cats = crit.list();<br />
<br />
2. 限制结果集内容<br />
一个单独的查询条件是org.hibernate.criterion.Criterion 接口的一个实例。<br />
<br />
org.hibernate.criterion.Restrictions类 定义了获得某些内置Criterion类型的工厂方法。<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp; .add( Restrictions.like("name", "Fritz%") )<br />
&nbsp; .add( Restrictions.between("weight", minWeight, maxWeight) )<br />
&nbsp; .list();<br />
<br />
约束可以按逻辑分组。 <br />
<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp; .add( Restrictions.like("name", "Fritz%") )<br />
&nbsp; .add( Restrictions.or(<br />
&nbsp; &nbsp; Restrictions.eq( "age", new Integer(0) ),<br />
&nbsp; &nbsp; Restrictions.isNull("age")<br />
&nbsp; ) )<br />
&nbsp; .list();<br />
<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp; .add( Restrictions.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) )<br />
&nbsp; .add( Restrictions.disjunction()<br />
&nbsp; &nbsp; .add( Restrictions.isNull("age") )<br />
&nbsp; &nbsp; .add( Restrictions.eq("age", new Integer(0) ) )<br />
&nbsp; &nbsp; .add( Restrictions.eq("age", new Integer(1) ) )<br />
&nbsp; &nbsp; .add( Restrictions.eq("age", new Integer(2) ) )<br />
&nbsp; ) )<br />
&nbsp; .list();<br />
<br />
Hibernate提供了相当多的内置criterion类型(Restrictions 子类), 但是尤其有用的是可以允许<br />
<br />
你直接使用SQL。<br />
<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp; .add( Restrictions.sql("lower({alias}.name) like lower(?)", "Fritz%", <br />
<br />
Hibernate.STRING) )<br />
&nbsp; .list();<br />
<br />
{alias}占位符应当被替换为被查询实体的列别名。 <br />
Property实例是获得一个条件的另外一种途径。你可以通过调用Property.forName() 创建一个<br />
<br />
Property。 <br />
<br />
Property age = Property.forName("age");<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp; .add( Restrictions.disjunction()<br />
&nbsp; &nbsp; .add( age.isNull() )<br />
&nbsp; &nbsp; .add( age.eq( new Integer(0) ) )<br />
&nbsp; &nbsp; .add( age.eq( new Integer(1) ) )<br />
&nbsp; &nbsp; .add( age.eq( new Integer(2) ) )<br />
&nbsp; ) )<br />
&nbsp; .add( Property.forName("name").in( new String[] { "Fritz", "Izi", "Pk" } ) )<br />
&nbsp; .list();<br />
<br />
3. 结果集排序<br />
你可以使用org.hibernate.criterion.Order来为查询结果排序。 <br />
<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp; .add( Restrictions.like("name", "F%")<br />
&nbsp; .addOrder( Order.asc("name") )<br />
&nbsp; .addOrder( Order.desc("age") )<br />
&nbsp; .setMaxResults(50)<br />
&nbsp; .list();<br />
<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp; .add( Property.forName("name").like("F%") )<br />
&nbsp; .addOrder( Property.forName("name").asc() )<br />
&nbsp; .addOrder( Property.forName("age").desc() )<br />
&nbsp; .setMaxResults(50)<br />
&nbsp; .list();<br />
<br />
4. 关联<br />
你可以使用createCriteria()非常容易的在互相关联的实体间建立 约束。<br />
<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp; .add( Restrictions.like("name", "F%")<br />
&nbsp; .createCriteria("kittens")<br />
&nbsp; &nbsp; .add( Restrictions.like("name", "F%")<br />
&nbsp; .list();<br />
<br />
<br />
注意第二个 createCriteria()返回一个新的 Criteria实例，该实例引用kittens 集合中的元素。 <br />
接下来，替换形态在某些情况下也是很有用的。<br />
<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp; .createAlias("kittens", "kt")<br />
&nbsp; .createAlias("mate", "mt")<br />
&nbsp; .add( Restrictions.eqProperty("kt.name", "mt.name") )<br />
&nbsp; .list();<br />
<br />
<br />
(createAlias()并不创建一个新的 Criteria实例。) <br />
Cat实例所保存的之前两次查询所返回的kittens集合是 没有被条件预过滤的。如果你希望只获得<br />
<br />
符合条件的kittens， 你必须使用returnMaps()。 <br />
<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp; .createCriteria("kittens", "kt")<br />
&nbsp; .add( Restrictions.eq("name", "F%") )<br />
&nbsp; .returnMaps()<br />
&nbsp; .list();<br />
Iterator iter = cats.iterator();<br />
while ( iter.hasNext() ) {<br />
&nbsp; Map map = (Map) iter.next();<br />
&nbsp; Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);<br />
&nbsp; Cat kitten = (Cat) map.get("kt");<br />
}<br />
<br />
5. 动态关联抓取<br />
你可以使用setFetchMode()在运行时定义动态关联抓取的语义。 <br />
<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp; .add( Restrictions.like("name", "Fritz%") )<br />
&nbsp; .setFetchMode("mate", FetchMode.EAGER)<br />
&nbsp; .setFetchMode("kittens", FetchMode.EAGER)<br />
&nbsp; .list();<br />
<br />
这个查询可以通过外连接抓取mate和kittens。<br />
<br />
6. 查询示例<br />
org.hibernate.criterion.Example类允许你通过一个给定实例 构建一个条件查询。<br />
<br />
Cat cat = new Cat();<br />
cat.setSex('F');<br />
cat.setColor(Color.BLACK);<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp; .add( Example.create(cat) )<br />
&nbsp; .list();<br />
<br />
<br />
版本属性、标识符和关联被忽略。默认情况下值为null的属性将被排除。 <br />
可以自行调整Example使之更实用。 <br />
<br />
Example example = Example.create(cat)<br />
&nbsp; .excludeZeroes() &nbsp; &nbsp; &nbsp; //exclude zero valued properties<br />
&nbsp; .excludeProperty("color") //exclude the property named "color"<br />
&nbsp; .ignoreCase() &nbsp; &nbsp; &nbsp; &nbsp; //perform case insensitive string comparisons<br />
&nbsp; .enableLike(); &nbsp; &nbsp; &nbsp; &nbsp; //use like for string comparisons<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp; .add(example)<br />
&nbsp; .list();<br />
<br />
<br />
甚至可以使用examples在关联对象上放置条件。<br />
<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp; .add( Example.create(cat) )<br />
&nbsp; .createCriteria("mate")<br />
&nbsp; &nbsp; .add( Example.create( cat.getMate() ) )<br />
&nbsp; .list();<br />
<br />
<br />
7. 投影(Projections)、聚合（aggregation）和分组（grouping）<br />
org.hibernate.criterion.Projections是 Projection 的实例工厂。我们通过调用 <br />
<br />
setProjection()应用投影到一个查询。 <br />
<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp; .setProjection( Projections.rowCount() )<br />
&nbsp; .add( Restrictions.eq("color", Color.BLACK) )<br />
&nbsp; .list();<br />
<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp; .setProjection( Projections.projectionList()<br />
&nbsp; &nbsp; .add( Projections.rowCount() )<br />
&nbsp; &nbsp; .add( Projections.avg("weight") )<br />
&nbsp; &nbsp; .add( Projections.max("weight") )<br />
&nbsp; &nbsp; .add( Projections.groupProperty("color") )<br />
&nbsp; )<br />
&nbsp; .list();<br />
<br />
<br />
在一个条件查询中没有必要显式的使用 "group by" 。某些投影类型就是被定义为 分组投影，他<br />
<br />
们也出现在SQL的group by子句中。 <br />
<br />
可以选择把一个别名指派给一个投影，这样可以使投影值被约束或排序所引用。下面是两种不同的<br />
<br />
实现方式：<br />
<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp; .setProjection( Projections.alias( Projections.groupProperty("color"), "colr" ) )<br />
&nbsp; .addOrder( Order.asc("colr") )<br />
&nbsp; .list();<br />
<br />
<br />
<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp; .setProjection( Projections.groupProperty("color").as("colr") )<br />
&nbsp; .addOrder( Order.asc("colr") )<br />
&nbsp; .list();<br />
<br />
alias()和as()方法简便的将一个投影实例包装到另外一个 别名的Projection实例中。简而言之，<br />
<br />
当你添加一个投影到一个投影列表中时 你可以为它指定一个别名： <br />
<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp; .setProjection( Projections.projectionList()<br />
&nbsp; &nbsp; .add( Projections.rowCount(), "catCountByColor" )<br />
&nbsp; &nbsp; .add( Projections.avg("weight"), "avgWeight" )<br />
&nbsp; &nbsp; .add( Projections.max("weight"), "maxWeight" )<br />
&nbsp; &nbsp; .add( Projections.groupProperty("color"), "color" )<br />
&nbsp; )<br />
&nbsp; .addOrder( Order.desc("catCountByColor") )<br />
&nbsp; .addOrder( Order.desc("avgWeight") )<br />
&nbsp; .list();<br />
<br />
<br />
List results = session.createCriteria(Domestic.class, "cat")<br />
&nbsp; .createAlias("kittens", "kit")<br />
&nbsp; .setProjection( Projections.projectionList()<br />
&nbsp; &nbsp; .add( Projections.property("cat.name"), "catName" )<br />
&nbsp; &nbsp; .add( Projections.property("kit.name"), "kitName" )<br />
&nbsp; )<br />
&nbsp; .addOrder( Order.asc("catName") )<br />
&nbsp; .addOrder( Order.asc("kitName") )<br />
&nbsp; .list();<br />
<br />
<br />
也可以使用Property.forName()来表示投影：<br />
<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp; .setProjection( Property.forName("name") )<br />
&nbsp; .add( Property.forName("color").eq(Color.BLACK) )<br />
&nbsp; .list();<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp; .setProjection( Projections.projectionList()<br />
&nbsp; &nbsp; .add( Projections.rowCount().as("catCountByColor") )<br />
&nbsp; &nbsp; .add( Property.forName("weight").avg().as("avgWeight") )<br />
&nbsp; &nbsp; .add( Property.forName("weight").max().as("maxWeight") )<br />
&nbsp; &nbsp; .add( Property.forName("color").group().as("color" )<br />
&nbsp; )<br />
&nbsp; .addOrder( Order.desc("catCountByColor") )<br />
&nbsp; .addOrder( Order.desc("avgWeight") )<br />
&nbsp; .list();<br />
<br />
<br />
8. 离线(detached)查询和子查询<br />
DetachedCriteria类使你在一个session范围之外创建一个查询，并且可以使用任意的 Session来<br />
<br />
执行它。<br />
<br />
DetachedCriteria query = DetachedCriteria.forClass(Cat.class)<br />
&nbsp; .add( Property.forName("sex").eq('F') );<br />
//创建一个Session<br />
Session session = .;<br />
Transaction txn = session.beginTransaction();<br />
List results = query.getExecutableCriteria(session).setMaxResults(100).list();<br />
txn.commit();<br />
session.close();<br />
<br />
<br />
DetachedCriteria也可以用以表示子查询。条件实例包含子查询可以通过 Subqueries或者<br />
Property获得。<br />
<br />
DetachedCriteria avgWeight = DetachedCriteria.forClass(Cat.class)<br />
&nbsp; .setProjection( Property.forName("weight").avg() );<br />
session.createCriteria(Cat.class)<br />
&nbsp; .add( Property.forName("weight).gt(avgWeight) )<br />
&nbsp; .list();<br />
DetachedCriteria weights = DetachedCriteria.forClass(Cat.class)<br />
&nbsp; .setProjection( Property.forName("weight") );<br />
session.createCriteria(Cat.class)<br />
&nbsp; .add( Subqueries.geAll("weight", weights) )<br />
&nbsp; .list();<br />
<br />
相互关联的子查询也是有可能的：<br />
<br />
DetachedCriteria avgWeightForSex = DetachedCriteria.forClass(Cat.class, "cat2")<br />
&nbsp; .setProjection( Property.forName("weight").avg() )<br />
&nbsp; .add( Property.forName("cat2.sex").eqProperty("cat.sex") );<br />
session.createCriteria(Cat.class, "cat")<br />
&nbsp; .add( Property.forName("weight).gt(avgWeightForSex) )<br />
&nbsp; .list();<br />
<img src ="http://www.blogjava.net/relax/aggbug/231138.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/relax/" target="_blank">轻松</a> 2008-09-25 16:35 <a href="http://www.blogjava.net/relax/archive/2008/09/25/231138.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate 复合查询</title><link>http://www.blogjava.net/relax/archive/2008/03/27/188943.html</link><dc:creator>轻松</dc:creator><author>轻松</author><pubDate>Thu, 27 Mar 2008 02:23:00 GMT</pubDate><guid>http://www.blogjava.net/relax/archive/2008/03/27/188943.html</guid><wfw:comment>http://www.blogjava.net/relax/comments/188943.html</wfw:comment><comments>http://www.blogjava.net/relax/archive/2008/03/27/188943.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/relax/comments/commentRss/188943.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/relax/services/trackbacks/188943.html</trackback:ping><description><![CDATA[<p class="g_w_100 g_t_wrap g_t_center g_t_bold g_t_24 g_c_pdin c07" id="blogtitle__fks_0IiPdXDLvvC8WS_B022qKwLpgeWuihpM">&nbsp;</p>
<div class="g_blog_list">
<div class="g_t_center g_c_pdin g_p_center c07 content" id="blogtext__fks_0IiPdXDLvvC8WS_B022qKwLpgeWuihpM" style="width: 760px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<div><strong><span>复合查询主要是处理，具有关联关系的两个实体怎样进行关联查询，比如</span></strong><strong><span>User</span></strong><strong><span>实体对象与</span></strong><strong><span>Addres</span></strong><strong><span>实体对象具有一对多的关联关系，我们可以如下构造符合查询：</span></strong></div>
<div><strong><span>Criteria criteria=session.createCriteria(User.class);</span></strong></div>
<div><strong><span>&nbsp;&nbsp; </span></strong><strong><span>Criteria addcriteria=criteria.createCriteria(&#8220;addresses&#8221;);(1)</span></strong></div>
<div><strong><span>&nbsp;&nbsp; addcriteria.add(Express.like(&#8220;address&#8221;,&#8221;%tianjin%&#8221;));</span></strong></div>
<div><strong><span>&nbsp;&nbsp;</span></strong><strong><span>List list=criteria.list();</span></strong></div>
<div><strong><span>&nbsp;&nbsp; for(int i=0;i
<list></span></strong></div>
<div><strong><span>&nbsp;&nbsp;&nbsp;&nbsp; User user=(User)list.get(i);</span></strong></div>
<div><strong><span>&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(user.getName()+&#8221;\n&#8221;);</span></strong></div>
<div><strong><span>&nbsp;&nbsp;&nbsp;&nbsp; Set addresses=user.getAddresses();</span></strong></div>
<div><strong><span>&nbsp;&nbsp;&nbsp;&nbsp; Iterator it=addresses.iterator();</span></strong></div>
<div><strong><span>&nbsp;&nbsp;&nbsp;&nbsp; while(it.hasNext(){</span></strong></div>
<div><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Address address=(Address)it.next();</span></strong></div>
<div><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(address.getAddress()+&#8221;\n&#8221;);</span></strong></div>
<div><strong><span>&nbsp;&nbsp;&nbsp;&nbsp; }</span></strong></div>
<div><strong><span>&nbsp;&nbsp; }</span></strong></div>
<div><strong><span>当执行到了（</span></strong><strong><span>1</span></strong><strong><span>）处时，表明要针对</span></strong><strong><span>User</span></strong><strong><span>对象的</span></strong><strong><span>addresses</span></strong><strong><span>属性添加新的查询条件，因此当执行</span></strong><strong><span>criteria.list()</span></strong><strong><span>时，</span></strong><strong><span>Hibernate</span></strong><strong><span>会生成类似如下的</span></strong><strong><span>SQL</span></strong><strong><span>语句：</span></strong></div>
<div><strong><span>Select * from user inner join address on user.id=address.id where address.address like &#8216;%shanghai%&#8217;;</span></strong></div>
<div><strong><span>正如我们所见，我们可以通过向</span></strong><strong><span>Criteria</span></strong><strong><span>中添加保存关联对象的集合属性（</span></strong><strong><span>addresses</span></strong><strong><span>属性保存与</span></strong><strong><span>User</span></strong><strong><span>对象相关联的</span></strong><strong><span>Address</span></strong><strong><span>对象），来构造复合查询，在数据库一端是通过内连接查询来实现。</span></strong></div>
<div><strong></strong>&nbsp;</div>
<div><strong><span>相关：</span></strong></div>
<div><strong><span>1. Hibernate</span></strong></div>
<div><strong><span>2.</span></strong></div>
<div><strong><span>
<div style="margin-top: 1px; margin-left: 15px">
<h2><a title="永久链接: Hibernate QBC查询 " href="http://iorit2003.javaeye.com/blog/139922">Hibernate QBC查询 </a></h2>
</div>
<div style="margin-top: 10px; margin-left: 15px; overflow: auto">
<table width="100%">
    <tbody>
        <tr>
            <td>
            <div><strong><span>QBC</span></strong><strong><span>查询：</span></strong></div>
            <div><strong><span>&nbsp;&nbsp; QBC</span></strong><strong><span>查询就是通过使用</span></strong><strong><span>Hibernate</span></strong><strong><span>提供的</span></strong><strong><span>Query By Criteria API</span></strong><strong><span>来查询对象，这种</span></strong><strong><span>API</span></strong><strong><span>封装了</span></strong><strong><span>SQL</span></strong><strong><span>语句的动态拼装，对查询提供了更加面向对象的功能接口。我们看下面的示例程序：</span></strong></div>
            <div><strong><span>Criteria criteria=session.createCriteria(User.class);</span></strong></div>
            <div><strong><span>criteria.add(Expression.eq(&#8220;name&#8221;,&#8221;zx&#8221;));</span></strong></div>
            <div><strong><span>criteria.add(Expression.eq(&#8220;age&#8221;,new Integer(27));</span></strong></div>
            <div><strong><span>List list=criteria.list();</span></strong></div>
            <div><strong><span>当执行</span></strong><strong><span>criteria.list()</span></strong><strong><span>时会生成类似这样的</span></strong><strong><span>SQL</span></strong><strong><span>语句：</span></strong><strong><span>Select * from user where name=&#8217;zx&#8217; and age=27;</span></strong><strong><span>所以在这里我们可以看出，</span></strong><strong><span>Criteria</span></strong><strong><span>实际上是一个查询容器，它对查询条件表达式的添加进行了封装，具体的查询条件是通过</span></strong><strong><span>add()</span></strong><strong><span>方法添加的，而且具体的查询条件的表达式运算是通过</span></strong><strong><span>Expression</span></strong><strong><span>指定的。</span></strong><strong><span>Hibernate</span></strong><strong><span>在运行期会根据</span></strong><strong><span>Criteria</span></strong><strong><span>指定的表达式条件来添加查询条件，并且生成查询语句。这种方式非常符合</span></strong><strong><span>Java</span></strong><strong><span>以及所有面向对象编程语言的编程方式，所以大多数的持久层框架都提供了对这种方式查询的支持。下面我们讲解这种查询方式的各个技术细节。</span></strong></div>
            <div><strong><span>1、</span></strong><strong><span>Criteria</span></strong><strong><span>查询表达式：</span></strong></div>
            <div><strong><span>正如我们所见，</span></strong><strong><span>Expression</span></strong><strong><span>对查询语句的表达式进行了封装和限制，下表列出了</span></strong><strong><span>Expression</span></strong><strong><span>所有的方法，以及每个方法所对应的查询表达式及其限制。</span></strong></div>
            <table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
                <tbody>
                    <tr>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>方法</span></strong></div>
                        </td>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>描述</span></strong></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>Expression.eq</span></strong></div>
                        </td>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>对应</span></strong><strong><span>SQL</span></strong><strong><span>的&#8220;</span></strong><strong><span>field=value</span></strong><strong><span>&#8221;表达式</span></strong></div>
                        <div><strong><span>如：</span></strong><strong><span>Expression.eq(&#8220;name&#8221;,&#8221;zx&#8221;);</span></strong></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>Expression.allEq</span></strong></div>
                        </td>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>方法的参数为一个</span></strong><strong><span>Map</span></strong><strong><span>类型对象，包含多个名</span></strong><strong><span>/</span></strong><strong><span>值对对应关系，相当于多个</span></strong><strong><span>Expression.eq</span></strong><strong><span>的叠加</span></strong></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>Expression.gt</span></strong></div>
                        </td>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>对应</span></strong><strong><span>SQL</span></strong><strong><span>的&#8220;</span></strong><strong><span>field&gt;value</span></strong><strong><span>&#8221;表达式</span></strong></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>Expression.ge</span></strong></div>
                        </td>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>对应</span></strong><strong><span>SQL</span></strong><strong><span>的&#8220;</span></strong><strong><span>field&gt;=value</span></strong><strong><span>&#8221;表达式</span></strong></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>Expression.lt</span></strong></div>
                        </td>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>对应</span></strong><strong><span>SQL</span></strong><strong><span>的&#8220;</span></strong><strong><span>field<value></span></strong><strong><span>&#8221;表达式</span></strong></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>Expression.le</span></strong></div>
                        </td>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>对应</span></strong><strong><span>SQL</span></strong><strong><span>的&#8220;</span></strong><strong><span>field&lt;=value</span></strong><strong><span>&#8221;表达式</span></strong></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>Expression.between</span></strong></div>
                        </td>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>对应</span></strong><strong><span>SQL</span></strong><strong><span>语句的</span></strong><strong><span>between</span></strong><strong><span>表达式，如：查询年龄在</span></strong><strong><span>21</span></strong><strong><span>与</span></strong><strong><span>27</span></strong><strong><span>岁之间的用户，可以写成</span></strong><strong><span>Expression.between(&#8220;age&#8221;,new Integer(21),new Integer(27));</span></strong></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>Expression.like</span></strong></div>
                        </td>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>对应</span></strong><strong><span>SQL</span></strong><strong><span>语句的</span></strong><strong><span>&#8221;field like value&#8221;</span></strong><strong><span>表达式</span></strong></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>Expression.in</span></strong></div>
                        </td>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>对应</span></strong><strong><span>SQL</span></strong><strong><span>语句的&#8220;</span></strong><strong><span>field in(&#8230;&#8230;)</span></strong><strong><span>&#8221;表达式</span></strong></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>Expression.eqProperty</span></strong></div>
                        </td>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>用于比较两个属性值，对应</span></strong><strong><span>&#8221;field=field&#8221;SQL</span></strong><strong><span>表达式</span></strong></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>Expression.gtProperty</span></strong></div>
                        </td>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>用于比较两个属性值，对应</span></strong><strong><span>&#8221;field&gt;field&#8221;SQL</span></strong><strong><span>表达式</span></strong></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>Expression.geProperty</span></strong></div>
                        </td>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>用于比较两个属性值，对应</span></strong><strong><span>&#8221;field&gt;=field&#8221;SQL</span></strong><strong><span>表达式</span></strong></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>Expression.ltProperty</span></strong></div>
                        </td>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>用于比较两个属性值，对应</span></strong><strong><span>&#8221;field<field></span></strong><strong><span>表达式</span></strong></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>Expression.leProperty</span></strong></div>
                        </td>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>用于比较两个属性值，对应</span></strong><strong><span>&#8221;field&lt;=field&#8221;SQL</span></strong><strong><span>表达式</span></strong></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>Expression.and</span></strong></div>
                        </td>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>对应</span></strong><strong><span>SQL</span></strong><strong><span>语句的</span></strong><strong><span>And</span></strong><strong><span>关系组合，如：</span></strong><strong><span>Expression.and(Expression.eq(&#8220;name&#8221;,&#8221;zx&#8221;),Expression.eq(&#8220;sex&#8221;,&#8221;1&#8221;));</span></strong></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>Expression.or</span></strong></div>
                        </td>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>对应</span></strong><strong><span>SQL</span></strong><strong><span>语句的</span></strong><strong><span>Or</span></strong><strong><span>关系组合，如：</span></strong><strong><span>Expression.or(Expression.eq(&#8220;name&#8221;,&#8221;zx&#8221;),Expression.eq(&#8220;name&#8221;,&#8221;zhaoxin&#8221;));</span></strong></div>
                        </td>
                    </tr>
                    <tr>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>Expression.sql</span></strong></div>
                        </td>
                        <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top">
                        <div><strong><span>作为补充这个方法提供了原生</span></strong><strong><span>SQL</span></strong><strong><span>语句查询的支持，在执行时直接通过原生</span></strong><strong><span>SQL</span></strong><strong><span>语句进行限定，如：</span></strong><strong><span>Expression.sql(&#8220;lower({alias}.name) like (?)&#8221;,&#8220;zhao%&#8221;,Hibernate.STRING) ;</span></strong><strong><span>在运行时</span></strong><strong><span>{ alias }</span></strong><strong><span>将会由当前查询所关联的实体类名替换，</span></strong><strong><span>()</span></strong><strong><span>中的</span></strong><strong><span>?</span></strong><strong><span>将会由</span></strong><strong><span>&#8221;zhao%&#8221;</span></strong><strong><span>替换，并且类型由</span></strong><strong><span>Hibernate.STRING</span></strong><strong><span>指定。</span></strong></div>
                        </td>
                    </tr>
                </tbody>
            </table>
            <div><strong><span>注意：</span></strong><strong><span>Expression</span></strong><strong><span>各方法中的属性参数（各方法中的第一个参数）所指定的属性名称（如：</span></strong><strong><span>name,sex</span></strong><strong><span>），并不是数据库表中的实际字段名称，而是实体对象中映射实际数据表字段的类属性名称。</span></strong></div>
            <div><strong>&nbsp;</strong></div>
            <div><strong><span>2、</span></strong><strong><span>示例查询：</span></strong></div>
            <div><strong><span>&nbsp;&nbsp; </span></strong><strong><span>示例查询是通过</span></strong><strong><span>Example</span></strong><strong><span>类来完成的，</span></strong><strong><span>Example</span></strong><strong><span>类实现了</span></strong><strong><span>Criterion</span></strong><strong><span>接口，可以用作</span></strong><strong><span>Criteria</span></strong><strong><span>查询条件，</span></strong><strong><span>Example</span></strong><strong><span>类的作用是：根据已有对象，查询属性值与之相同的其他对象。如下代码所示：</span></strong></div>
            <div><strong><span>Criteria criteria=session.createCriteria(User.class);</span></strong></div>
            <div><strong><span>User exampleuser=new User(&#8220;zx&#8221;);</span></strong></div>
            <div><strong><span>criteria.add(Example.create(exampleuser));</span></strong></div>
            <div><strong><span>List list=criteria.list();</span></strong></div>
            <div><strong><span>for(int i=0;i
            <list></span></strong></div>
            <div><strong><span>&nbsp;&nbsp; User user=(User)list.get(i);</span></strong></div>
            <div><strong><span>&nbsp;&nbsp; System.out.println(user.getName()+&#8221;\n&#8221;);</span></strong></div>
            <div><strong><span>}</span></strong></div>
            <div><strong><span>上述代码中</span></strong><strong><span>User exampleuser=new User(&#8220;zx&#8221;);criteria.add(Example.create(exampleuser));</span></strong><strong><span>两句相当于</span></strong></div>
            <div><strong><span>criteria.add(Expression.eq(&#8220;name&#8221;,&#8221;zx&#8221;));</span></strong><strong><span>因此会生成类似如下的</span></strong><strong><span>SQL</span></strong><strong><span>语句：</span></strong></div>
            <div><strong><span>select * from user where name=&#8217;zx&#8217;;</span></strong><strong><span>在上面的代码中</span></strong><strong><span>exampleuser</span></strong><strong><span>称为示例对象。</span></strong></div>
            <div><strong><span>&nbsp;&nbsp;</span></strong><strong><span>在</span></strong><strong><span>Hibernate</span></strong><strong><span>中队示例查询，默认情况下会排除掉示例对象中属性值为空的属性，还可以调用</span></strong><strong><span>Example.excludeNone</span></strong><strong><span>（排除空串值）</span></strong><strong><span>/excludeZeros</span></strong><strong><span>（排除零值），或者调用</span></strong><strong><span>Example.excludeProperty</span></strong><strong><span>方法来指定排除特定属性。</span></strong></div>
            <div><strong><span>&nbsp;&nbsp; </span></strong><strong><span>示例查询主要应用于组合查询中，比如根据用户输入的查询条件动态生成最终的查询语句，通过使用示例查询，可以避免由于查询条件过多而写的大量</span></strong><strong><span>if</span></strong><strong><span>判断语句。</span></strong></div>
            <div><strong><span>3、</span></strong><strong><span>复合查询：</span></strong></div>
            <div><strong><span>复合查询主要是处理，具有关联关系的两个实体怎样进行关联查询，比如</span></strong><strong><span>User</span></strong><strong><span>实体对象与</span></strong><strong><span>Addres</span></strong><strong><span>实体对象具有一对多的关联关系，我们可以如下构造符合查询：</span></strong></div>
            <div><strong><span>Criteria criteria=session.createCriteria(User.class);</span></strong></div>
            <div><strong><span>&nbsp;&nbsp; </span></strong><strong><span>Criteria addcriteria=criteria.createCriteria(&#8220;addresses&#8221;);(1)</span></strong></div>
            <div><strong><span>&nbsp;&nbsp; addcriteria.add(Express.like(&#8220;address&#8221;,&#8221;%tianjin%&#8221;));</span></strong></div>
            <div><strong><span>&nbsp;&nbsp;</span></strong><strong><span>List list=criteria.list();</span></strong></div>
            <div><strong><span>&nbsp;&nbsp; for(int i=0;i
            <list></span></strong></div>
            <div><strong><span>&nbsp;&nbsp;&nbsp;&nbsp; User user=(User)list.get(i);</span></strong></div>
            <div><strong><span>&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(user.getName()+&#8221;\n&#8221;);</span></strong></div>
            <div><strong><span>&nbsp;&nbsp;&nbsp;&nbsp; Set addresses=user.getAddresses();</span></strong></div>
            <div><strong><span>&nbsp;&nbsp;&nbsp;&nbsp; Iterator it=addresses.iterator();</span></strong></div>
            <div><strong><span>&nbsp;&nbsp;&nbsp;&nbsp; while(it.hasNext(){</span></strong></div>
            <div><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Address address=(Address)it.next();</span></strong></div>
            <div><strong><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(address.getAddress()+&#8221;\n&#8221;);</span></strong></div>
            <div><strong><span>&nbsp;&nbsp;&nbsp;&nbsp; }</span></strong></div>
            <div><strong><span>&nbsp;&nbsp; }</span></strong></div>
            <div><strong><span>当执行到了（</span></strong><strong><span>1</span></strong><strong><span>）处时，表明要针对</span></strong><strong><span>User</span></strong><strong><span>对象的</span></strong><strong><span>addresses</span></strong><strong><span>属性添加新的查询条件，因此当执行</span></strong><strong><span>criteria.list()</span></strong><strong><span>时，</span></strong><strong><span>Hibernate</span></strong><strong><span>会生成类似如下的</span></strong><strong><span>SQL</span></strong><strong><span>语句：</span></strong></div>
            <div><strong><span>Select * from user inner join address on user.id=address.id where address.address like &#8216;%shanghai%&#8217;;</span></strong></div>
            <div><strong><span>正如我们所见，我们可以通过向</span></strong><strong><span>Criteria</span></strong><strong><span>中添加保存关联对象的集合属性（</span></strong><strong><span>addresses</span></strong><strong><span>属性保存与</span></strong><strong><span>User</span></strong><strong><span>对象相关联的</span></strong><strong><span>Address</span></strong><strong><span>对象），来构造复合查询，在数据库一端是通过内连接查询来实现。</span></strong></div>
            <div><strong>&nbsp;</strong></div>
            <div><strong>&nbsp;</strong></div>
            <div><strong>&nbsp;</strong></div>
            <div><strong><span>4、</span></strong><strong><span>Criteria</span></strong><strong><span>的高级特性：</span></strong></div>
            <div><strong><span>A、</span></strong><strong><span>限定返回记录条数：</span></strong></div>
            <div><strong><span>&nbsp;</span></strong><strong><span>我们可以通过利用</span></strong><strong><span>Criteria.setFirstResult/setMaxResult</span></strong><strong><span>方法来限定返回某一次查询的记录数，如下代码：</span></strong></div>
            <div><strong><span>Criteria criteria=session.createCriteria(User.class);</span></strong></div>
            <div><strong><span>criteria.setFirstResult(100);</span></strong></div>
            <div><strong><span>criteria.setMaxResult(200);</span></strong></div>
            <div><strong><span>通过以上代码可以设定该次查询返回</span></strong><strong><span>user</span></strong><strong><span>表中的从第</span></strong><strong><span>100</span></strong><strong><span>条记录开始直到第</span></strong><strong><span>200</span></strong><strong><span>条记录结束的</span></strong><strong><span>100</span></strong><strong><span>条记录。</span></strong></div>
            <div><strong><span>B、</span></strong><strong><span>对查询结果进行排序：</span></strong></div>
            <div><strong><span>&nbsp;</span></strong><strong><span>可通过使用</span></strong><tt><strong><span>net.sf.hibernate.expression.Order</span></strong></tt><tt><strong><span>类可以对查询结果集进行排序，如下面代码：</span></strong></tt></div>
            <div><strong><span>Criteria criteria=session.createCriteria(User.class);</span></strong></div>
            <div><strong><span>criteria.add(Expression.eq(&#8220;groupid&#8221;,&#8221;2&#8221;);</span></strong></div>
            <div><strong><span>criteria.addOrder(Order.asc(&#8220;name&#8221;));</span></strong></div>
            <div><strong><span>criteria.addOrder(Order.desc(&#8220;groupid&#8221;));</span></strong></div>
            <div><strong><span>List list=criteria.list();</span></strong></div>
            <div><strong><span>通过使用</span></strong><strong><span>Order</span></strong><strong><span>类的</span></strong><strong><span>asc()/desc()</span></strong><strong><span>方法，可以指定针对某个字段的排序逻辑，如果执行上述代码，会生成类似如下的</span></strong><strong><span>SQL</span></strong><strong><span>语句：</span></strong></div>
            <div><strong><span>Select * from user where groupid=&#8217;2&#8217; order by name asc,groupid desc</span></strong></div>
            <div><strong><span>C、</span></strong><strong><span>分组与统计：</span></strong></div>
            <div><strong><span>&nbsp;&nbsp; </span></strong><strong><span>在</span></strong><strong><span>Hibernate3</span></strong><strong><span>中，对</span></strong><strong><span>Criteria</span></strong><strong><span>又增添了新功能，可以支持分组与统计功能，在</span></strong><strong><span>Hibernate3</span></strong><strong><span>中增加了</span></strong><strong><span>Projections</span></strong><strong><span>以及</span></strong><strong><span>ProjectionList</span></strong><strong><span>类，这两个类对分组与统计功能进行了封装，如下代码：</span></strong></div>
            <div><strong><span>Criteria criteria=session.createCriteria(User.class);</span></strong></div>
            <div><strong><span>criteria.setProjection(Projections.groupProperty(&#8220;age&#8221;));(1)</span></strong></div>
            <div><strong><span>List list=criteria.list();</span></strong></div>
            <div><strong><span>Iterator it=list.iterator();</span></strong></div>
            <div><strong><span>while(it.hasNext()){</span></strong></div>
            <div><strong><span>&nbsp;System.out.println(it.next());</span></strong></div>
            <div><strong><span>}</span></strong></div>
            <div><strong><span>通过（</span></strong><strong><span>1</span></strong><strong><span>）处的代码，我们通过</span></strong><strong><span>Projections</span></strong><strong><span>类指定了用于分组的目标属性，当进行检索时</span></strong><strong><span>Hibernate</span></strong><strong><span>会生成类似如下的</span></strong><strong><span>SQL</span></strong><strong><span>语句：</span></strong></div>
            <div><strong><span>Select age from user group by age;</span></strong></div>
            <div><strong><span>还可以通过使用</span></strong><strong><span>Projections</span></strong><strong><span>的</span></strong><strong><span>avg()/rowCount()/count()/max()/min()/countDistinct()</span></strong><strong><span>等方法来实现统计功能，如下面的代码示例：</span></strong></div>
            <div><strong><span>Criteria criteria=session.createCriteria(User.class);</span></strong></div>
            <div><strong><span>criteria.setProjection(Projections.avg(&#8220;age&#8221;));(1)</span></strong></div>
            <div><strong><span>List list=criteria.list();</span></strong></div>
            <div><strong><span>Iterator it=list.iterator();</span></strong></div>
            <div><strong><span>while(it.hasNext()){</span></strong></div>
            <div><strong><span>&nbsp;System.out.println(it.next());</span></strong></div>
            <div><strong><span>}</span></strong></div>
            <div><strong><span>通过（</span></strong><strong><span>1</span></strong><strong><span>）处的代码，我们实现了对用户平均年龄的统计，当进行检索时，</span></strong><strong><span>Hibernate</span></strong><strong><span>会生成类似如下的</span></strong><strong><span>SQL</span></strong><strong><span>语句：</span></strong></div>
            <div><strong><span>Select avg(age) from user;</span></strong></div>
            <div><strong><span>另外，在</span></strong><strong><span>SQL</span></strong><strong><span>语句中的多条件分组与统计功能，可以利用</span></strong><strong><span>ProjectionList</span></strong><strong><span>类来实现，如下面代码所示：</span></strong></div>
            <div><strong><span>Criteria criteria=session.createCriteria(User.class);</span></strong></div>
            <div><strong><span>ProjectionList prolist=Projections.projectionList();</span></strong></div>
            <div><strong><span>prolist.add(Projections.groupProperty(&#8220;age&#8221;));</span></strong></div>
            <div><strong><span>prolist.add(Projections.rowCount());</span></strong></div>
            <div><strong><span>criteria.setProjection(prolist);</span></strong></div>
            <div><strong><span>List list=criteria.list();</span></strong></div>
            <div><strong><span>通过以上代码，实现了对不同年龄人员数量的分组统计，当进行检索时，</span></strong><strong><span>Hibernate</span></strong><strong><span>会生成类似如下的</span></strong><strong><span>SQL</span></strong><strong><span>语句：</span></strong></div>
            <div><strong><span>Select age,count(*) from user group by age;</span></strong></div>
            <div><strong><span>5、</span></strong><strong><span>DetachedCriteria:</span></strong></div>
            <div><strong><span>在</span></strong><strong><span>Hibernate2</span></strong><strong><span>中，</span></strong><strong><span>Criteria</span></strong><strong><span>实例是与创建它的</span></strong><strong><span>Session</span></strong><strong><span>实例具有相同的生命周期的，也就是说，</span></strong><strong><span>Session</span></strong><strong><span>实例是它所创建的</span></strong><strong><span>Criteria</span></strong><strong><span>实例的宿主，当</span></strong><strong><span>Session</span></strong><strong><span>关闭时，寄生于</span></strong><strong><span>Session</span></strong><strong><span>实例的</span></strong><strong><span>Criteria</span></strong><strong><span>都将失效。这就对</span></strong><strong><span>Criteria</span></strong><strong><span>的重用造成了困难，为了实现</span></strong><strong><span>Criteria</span></strong><strong><span>实例的重用，在</span></strong><strong><span>Hibernate3</span></strong><strong><span>中提供了一个</span></strong><strong><span>DetachedCriteria</span></strong><strong><span>类，</span></strong><strong><span>DetachedCriteria</span></strong><strong><span>实例的生命周期与</span></strong><strong><span>Session</span></strong><strong><span>实例的生命周期无关，我们可以利用</span></strong><strong><span>DetachedCriteria</span></strong><strong><span>对一些常用的</span></strong><strong><span>Criteria</span></strong><strong><span>查询条件进行抽离，当需要进行检索时再与</span></strong><strong><span>Session</span></strong><strong><span>实例关联，从而获得运行期的</span></strong><strong><span>Criteria</span></strong><strong><span>实例。如下面的代码所示：</span></strong></div>
            <div><strong><span>&nbsp;&nbsp; DetachedCriteria dc= DetachedCriteria.forClass(User.class);</span></strong></div>
            <div><strong><span>&nbsp;&nbsp; dc.add(Expression.eq(&#8220;name&#8221;,&#8221;zhaoxin&#8221;));</span></strong></div>
            <div><strong><span>&nbsp;&nbsp; dc.add(Expression.eq(&#8220;sex&#8221;,&#8221;1&#8221;));</span></strong></div>
            <div><strong><span>&nbsp;&nbsp; <span style="color: red">Criteria criteria=dc.getExecutableCriteria(session);</span></span></strong></div>
            <div><strong><span>&nbsp;&nbsp; Iterator it=criteria.list().iterator();</span></strong></div>
            <div><strong><span>&nbsp;&nbsp; while(it.hasNext()){</span></strong></div>
            <div><strong><span>&nbsp;&nbsp;&nbsp;&nbsp; User user=(User)it.next();</span></strong></div>
            <div><strong><span>&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(user.getName());</span></strong></div>
            <div><strong><span>&nbsp;&nbsp; }</span></strong></div>
            <div><strong><span>&nbsp;</span></strong><strong><span>正如我们所见，</span></strong><strong><span>DetachedCriteria</span></strong><strong><span>的生存周期与</span></strong><strong><span>session</span></strong><strong><span>实例无关，当需要进行检索时，通过</span></strong><strong><span>getExecutableCriteria(session)</span></strong><strong><span>方法，与当前的</span></strong><strong><span>Session</span></strong><strong><span>实例关联并获得运行期的</span></strong><strong><span>Criteria</span></strong><strong><span>实例，完成检索。</span></strong></div>
            <div><strong><span>DetachedCriteria</span></strong><strong><span>也可以用于完成子查询功能，如下代码所示：</span></strong></div>
            <div><strong><span>DetachedCriteria dc= DetachedCriteria.forClass(User.class);</span></strong></div>
            <div><strong><span>dc.setProjection(Projections.avg(&#8220;age&#8221;));</span></strong></div>
            <div><strong><span>Criteria criteria=session.createCriteria(User.class);</span></strong></div>
            <div><strong><span>criteria.add(Subqueries.propertyGt(&#8220;age&#8221;,dc));</span></strong></div>
            <div><strong><span>List list=criteria.list();</span></strong></div>
            <div><strong><span>通过</span></strong><strong><span>Subqueries</span></strong><strong><span>类，实现了添加子查询的功能，我们将</span></strong><strong><span>DetachedCriteria</span></strong><strong><span>所设定的查询条件，当作子查询添加到了运行时</span></strong><strong><span>Criteria</span></strong><strong><span>实例的查询条件中，当执行检索时</span></strong><strong><span>Hibernate</span></strong><strong><span>会生成类似如下的</span></strong><strong><span>SQL</span></strong><strong><span>语句：</span></strong></div>
            <div><strong><span>Select * from user where age&gt;(select avg(age) from user group by age);</span></strong></div>
            </td>
        </tr>
    </tbody>
</table>
</div>
</span></strong></div>
</div>
</div>
<img src ="http://www.blogjava.net/relax/aggbug/188943.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/relax/" target="_blank">轻松</a> 2008-03-27 10:23 <a href="http://www.blogjava.net/relax/archive/2008/03/27/188943.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用struts+spring+hibernate 组装web应用</title><link>http://www.blogjava.net/relax/archive/2005/03/22/2315.html</link><dc:creator>轻松</dc:creator><author>轻松</author><pubDate>Tue, 22 Mar 2005 03:19:00 GMT</pubDate><guid>http://www.blogjava.net/relax/archive/2005/03/22/2315.html</guid><wfw:comment>http://www.blogjava.net/relax/comments/2315.html</wfw:comment><comments>http://www.blogjava.net/relax/archive/2005/03/22/2315.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/relax/comments/commentRss/2315.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/relax/services/trackbacks/2315.html</trackback:ping><description><![CDATA[<TABLE cellSpacing=0 cellPadding=0 width="85%" align=center border=0>
<TBODY>
<TR>
<TD style="FONT-SIZE: 9pt" align=middle width="100%" height=30><FONT color=#666666>matrix.com.cn&nbsp;&nbsp;&nbsp;&nbsp;<!--阅读335次--></FONT>&nbsp;&nbsp;<A href="http://www.dangdang.com/league/leagueref.asp?from=P-2023703&amp;backurl=http://211.100.16.156/dangdang.dll?key=WEB开发"><FONT color=red>相关书籍</FONT></A></TD></TR>
<TR>
<TD style="FONT-SIZE: 9pt" align=middle width="100%"></TD></TR>
<TR>
<TD style="FONT-SIZE: 14px" align=middle width="100%">
<TABLE cellSpacing=0 cellPadding=0 align=center border=0>
<TBODY>
<TR>
<TD style="FONT-SIZE: 14px">
<TABLE class=tf width="98%" align=center border=0>
<TBODY>
<TR>
<TD class=bw width="100%"><FONT class=htd id=font_word style="FONT-SIZE: 14px" font-family:宋体, Verdana, Arial, Helvetica, sans-serif;>src=http://pagead2.googlesyndication.com/pagead/show_ads.js&gt;</SCRIPT><SPAN class=postbody>其实，就算用Java建造一个不是很烦琐的web应用，也不是件轻松的事情。 在构架的一开始就有很多事情要考虑。 从高处看，摆在开发者面前有很多问题：要考虑是怎样建立用户接口？在哪里处理业务逻辑？ 怎样持久化的数据。 而这三层构架中，每一层都有他们要仔细考虑的。 各个层该使用什么技术？ 怎样的设计能松散耦合还能灵活改变？ 怎样替换某个层而不影响整体构架？应用程序如何做各种级别的业务处理（比如事务处理）？ <BR><BR><BR><BR>构架一个Web应用需要弄明白好多问题。 幸运的是，已经有不少开发者已经遇到过这类问题，并且建立了处理这类问题的框架。 一个好框架具备以下几点： 减轻开发者处理复杂的问题的负担（“不重复发明轮子”）； 内部有良好的扩展； 并且有一个支持它的强大的用户团体。 好的构架一般有针对性的处理某一类问题，并且能将它做好（Do One Thing well）。 然而，你的程序中有几个层可能需要使用特定的框架，已经完成的UI(用户接口) 并不代表你也可以把你的业务逻辑和持久逻辑偶合到你的UI部分。 举个例子， 你不该在一个Controller(控制器)里面写JDBC代码作为你的业务逻辑， 这不是控制器应该提供的。 一个UI 控制器应该委派给其它给在UI范围之外的轻量级组件。 好的框架应该能指导代码如何分布。 更重要的是，框架能把开发者从编码中解放出来，使他们能专心于应用程序的逻辑（这对客户来说很重要）。 <BR><BR><BR><BR>这篇文章将讨论怎样结合几种著名的框架来使得你的应用程序做到松弛耦合。 <BR><BR>如何建立你的架构，并且怎样让你的各个应用层保持一致。？如何整合框架以便让每个层在以一种松散偶合的方式彼此作用而不用管低层的技术细节？这对我们来说真是一种挑战。 这里讨论一个整合框架的策略( 使用3 种受欢迎的开源框架) ：表示层我们用Struts； 业务层我们用Spring；而持久层则用Hibernate。 你也可以用其他FrameWork替换只要能得到同样的效果。 见图1 （框架组合示意图） <BR><BR><IMG src="http://www.onjava.com/onjava/2004/04/07/graphics/wiring.gif" border=0> <BR><BR><SPAN style="FONT-WEIGHT: bold">应用程序的分层</SPAN> <BR><BR>大部分的Web应用在职责上至少能被分成4层。 这四层是：presentation（描述），persistence（持久），business（业务）和domain model（域模块）。每个层在处理程序上都应该有一项明确的责任, 而不应该在功能上与其它层混合，并且每个层要与其它层分开的，但要给他们之间放一个通信接口。 我们就从介绍各个层开始，讨论一下这些层应该提供什么，不应该提供什么。 <BR><BR><BR><BR><SPAN style="FONT-WEIGHT: bold">表示层(The Presentation Layer) </SPAN><BR><BR>一般来讲，一个典型的Web应用的的末端应该是表示层。 很多Java发者也理解Struts所提供的。 象业务逻辑之类的被打包到org.apache.struts.Action.， 因此，我们很赞成使用Struts这样的框架。 <BR><BR><BR><BR>下面是Struts所负责的： <BR><BR>* 管理用户的请求,做出相应的响应。 <BR><BR>* 提供一个Controller ,委派调用业务逻辑和其它上层处理。 <BR><BR>* 处理异常，抛给Struts Action <BR><BR>* 为显示提供一个模型 <BR><BR>* UI验证。 <BR><BR><BR><BR>以下条款，不该在Struts显示层的编码中经常出现。 它们与显示层无关的。 <BR><BR>* 直接的与数据库通信，例如JDBC调用。 <BR><BR>* 与你应用程序相关联的业务逻辑以及校验。 <BR><BR>* 事物管理。 <BR><BR>在表示层引入这些代码，则会带来高偶合和麻烦的维护。 <BR><BR><BR><BR><BR><BR><SPAN style="FONT-WEIGHT: bold">持久层(The Persistence Layer)</SPAN> <BR><BR>典型的Web应用的另一个末端是持久层。这里通常是程序最容易失控的地方。开发者总是低估构建他们自己的持久框架的挑战性。系统内部的持续层不但需要大量调试时间，而且还经常缺少功能使之变得难以控制，这是持久层的通病。 还好有几个ORM开源框架很好的解决了这类问题。尤其是Hibernate。 Hibernate为java提供了OR持久化机制和查询服务, 它还给已经熟悉SQL和JDBC API 的Java开发者一个学习桥梁，他们学习起来很方便。 Hibernate的持久对象是基于POJO和Java collections。此外，使用Hibernate并不妨碍你正在使用的IDE。 <BR><BR><BR><BR>请看下面的条目，你在持久层编码中需要了解的。 <BR><BR>* 查询对象的相关信息的语句。 Hibernate通过一个OO查询语言（HQL）或者正则表达的API来完成查询。 HQL非常类似于SQL-- 只是把SQL里的table和columns用Object和它的fields代替。 你需要学习一些新的HQL语言； 不管怎样，他们容易理解而文档也做的很好。 HQL是一种对象查询的自然语言，花很小的代价就能学习它。 <BR><BR>* 如何存储，更新，删除数据库记录。 <BR><BR>* 象Hibernate这类的高级ORM框架支持大部分主流数据库，并且他们支持 Parent/child关系，事物处理，继承和多态。 <BR><BR><BR><BR><SPAN style="FONT-WEIGHT: bold">业务层（The Business Layer）</SPAN> <BR><BR>一个典型Web应用的中间部分是业务层或者服务层。 从编码的视角来看，这层是最容易被忽视的一层。 而我们却往往在UI层或持久层周围看到这些业务处理的代码，这其实是不正确的，因为它导致了程序代码的紧密偶合，这样一来，随着时间推移这些代码很难维护。幸好，针对这一问题有好几种Frameworks存在。 最受欢迎的两个框架是Spring和PicoContainer。 这些为也被称为microcontainers，他们能让你很好的把对象搭配起来。 这两个框架都着手于‘依赖注射’(dependency injection)(还有我们知道的‘控制反转’Inversion of Control=IoC)这样的简单概念。 这篇文章将关注于Spring的注射（译注：通过一个给定参数的Setter方法来构造Bean,有所不同于Factory）, Spring还提供了Setter Injection(type2)，Constructor Injection(type3)等方式供我们选择。 Spring把程序中所涉及到包含业务逻辑和Dao的Objects——例如transaction management handler（事物管理控制）、Object Factoris(对象工厂)、service objects（服务组件）——都通过XML来配置联系起来。 <BR><BR><BR><BR>后面我们会举个例子来揭示一下Spring 是怎样运用这些概念。 <BR><BR>业务层所负责的如下： <BR><BR>* 处理应用程序的 业务逻辑和业务校验 <BR><BR>* 管理事物 <BR><BR>* 允许与其它层相互作用的接口 <BR><BR>* 管理业务层级别的对象的依赖。 <BR><BR>* 在显示层和持久层之间增加了一个灵活的机制，使得他们不直接的联系在一起。 <BR><BR>* 通过揭示 从显示层到业务层之间的Context来得到business services。 <BR><BR>* 管理程序的执行（从业务层到持久层）。 <BR><BR><BR><BR><BR><BR><SPAN style="FONT-WEIGHT: bold">域模块层（The Domain Model Layer ）</SPAN> <BR>既然我们致力于的是一个不是很复杂的Web的应用， 我们需要一个对象集合，让它在不同层之间移动的。 域模块层由实际需求中的业务对象组成 比如, OrderLineItem , Product等等。 开发者在这层 不用管那些DTOs，仅关注domain object即可。 例如，Hibernate允许你将数据库中的信息存放入对象（domain objects），这样你可以在连接断开的情况下把这些数据显示到UI层。 而那些对象也可以返回给持续层，从而在数据库里更新。 而且，你不必把对象转化成DTOs（这可能似的它在不同层之间的在传输过程中丢失），这个模型使得Java开发者能很自然运用OO，而不需要附加的编码。 <BR><BR>一个简单例子 <BR><BR><BR><BR>既然我们已经从全局上理解这些组件。 现在就让我们开始实践吧。 我们还是用 Struts，Spring 和Hibernate。这三个框架已经被描述够多了，这里就不重复介绍了。 这篇文章举例指导你如何使用这三个框架整合开发, 并向你揭示 一个请求是如何贯穿于各个层的。（从用户的加入一个Order到数据库，显示；进而更新、删除）。 <BR><BR><BR><BR>从这里可以下载到程序程序原代码（<A class=postlink href="http://www.onjava.com/onjava/2004/04/07/examples/wiring.zip" target=_blank><FONT color=#006699>download</FONT></A>） <BR><BR>既然每个层是互相作用的，我们就先来创建domain objects。首先，我们要在这些Object中要确定那些是需要持久化的，哪些是提供给business logic，那些是显示接口的设计。 下一步，我们将配置我们的持久层并且定义好Hibernate的OR mappings。然后定义好Business Objects。有了这些组成部分之后，我们将 使用Spring把这些连接起来。 最后，我们提供给Spring一个持久层，从这个持久层里我们可以知道它是如何与业务逻辑层（business service layer）通信的，以及它是怎样处理其他层抛出的异常的。。 <BR><BR><BR><BR><SPAN style="FONT-WEIGHT: bold">域对象层（Domain Object Layer）</SPAN> <BR><BR><BR>这层是编码的着手点，我们的编码就从这层开始。 例子中Order 与OrderItem 是一个One—To—Many的关系。 下面就是Domain Object Layer的两个对象： <BR><BR><BR><BR>· com.meagle.bo.Order.java: 包含了一个Order的概要信息 <BR><BR>· com.meagle.bo.OrderLineItem.java: 包含了Order的详细信息 <BR><BR>好好考虑怎你的package命名,这反应出了你是怎样分层的。 例如 domain objects在程序中可能打包在com.meagle.bo内。 更详细一点将打包在com. meagle.bo的子目录下面。business logic应该从com.meagle.serice开始打包，而DAO 对象应该位于com.meagle.service.dao.hibernate。反应Forms和Actions的 持久对象（presentation classes） 应该分别放在 com.meagle.action和com.meagle.forms包。 准确的给包命名使得你的classes很好分割并且易于维护，并且在你添加新的classes时，能使得程序结构上保持上下一致。 <BR><BR><SPAN style="FONT-WEIGHT: bold">持久层的配置（Persistence Layer Configuration）</SPAN> <BR><BR>建立Hibernate的持久层 需要好几个步骤。 第一步让我们把BO持久化。 既然Hibernate是通过POJO工作的， 因此Order和 OrderLineItem对象需要给所有的fileds 加上getter,setter方法。 Hibernate通过XML文件来映射(OR)对象，以下两个xml文件分别映射了Order 和OrderItem对象。（这里有个叫XDoclet工具可以自动生成你的XML影射文件） <BR><BR>- Order.hbm.xml <BR>- OrderLineItem.hbm.xml <BR><BR>你可以在WebContent/WEB-INF/classes/com/meagle/bo目录下找到这些xml文件。Hibernate的 [urlhttp://www.hibernate.org/hib_docs/api/net/sf/hibernate/SessionFactory.html]SessionFactory [/url]是用来告诉程序 应该与哪个数据库通信，该使用哪个连接池或使用了DataSource， 应该加载哪些持久对象。而<A class=postlink href="http://www.hibernate.org/hib_docs/api/net/sf/hibernate/Session.html" target=_blank><FONT color=#006699>Session</FONT></A>接口是用来完成Selecting，Saving，Delete和Updating这些操作。 后面的我们将讲述SessionFactory和Session是怎样设置的。 <BR><BR><SPAN style="FONT-WEIGHT: bold">业务层的配置（Business Layer Configuration）</SPAN> <BR><BR>既然我们已经有了domain objects，接下来我们就要business service objects了，用他们来执行程序的logic,调用持久层，得到UI层的requests,处理transactions，并且控制exceptions。 为了将这些连接起来并且易于管理，我们将使用面向方面的 SpringFramework。 Spring 提供了 控制倒置（inversion of control 0==IoC)和注射依赖设置（setter dependency injection）这些方式（可供选择），用XML文件将对象连接起来。 IoC是一个简单概念（它允许一个对象在上层接受其他对象的创建），用IoC这种方式让你的对象从创建中释放了出来，降低了偶合度。 <BR><BR><BR><BR><BR>这里是一个没有使用IoC的对象创建的例子，它有很高偶合度。 <BR><BR><BR><IMG src="http://www.onjava.com/onjava/2004/04/07/graphics/nonioc.gif" border=0> <BR><BR><SPAN style="FONT-STYLE: italic">图 2.没有使用 IoC. A 创建了 B 和 C</SPAN> <BR><BR>而这里是一个使用IoC的例子，这种方式允许对象在高层可以创建并进入另外一个对象，所以这样可以直接被执行。 <BR><IMG src="http://www.onjava.com/onjava/2004/04/07/graphics/ioc.gif" border=0> <BR><BR><SPAN style="FONT-STYLE: italic">图 3. 对象使用了 IoC。 A 包含了接受B,C的 setter方法 , 这同样达到了 由A创建B,C的目的。</SPAN> <BR><BR>建立我们的业务服务对象（Building Our Business Service Objects） <BR><BR><BR>Business Object中的Setter方法接受的是接口，这样我们可以很松散的定义对象实现，然后注入。 在我们的案例中，我们将用一个business service object接收一个DAO,用它来控制domain objects的持久化。 由于在这个例子中使用了Hibernate，我们可以很方便的用其他持久框架实现 同时通知Spring 有新的DAO可以使用了。 <BR><BR>在面向接口的编程中，你会明白 “注射依赖”模式是怎样松散耦合你的业务逻辑和持久机制的：）。 <BR><BR><BR><BR>下面是一个接口business service object，DAO代码片段： <BR><BR><BR></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B><FONT size=2>代码:</FONT></B></SPAN></TD></TR>
<TR>
<TD class=code><BR>public interface IOrderService { <BR><BR>&nbsp; public abstract Order saveNewOrder(Order order) <BR><BR>&nbsp; &nbsp; throws OrderException, <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;OrderMinimumAmountException; <BR><BR>&nbsp; <BR><BR>&nbsp; public abstract List findOrderByUser( <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;String user) <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;throws OrderException; <BR><BR>&nbsp; <BR><BR>&nbsp; public abstract Order findOrderById(int id) <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;throws OrderException; <BR><BR>&nbsp; <BR><BR>&nbsp; public abstract void setOrderDAO( <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IOrderDAO orderDAO); <BR><BR>} <BR><BR>&nbsp;</TD></TR></TBODY></TABLE><SPAN class=postbody><BR>注意到这段代码里有一个 setOrderDao（），它就是一个DAO Object设置方法（注射器）。 但这里并没有一个getOrderDao的方法，这不必要，因为你并不会在外部访问这个orderDao。这个DAO Objecte将被调用，和我们的persistence layer 通信。我们将用Spring把DAO Object 和 business service object搭配起来的。因为我们是面向接口编程的，所以并不需要将实现类紧密的耦合在一起。 <BR><BR><BR><BR>接下去我们开始我们的DAO的实现类进行编码。 既然Spring已经有对Hibernate的支持，那这个例子就直接继承<A class=postlink href="http://www.springframework.org/docs/api/org/springframework/orm/hibernate/support/HibernateDaoSupport.html" target=_blank><FONT color=#006699>HibernateDaoSupport</FONT></A>类了，这个类很有用，我们可以参考<A class=postlink href="http://www.springframework.org/docs/api/org/springframework/orm/hibernate/HibernateTemplate.html" target=_blank><FONT color=#006699>HibernateTemplate</FONT></A>（它主要是针对HibernateDaoSupport的一个用法，译注：具体可以查看<A class=postlink href="http://www.springframework.org/docs/api/index.html" target=_blank><FONT color=#006699>Srping 的API</FONT></A>）。 下面是这个DAO接口代码： <BR><BR></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B><FONT size=2>代码:</FONT></B></SPAN></TD></TR>
<TR>
<TD class=code>public interface IOrderDAO { <BR>&nbsp; public abstract Order findOrderById( <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; final int id); <BR>&nbsp; <BR>&nbsp; public abstract List findOrdersPlaceByUser( <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;final String placedBy); <BR>&nbsp; public abstract Order saveOrder( <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;final Order order); <BR>}</TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR>我们仍然要给我们持久层组装很多关联的对象，这里包含了HibernateSessionFactory 和TransactionManager。 Spring 提供了一个 <A class=postlink href="http://www.springframework.org/docs/api/org/springframework/orm/hibernate/HibernateTransactionManager.html" target=_blank><FONT color=#006699>HibernateTransactionManager</FONT></A>，他用线程捆绑了一个Hibernate Session，用它来支持transactions(请查看<A class=postlink href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ThreadLocal.html" target=_blank><FONT color=#006699>ThreadLocal</FONT></A>) 。 <BR><BR>下面是HibernateSessionFactory 和 HibernateTransactionManager:的配置： <BR><BR></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B><FONT size=2>代码:</FONT></B></SPAN></TD></TR>
<TR>
<TD class=code>&lt;bean id="mySessionFactory" <BR>&nbsp; &nbsp; &nbsp; &nbsp;class="org.springframework.orm.hibernate. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LocalSessionFactoryBean"&gt; <BR>&nbsp; &lt;property name="mappingResources"&gt; <BR>&nbsp; &nbsp; &lt;list&gt; <BR>&nbsp; &nbsp; &nbsp; &lt;value&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp; com/meagle/bo/Order.hbm.xml <BR>&nbsp; &nbsp; &nbsp; &lt;/value&gt; <BR>&nbsp; &nbsp; &nbsp; &lt;value&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp; com/meagle/bo/OrderLineItem.hbm.xml <BR>&nbsp; &nbsp; &nbsp; &lt;/value&gt; <BR>&nbsp; &nbsp; &lt;/list&gt; <BR>&nbsp; &lt;/property&gt; <BR>&nbsp; &lt;property name="hibernateProperties"&gt; <BR>&nbsp; &nbsp; &lt;props&gt; <BR>&nbsp; &nbsp; &nbsp; &lt;prop key="hibernate.dialect"&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp; net.sf.hibernate.dialect.MySQLDialect <BR>&nbsp; &nbsp; &nbsp; &lt;/prop&gt; <BR>&nbsp; &nbsp; &nbsp; &lt;prop key="hibernate.show_sql"&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp; false <BR>&nbsp; &nbsp; &nbsp; &lt;/prop&gt; <BR>&nbsp; &nbsp; &nbsp; &lt;prop key="hibernate.proxool.xml"&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp; C:/MyWebApps/.../WEB-INF/proxool.xml <BR>&nbsp; &nbsp; &nbsp; &lt;/prop&gt; <BR>&nbsp; &nbsp; &nbsp; &lt;prop key="hibernate.proxool.pool_alias"&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; spring <BR>&nbsp; &nbsp; &nbsp; &lt;/prop&gt; <BR>&nbsp; &nbsp; &lt;/props&gt; <BR>&nbsp; &lt;/property&gt; <BR>&lt;/bean&gt; <BR>&nbsp; <BR>&lt;!-- Transaction manager for a single Hibernate <BR>SessionFactory (alternative to JTA) --&gt; <BR>&lt;bean id="myTransactionManager" <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;class="org. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; springframework. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; orm. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hibernate. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HibernateTransactionManager"&gt; <BR>&nbsp; &lt;property name="sessionFactory"&gt; <BR>&nbsp; &nbsp; &lt;ref local="mySessionFactory"/&gt; <BR>&nbsp; &lt;/property&gt; <BR>&nbsp; &lt;/bean&gt;</TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR><BR>可以看出：每个对象都可以在Spring 配置信息中用&lt;bean&gt;标签引用。在这里，mySessionFactory引用了HibernateSessionFactory，而myTransactionManager引用了HibernateTransactionManage。 注意代码中myTransactionManger Bean有个sessionFactory属性。 HibernateTransactionManager有个sessionFactory setter 和 getter方法，这是用来在Spring启动的时候实现“依赖注入” （dependency injection）的。 在sessionFactory 属性里 引用mySessionFactory。这两个对象在Spring容器初始化后就被组装了起来了。 这样的搭配让你从 单例（singleton objects）和工厂（factories）中解放了出来，降低了代码的维护代价。 mySessionFactory.的两个属性，分别是用来注入mappingResources 和 hibernatePropertes的。通常，如果你在Spring之外使用Hibernate,这样的设置应该放在hibernate.cfg.xml中的。 不管怎样,Spring提供了一个便捷的方式-----在Spring内部配置中并入了Hibernate的配置。 如果要得到更多的信息，可以查阅Spring API。 <BR><BR><BR><BR><BR><BR>既然我们已经组装配置好了Service Beans，就需要把Business Service Object和 DAO也组装起来，并把这些对象配到一个事务管理器（transaction manager）里。 <BR><BR><BR><BR>在Spring中的配置信息： <BR></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B><FONT size=2>代码:</FONT></B></SPAN></TD></TR>
<TR>
<TD class=code><BR>&lt;!-- ORDER SERVICE --&gt; <BR>&lt;bean id="orderService" <BR>&nbsp; class="org. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;springframework. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;transaction. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;interceptor. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TransactionProxyFactoryBean"&gt; <BR>&nbsp; &lt;property name="transactionManager"&gt; <BR>&nbsp; &nbsp; &lt;ref local="myTransactionManager"/&gt; <BR>&nbsp; &lt;/property&gt; <BR>&nbsp; &lt;property name="target"&gt; <BR>&nbsp; &nbsp; &lt;ref local="orderTarget"/&gt; <BR>&nbsp; &lt;/property&gt; <BR>&nbsp; &lt;property name="transactionAttributes"&gt; <BR>&nbsp; &nbsp; &lt;props&gt; <BR>&nbsp; &nbsp; &nbsp; &lt;prop key="find*"&gt; <BR>&nbsp; &nbsp; &nbsp;PROPAGATION_REQUIRED,readOnly,-OrderException <BR>&nbsp; &nbsp; &nbsp; &lt;/prop&gt; <BR>&nbsp; &nbsp; &nbsp; &lt;prop key="save*"&gt; <BR>&nbsp; &nbsp; &nbsp;PROPAGATION_REQUIRED,-OrderException <BR>&nbsp; &nbsp; &nbsp; &lt;/prop&gt; <BR>&nbsp; &nbsp; &lt;/props&gt; <BR>&nbsp; &lt;/property&gt; <BR>&lt;/bean&gt; <BR>&nbsp; <BR>&lt;!-- ORDER TARGET PRIMARY BUSINESS OBJECT: <BR>Hibernate implementation --&gt; <BR>&lt;bean id="orderTarget" <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;class="com. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; meagle. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; service. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; spring. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OrderServiceSpringImpl"&gt; <BR>&nbsp; &lt;property name="orderDAO"&gt; <BR>&nbsp; &nbsp; &lt;ref local="orderDAO"/&gt; <BR>&nbsp; &lt;/property&gt; <BR>&lt;/bean&gt; <BR>&nbsp; <BR>&lt;!-- ORDER DAO OBJECT --&gt; <BR>&lt;bean id="orderDAO" <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;class="com. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; meagle. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; service. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dao. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hibernate. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OrderHibernateDAO"&gt; <BR>&nbsp; &lt;property name="sessionFactory"&gt; <BR>&nbsp; &nbsp; &lt;ref local="mySessionFactory"/&gt; <BR>&nbsp; &lt;/property&gt; <BR>&lt;/bean&gt;</TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR><BR><BR>图4 是我们对象搭建的一个提纲。 从中可以看出，每个对象都联系着Spring，并且能通过Spring注入到其他对象。把它与Spring的配置文件比较，观察他们之间的关系 <BR><BR><IMG src="http://www.onjava.com/onjava/2004/04/07/graphics/spring_wiring.gif" border=0> <BR><BR><SPAN style="FONT-STYLE: italic">图 4. Spring就是这样基于配置文件，将各个Bean搭建在一起。</SPAN> <BR><BR>这个例子使用一个TransactionProxyFactoryBean，它定义了一个setTransactionManager()。 这对象很有用，他能很方便的处理你申明的事物还有Service Object。 你可以通过transactionAttributes属性来定义怎样处理。 想知道更多还是参考TransactionAttributeEditor吧。 <BR><BR>TransactionProxyFactoryBean 还有个setter. 这会被我们 Business service object（orderTarget）引用， orderTarget定义了 业务服务层，并且它还有个属性，由setOrderDAO()引用。这个属性 <BR><BR><BR><BR>Spring 和Bean 的还有一点要注意的： bean可以以用两种方式创造。 这些都在单例模式（Sington）和原型模式（propotype）中定义了。 默认的方式是singleton,这意味着共享的实例将被束缚。 而原形模式是在Spring用到bean的时候允许新建实例的。当每个用户需要得到他们自己Bean的Copy时，你应该仅使用prototype模式。（更多的请参考设计模式中的单例模式和原形模式） <BR><BR><SPAN style="FONT-WEIGHT: bold">提供一个服务定位器（Providing a Service Locator）</SPAN> <BR>既然我们已经将我们的Serices和DAO搭配起来了。我们需要把我们的Service显示到其他层。 这个通常是在Struts或者Swing这层里编码。一个简单方法就是用 服务定位器返回给Spring context 。当然，可以通过直接调用Spring中的Bean来做。 <BR><BR>下面是一个Struts Actin 中的服务定位器的一个例子。 <BR></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B><FONT size=2>代码:</FONT></B></SPAN></TD></TR>
<TR>
<TD class=code><BR>public abstract class BaseAction extends Action { <BR>&nbsp; <BR>&nbsp; private IOrderService orderService; <BR>&nbsp; <BR>&nbsp; public void setServlet(ActionServlet <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;actionServlet) { <BR>&nbsp; &nbsp; super.setServlet(actionServlet); <BR>&nbsp; &nbsp; ServletContext servletContext = <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;actionServlet.getServletContext(); <BR>&nbsp; <BR>&nbsp; &nbsp; WebApplicationContext wac = <BR>&nbsp; &nbsp; &nbsp; WebApplicationContextUtils. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;getRequiredWebApplicationContext( <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;servletContext); <BR>&nbsp; <BR>&nbsp; &nbsp; &nbsp; this.orderService = (IOrderService) <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;wac.getBean("orderService"); <BR>&nbsp; } <BR>&nbsp; <BR>&nbsp; protected IOrderService getOrderService() { <BR>&nbsp; &nbsp; return orderService; <BR>&nbsp; } <BR>} <BR>&nbsp;</TD></TR></TBODY></TABLE><SPAN class=postbody><BR><SPAN style="FONT-WEIGHT: bold">UI 层配置 （UI Layer Configuration）</SPAN> <BR><BR>这个例子里UI层 使用了Struts framework. 这里我们要讲述一下在给程序分层的时候， 哪些是和Struts部分的。我们就从一个Struts-config.xml文件中的Action的配置信息开始吧。 <BR></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B><FONT size=2>代码:</FONT></B></SPAN></TD></TR>
<TR>
<TD class=code><BR>struts-config.xml file. <BR><BR>&lt;action path="/SaveNewOrder" <BR>&nbsp; &nbsp; type="com.meagle.action.SaveOrderAction" <BR>&nbsp; &nbsp; name="OrderForm" <BR>&nbsp; &nbsp; scope="request" <BR>&nbsp; &nbsp; validate="true" <BR>&nbsp; &nbsp; input="/NewOrder.jsp"&gt; <BR>&nbsp; &lt;display-name&gt;Save New Order&lt;/display-name&gt; <BR>&nbsp; &lt;exception key="error.order.save" <BR>&nbsp; &nbsp; path="/NewOrder.jsp" <BR>&nbsp; &nbsp; scope="request" <BR>&nbsp; &nbsp; type="com.meagle.exception.OrderException"/&gt; <BR>&nbsp; &lt;exception key="error.order.not.enough.money" <BR>&nbsp; &nbsp; path="/NewOrder.jsp" <BR>&nbsp; &nbsp; scope="request" <BR>&nbsp; &nbsp; type="com. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; meagle. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exception. <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OrderMinimumAmountException"/&gt; <BR>&nbsp; &lt;forward name="success" path="/ViewOrder.jsp"/&gt; <BR>&nbsp; &lt;forward name="failure" path="/NewOrder.jsp"/&gt; <BR>&lt;/action&gt;</TD></TR></TBODY></TABLE><SPAN class=postbody><BR>SaveNewOrder 这个Action是用来持久化UI层里的表单提交过来Order的。这是Struts中一个很典型的Action; 注意观察这个Action中exception配置，这些Exceptions也在Spring 配置文件(applicationContext-hibernate.xml)中配置了（就在 business service object 的transactionAttributes属性里）。 当异常在业务层被被抛出时，我们可以控制他们，并适当的显示给UI层。 <BR><BR>第一个异常，OrderException,在持久层保存order对象失败的时候被触发。这将导致事物回滚并且通过BO把异常回传到Struts这一层。 <BR><BR>第二个异常，OrderMinimumAmountException也同第一个一样。 <BR><BR><BR><BR><BR><BR>搭配整和的最后一步 通过是让你显示层和业务层相结合。这个已经被服务定位器（service locator）实现了（前面讨论过了）， 这里服务层作为一个接口提供给我们的业务逻辑和持久层。 <BR><BR><BR><BR>SaveNewOrder Action 在Struts中用一个服务定位器（service locator）来调用执行业务方法的。 方法代码如下： <BR><BR><BR><BR></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B><FONT size=2>代码:</FONT></B></SPAN></TD></TR>
<TR>
<TD class=code>public ActionForward execute( <BR><BR>&nbsp; ActionMapping mapping, <BR><BR>&nbsp; ActionForm form, <BR><BR>&nbsp; javax.servlet.http.HttpServletRequest request, <BR><BR>&nbsp; javax.servlet.http.HttpServletResponse response) <BR><BR>&nbsp; throws java.lang.Exception { <BR><BR>&nbsp; <BR><BR>&nbsp; OrderForm oForm = (OrderForm) form; <BR><BR>&nbsp; <BR><BR>&nbsp; // Use the form to build an Order object that <BR><BR>&nbsp; // can be saved in the persistence layer. <BR><BR>&nbsp; // See the full source code in the sample app. <BR><BR>&nbsp; <BR><BR>&nbsp; // Obtain the wired business service object <BR><BR>&nbsp; // from the service locator configuration <BR><BR>&nbsp; // in BaseAction. <BR><BR>&nbsp; // Delegate the save to the service layer and <BR><BR>&nbsp; // further upstream to save the Order object. <BR><BR>&nbsp; getOrderService().saveNewOrder(order); <BR><BR>&nbsp; <BR><BR>&nbsp; oForm.setOrder(order); <BR><BR>&nbsp; <BR><BR>&nbsp; ActionMessages messages = new ActionMessages(); <BR><BR>&nbsp; messages.add( <BR><BR>&nbsp; &nbsp; &nbsp; ActionMessages.GLOBAL_MESSAGE, <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new ActionMessage( <BR><BR>&nbsp; &nbsp; &nbsp; "message.order.saved.successfully")); <BR><BR>&nbsp; <BR><BR>&nbsp; saveMessages(request, messages); <BR><BR>&nbsp; <BR><BR>&nbsp; return mapping.findForward("success"); <BR><BR>}</TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR>总结 <BR><BR>这篇文章在技术和构架方面掩盖了很多低层的基础信息， 文章的主要的意图在于让你意识到如何给你应用程序分层。 分层可以“解耦”你的代码——允许新的组件被添加进来，而且让你的代码易于维护。 这里用到的技术只是专注于把“解偶”做好。 不管怎样，使用这样的构架可以让你用其他技术代替现在的层。 例如，你可能不使用Hibernate实现持久化。既然你在DAO中面向接口的编程的，所以你完全可以用iBATIS来代替。或者，你也可能想用Struts外的其他的技术或者框架替换现在的UI层（转换久层，实现层并不应该直接影响到你的业务逻辑和业务服务层）。 用适当的框架搭建你的Web应用，其实也不是一件烦琐的工作，更主要的是它“解耦”了你程序中的各个层。 <BR><BR><BR><BR><BR><BR>后记： <BR><BR>看完这篇文章后，只是觉得很喜欢，于是就翻译了，当然同时也准备着挨大家扔来的鸡蛋：）。 <BR><BR>这篇文章里并没有太多的技术细节，和详细的步骤。如果你从未使用过这些框架而在运行实例程序遇上困难的话，可以到CSDN论坛Java Open Source版发贴，我一定会详细解答的（啊哦，这不算做广告吧？）， <BR><BR>文章是从一个构架的角度讲述了如何搭配现有的开源框架进行分层， 有太多的术语我都不知道怎么表达，而且可能有很多语句存在错误。如果影响了你的阅读，请你直接点原文地址，我同时也象你说声抱歉。 <BR><BR><BR><BR>作者简介：Mark Eagle 高级软件工程师，亚特兰大。 <BR>翻 译：Totodo,软件工程师 </SPAN></FONT></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/relax/aggbug/2315.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/relax/" target="_blank">轻松</a> 2005-03-22 11:19 <a href="http://www.blogjava.net/relax/archive/2005/03/22/2315.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>配置Middlegen-Hibernate和hibernate-extensions以产生hbm映射文件和POJO </title><link>http://www.blogjava.net/relax/archive/2005/03/01/1588.html</link><dc:creator>轻松</dc:creator><author>轻松</author><pubDate>Tue, 01 Mar 2005 06:43:00 GMT</pubDate><guid>http://www.blogjava.net/relax/archive/2005/03/01/1588.html</guid><wfw:comment>http://www.blogjava.net/relax/comments/1588.html</wfw:comment><comments>http://www.blogjava.net/relax/archive/2005/03/01/1588.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/relax/comments/commentRss/1588.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/relax/services/trackbacks/1588.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=2>先决条件：</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">已经安装了</SPAN><SPAN lang=EN-US>ant</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US>MySQL</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据库，数据库表已经建立。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p><FONT size=2>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><FONT size=2><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">1、<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">从</SPAN><SPAN lang=EN-US>Hibernate</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">官方网站下载</SPAN><SPAN lang=EN-US>Middlegen-Hibernate</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN lang=EN-US>hibernate-extensions</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，并解压。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><FONT size=2><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">2、<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">配置</SPAN><SPAN lang=EN-US>Middlegen-Hibernate:</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><SPAN lang=EN-US>2.1 </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">配置数据库连接</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">假设连接的数据库是</SPAN><SPAN lang=EN-US>MySQL</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，在</SPAN><SPAN lang=EN-US>Middlegen-Hibernate-r5\config\database</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">目录中有一个</SPAN><SPAN lang=EN-US>mysql.xml</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件，是用来配置</SPAN><SPAN lang=EN-US>MySQL</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据库的连接的。内容为：</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN>&lt;property name="database.script.file" value="${src.dir}/sql/${name}-mysql.sql"/&gt;<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN>&lt;property name="database.driver.file" value="${lib.dir}/<SPAN style="COLOR: red">mysql-connector-java-3.0.15-ga-bin.jar</SPAN>"/&gt;<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN>&lt;property name="database.driver.classpath"<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>value="${database.driver.file}"/&gt;<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN>&lt;property name="database.driver"<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>value="org.gjt.mm.mysql.Driver"/&gt;<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN>&lt;property name="database.url"<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>value="<SPAN style="COLOR: red">jdbc:mysql://localhost/jboss</SPAN>"/&gt;<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN>&lt;property name="database.userid" <SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN>value="<SPAN style="COLOR: red">jboss</SPAN>"/&gt;<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN>&lt;property name="database.password"<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>value="<SPAN style="COLOR: red">jboss</SPAN>"/&gt;<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN>&lt;property name="database.schema"<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>value=""/&gt;<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN>&lt;property name="database.catalog"<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>value=""/&gt;<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><o:p><FONT size=2>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN>&lt;property name="jboss.datasource.mapping"<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>value="mySQL"/&gt;<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将</SPAN><SPAN lang=EN-US>mysql-connector-java-3.0.15-ga-bin.jar</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">拷贝到</SPAN><SPAN lang=EN-US>${lib.dir}</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，也就是</SPAN><SPAN lang=EN-US>Middlegen-Hibernate-r5\lib</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">目录。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">修改配置文件中的数据库连接项目</SPAN><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto">database.url</SPAN><SPAN style="BACKGROUND: #d9d9d9; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 auto">、</SPAN><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto">database.userid</SPAN><SPAN style="BACKGROUND: #d9d9d9; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-shading: white; mso-pattern: gray-15 auto">、</SPAN><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto">database.userid</SPAN><SPAN lang=EN-US> </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使</SPAN><SPAN lang=EN-US>Middlegen-Hibernate</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以找到数据库。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><SPAN lang=EN-US>2.2 </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">配置</SPAN><SPAN lang=EN-US>Middlegen-Hibernate-r5</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</SPAN><SPAN lang=EN-US>ant</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">运行文件</SPAN><SPAN lang=EN-US>build.xml</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2>&lt;!DOCTYPE project [<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>&lt;!ENTITY database SYSTEM "file:./config/database/<SPAN style="COLOR: red">mysql.xml</SPAN>"&gt;<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2>]&gt;<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=2>指出使用的数据库配置文件。</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2>&lt;project name="Middlegen Hibernate" default="all" basedir="."&gt;<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN>&lt;property file="${basedir}/build.properties"/&gt;<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN>&lt;property name="name" value="<SPAN style="COLOR: red">hibernatesample</SPAN>"/&gt;<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><FONT size=2>指出你的应用名称。</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp; </SPAN>&lt;property name="build.gen-src.dir"<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>value="<SPAN style="COLOR: red">C:/sample</SPAN>"/&gt;<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">指出</SPAN><SPAN lang=EN-US>hbm</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的输出路径。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>&lt;hibernate<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>destination="${build.gen-src.dir}"<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>package="<SPAN style="COLOR: red">org.hibernate.sample</SPAN>"<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: red">genXDocletTags="false"<o:p></o:p></SPAN></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;</SPAN>genIntergratedCompositeKeys="false"<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>javaTypeMapper="middlegen.plugins.hibernate.HibernateJavaTypeMapper"<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>/&gt;<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">指出</SPAN><SPAN lang=EN-US>hbm</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">所在的包的位置。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">指出</SPAN><SPAN lang=EN-US>hbm.xml</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中是否需要</SPAN><SPAN lang=EN-US>XDoclet Tags</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US><o:p></o:p></SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><FONT size=2><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">3、<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">运行</SPAN><SPAN lang=EN-US>Middlegen-Hibernate:</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</SPAN><SPAN lang=EN-US>Middlegen-Hibernate</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">目录下运行</SPAN><SPAN lang=EN-US>ant</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，进入</SPAN><SPAN lang=EN-US>Middlegen-Hibernate</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的图形界面。可以设置表，和字段的特性。然后按</SPAN><SPAN lang=EN-US>Genarate</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，产生</SPAN><SPAN lang=EN-US>hbm.xml</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1; tab-stops: list 18.0pt"><FONT size=2><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">4、<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">配置</SPAN><SPAN lang=EN-US>hibernate-extensions</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</SPAN><SPAN lang=EN-US>hibernate-extensions-2.1.2\tools\bin</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">目录有一个</SPAN><SPAN lang=EN-US>setenv.bat</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件，改变其内容为：</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2>set JDBC_DRIVER=<SPAN style="COLOR: red">C:\java\Middlegen-Hibernate-r5\lib\mysql-connector-java-3.0.15-ga-bin.jar</SPAN><o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2>set HIBERNATE_HOME=<SPAN style="COLOR: red">C:\java\hibernate-2.1.6</SPAN><o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><o:p><FONT size=2>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2>set CORELIB=%HIBERNATE_HOME%\lib<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2>set LIB=..\lib<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2>set PROPS=%HIBERNATE_HOME%\src<o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="BACKGROUND: #d9d9d9; mso-shading: white; mso-pattern: gray-15 auto"><FONT size=2>set CP=%JDBC_DRIVER%;%PROPS%;%HIBERNATE_HOME%\hibernate2.jar;%CORELIB%\<SPAN style="COLOR: red">commons-logging-1.0.4.jar</SPAN>;%CORELIB%\<SPAN style="COLOR: red">commons-collections-2.1.1.jar</SPAN>;%CORELIB%\<SPAN style="COLOR: red">commons-lang-1.0.1.jar</SPAN>;%CORELIB%\<SPAN style="COLOR: red">cglib-full-2.0.2.jar</SPAN>;%CORELIB%\<SPAN style="COLOR: red">dom4j-1.4.jar;</SPAN>%CORELIB%\<SPAN style="COLOR: red">odmg-3.0.jar</SPAN>;%CORELIB%\<SPAN style="COLOR: red">xml-apis.jar</SPAN>;%CORELIB%\<SPAN style="COLOR: red">xerces-2.4.0.jar</SPAN>;%CORELIB%\<SPAN style="COLOR: red">xalan-2.4.0.jar</SPAN>;%LIB%\<SPAN style="COLOR: red">jdom.jar</SPAN>;%LIB%\..\<SPAN style="COLOR: red">hibernate-tools.jar</SPAN><o:p></o:p></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">注意红色字体提示的均是路径和</SPAN><SPAN lang=EN-US>JAR</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件名，一定要正确。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><SPAN lang=EN-US>5</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、运行</SPAN><SPAN lang=EN-US>hibernate-extensions</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，根据</SPAN><SPAN lang=EN-US>hbm.xml</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">产生</SPAN><SPAN lang=EN-US>POJO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</SPAN><SPAN lang=EN-US>DOS</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中运行</SPAN><SPAN lang=EN-US>hbm2java c:\sample\org\hibernate\sample\*.xml --output=c:\sample\<o:p></o:p></SPAN></FONT></P><B><BR></B><img src ="http://www.blogjava.net/relax/aggbug/1588.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/relax/" target="_blank">轻松</a> 2005-03-01 14:43 <a href="http://www.blogjava.net/relax/archive/2005/03/01/1588.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>