﻿<?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/wanghun723/category/39597.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 18 May 2009 20:43:06 GMT</lastBuildDate><pubDate>Mon, 18 May 2009 20:43:06 GMT</pubDate><ttl>60</ttl><item><title>Hibernate Gossip: 樂觀鎖定（Optimistic locking）</title><link>http://www.blogjava.net/wanghun723/articles/270897.html</link><dc:creator>L.J.</dc:creator><author>L.J.</author><pubDate>Fri, 15 May 2009 09:07:00 GMT</pubDate><guid>http://www.blogjava.net/wanghun723/articles/270897.html</guid><wfw:comment>http://www.blogjava.net/wanghun723/comments/270897.html</wfw:comment><comments>http://www.blogjava.net/wanghun723/articles/270897.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wanghun723/comments/commentRss/270897.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wanghun723/services/trackbacks/270897.html</trackback:ping><description><![CDATA[悲觀鎖定假定任何時刻存取資料時，都可能有另一個客戶也正在存取同一筆資料，因而對資料採取了資料庫層次的鎖定狀態，在鎖定的時間內其他的客戶不能對資料進行存取，對於單機或小系統而言，這並不成問題，然而如果是在網路上的系統，同時間會有許多連線，如果每一次讀取資料都造成鎖定，其後繼的存取就必須等待，這將造成效能上的問題，造成後繼使用者的長時間等待。 <br />
<br />
樂觀鎖定（Optimistic locking）則樂觀的認為資料的存取很少發生同時存取的問題，因而不作資料庫層次上的鎖定，為了維護正確的資料，樂觀鎖定使用應用程式上的邏輯實現版本控制的解決。 <br />
<br />
在不實行悲觀鎖定策略的情況下，資料不一致的情況一但發生，有幾個解決的方法，一種是先更新為主，一種是後更新的為主，比較複雜的就是檢查發生變動的資料來實現，或是檢查所有屬性來實現樂觀鎖定。 <br />
<br />
Hibernate中透過版本號檢查來實現後更新為主，這也是Hibernate所推薦的方式，在資料庫中加入一個version欄位記錄，在讀取資料時連同版本號一同讀取，並在更新資料時比對版本號與資料庫中的版本號，如果等於資料庫中的版本號則予以更新，並遞增版本號，如果小於資料庫中的版本號就丟出例外。<br />
<br />
實際來透過範例瞭解Hibernate的樂觀鎖定如何實現，首先在資料庫中新增一個表格：<br />
<div style="margin-left: 40px; font-family: Courier New,Courier,monospace"><span style="font-weight: bold">CREATE TABLE user (</span><br style="font-weight: bold" />
<span style="font-weight: bold">&nbsp; &nbsp; id INT(11) NOT NULL auto_increment PRIMARY KEY,</span><br style="font-weight: bold" />
<span style="font-weight: bold">&nbsp; &nbsp; version INT,</span><br style="font-weight: bold" />
<span style="font-weight: bold">&nbsp; &nbsp; name VARCHAR(100) NOT NULL default '',</span><br style="font-weight: bold" />
<span style="font-weight: bold">&nbsp; &nbsp; age INT</span><br style="font-weight: bold" />
<span style="font-weight: bold">);</span><br />
</div>
<br />
這個user表格中的version用來記錄版本號，以供Hibernate實現樂觀鎖定，接著設計User類別，當中必須包括version屬性：<br />
<ul>
    <li>User.java </li>
</ul>
<pre>package onlyfun.caterpillar;<br />
<br />
public class User {<br />
private Integer id;<br />
<span style="font-weight: bold">    private Integer version; // 增加版本屬性   </span><br />
private String name;<br />
private Integer age;<br />
<br />
public User() {<br />
}<br />
<br />
public Integer getId() {<br />
return id;<br />
}<br />
<br />
public void setId(Integer id) {<br />
this.id = id;<br />
}<br />
<br />
public Integer getVersion() {<br />
return version;<br />
}<br />
<br />
public void setVersion(Integer version) {<br />
this.version = version;<br />
}<br />
<br />
public String getName() {<br />
return name;<br />
}<br />
<br />
public void setName(String name) {<br />
this.name = name;<br />
}<br />
<br />
public Integer getAge() {<br />
return age;<br />
}<br />
<br />
public void setAge(Integer age) {<br />
this.age = age;<br />
}<br />
}</pre>
<br />
在映射文件的定義方面，則如下所示：<br />
<ul>
    <li>User.hbm.xml </li>
</ul>
<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt; <br />
&lt;!DOCTYPE hibernate-mapping <br />
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" <br />
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"&gt; <br />
<br />
&lt;hibernate-mapping&gt; <br />
<br />
&lt;class name="onlyfun.caterpillar.User" <br />
table="user"<br />
<span style="font-weight: bold">optimistic-lock="version"</span>&gt; <br />
<br />
&lt;id name="id" column="id" type="java.lang.Integer"&gt; <br />
&lt;generator class="native"/&gt; <br />
&lt;/id&gt; <br />
<br />
<span style="font-weight: bold">        &lt;version name="version" </span><br style="font-weight: bold" />
<span style="font-weight: bold">                 column="version"</span><br style="font-weight: bold" />
<span style="font-weight: bold">                 type="java.lang.Integer"/&gt; </span><br />
<br />
&lt;property name="name" column="name" type="java.lang.String"/&gt; <br />
<br />
&lt;property name="age" column="age" type="java.lang.Integer"/&gt; <br />
<br />
&lt;/class&gt; <br />
<br />
&lt;/hibernate-mapping&gt;</pre>
<br />
注意&lt;version&gt;標籤必須出現在&lt;id&gt;標籤之後，接著您可以試著在資料庫中新增資料，例如：<br />
<div style="margin-left: 40px"><span style="font-weight: bold; font-family: Courier New,Courier,monospace">User user = new User(); </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace" />
<span style="font-weight: bold; font-family: Courier New,Courier,monospace">user.setName("caterpillar"); </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace" />
<span style="font-weight: bold; font-family: Courier New,Courier,monospace">user.setAge(new Integer(30)); </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace" />
<span style="font-weight: bold; font-family: Courier New,Courier,monospace">Session session = sessionFactory.openSession();</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace" />
<span style="font-weight: bold; font-family: Courier New,Courier,monospace">Transaction tx =&nbsp; session.beginTransaction();</span><br style="font-weight: bold; font-family: Courier New,Courier,monospace" />
<span style="font-weight: bold; font-family: Courier New,Courier,monospace">session.save(user); </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace" />
<span style="font-weight: bold; font-family: Courier New,Courier,monospace">tx.commit(); </span><br style="font-weight: bold; font-family: Courier New,Courier,monospace" />
<span style="font-weight: bold; font-family: Courier New,Courier,monospace">session.close();</span><br />
</div>
<br />
<span class="postbody">您可以檢視資料庫中的資料，每一次對同一筆資料進行更新，version欄位的內容都會自動更新，接著來作個實驗，直接以範例說明：<br />
</span>
<div style="margin-left: 40px; font-family: Courier New,Courier,monospace"><span class="postbody" style="font-weight: bold">// 有使用1者開啟了一個session1</span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">Session session1 = sessionFactory.openSession();</span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">// 在這之後，馬上有另一個使用者2開啟了session2</span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">Session session2 = sessionFactory.openSession();</span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">Integer id = new Integer(1);</span><br style="font-weight: bold" />
<br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">// 使用者1查詢資料 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">User userV1 = (User) session1.load(User.class, id);</span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">// 使用者2查詢同一筆資料</span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">User userV2 = (User) session2.load(User.class, id);</span><br style="font-weight: bold" />
<br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">// 此時兩個版本號是相同的</span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">System.out.println(" v1 v2 " </span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + userV1.getVersion().intValue() + " " </span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + userV2.getVersion().intValue());</span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">Transaction tx1 = session1.beginTransaction();</span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">Transaction tx2 = session2.beginTransaction();</span><br style="font-weight: bold" />
<br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">// 使用者1更新資料 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">userV1.setAge(new Integer(31));</span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">tx1.commit();</span><br style="font-weight: bold" />
<br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">// 此時由於資料更新，資料庫中的版本號遞增了</span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">// 兩筆資料版本號不一樣了</span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">System.out.println(" v1 v2 " </span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + userV1.getVersion().intValue() + " " </span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + userV2.getVersion().intValue());</span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">// userV2 的 age 資料還是舊的 </span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">//&nbsp;資料更新</span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">userV2.setName("justin");</span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">// 因版本號比資料庫中的舊</span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">// 送出更新資料會失敗，丟出</span><span style="font-weight: bold">StableObjectStateException例外</span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">tx2.commit();</span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">session1.close();</span><br style="font-weight: bold" />
<span class="postbody" style="font-weight: bold">session2.close();</span><br />
</div>
<span class="postbody"><br />
運行以下的程式片段，會出現以下的結果：<br />
</span>
<div style="margin-left: 40px; font-family: Courier New,Courier,monospace"><span class="postbody"><span style="font-weight: bold">Hibernate: select user0_.id as id0_, user0_.version as version0_0_, user0_.name as name0_0_, user0_.age as age0_0_ from user user0_ where user0_.id=?</span></span><br style="font-weight: bold" />
<span class="postbody"><span style="font-weight: bold">Hibernate: select user0_.id as id0_, user0_.version as version0_0_, user0_.name as name0_0_, user0_.age as age0_0_ from user user0_ where user0_.id=?</span></span><br style="font-weight: bold" />
<span class="postbody"><span style="font-weight: bold">&nbsp;v1 v2 0 0</span></span><br style="font-weight: bold" />
<span class="postbody"><span style="font-weight: bold">Hibernate: update user set version=?, name=?, age=? where id=? and version=?</span></span><br style="font-weight: bold" />
<span class="postbody"><span style="font-weight: bold">&nbsp;v1 v2 1 0</span></span><br style="font-weight: bold" />
<span class="postbody"><span style="font-weight: bold">Hibernate: update user set version=?, name=?, age=? where id=? and version=?</span></span><br style="font-weight: bold" />
<span class="postbody" style="color: rgb(255,0,0)"><span style="font-weight: bold">16:11:43,187 ERROR AbstractFlushingEventListener:277 - Could not synchronize database state with session</span></span><br style="font-weight: bold; color: rgb(255,0,0)" />
<span class="postbody" style="color: rgb(255,0,0)"><span style="font-weight: bold">org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [onlyfun.caterpillar.User#1]</span></span><br style="font-weight: bold; color: rgb(255,0,0)" />
<span class="postbody" style="color: rgb(255,0,0)"><span style="font-weight: bold">&nbsp;&nbsp;&nbsp; at org.hibernate.persister.entity.BasicEntityPersister.check(BasicEntityPersister.java:1441)</span></span><br />
</div>
<span class="postbody"><span style="font-family: Courier New,Courier,monospace">&nbsp;</span><br />
由於新的版本號是1，而userV2的版本號還是0，因此更新失敗丟出StableObjectStateException，您可以捕捉這個例外作善後處理，例如在處理中重新讀取資料庫中的資料，同時將目前的資料與資料庫中的資料秀出來，讓使用者有機會比對不一致的資料，以決定要變更的部份，或者您可以設計程式自動讀取新的資料，並比對真正要更新的資料，這一切可以在背景執行，而不用讓您的使用者知道。 <br />
<br />
要注意的是，由於樂觀鎖定是使用系統中的程式來控制，而不是使用資料庫中的鎖定機制，因而如果有人特意自行更新版本訊息來越過檢查，則鎖定機制就會無效，例如在上例中自行更改userV2的version屬性，使之與資料庫中的版本號相同的話就不會有錯誤，像這樣版本號被更改，或是由於資料是由外部系統而來，因而版本資訊不受控制時，鎖定機制將會有問題，設計時必須注意。<br />
</span>
<img src ="http://www.blogjava.net/wanghun723/aggbug/270897.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wanghun723/" target="_blank">L.J.</a> 2009-05-15 17:07 <a href="http://www.blogjava.net/wanghun723/articles/270897.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate每个jar包的作用</title><link>http://www.blogjava.net/wanghun723/articles/270895.html</link><dc:creator>L.J.</dc:creator><author>L.J.</author><pubDate>Fri, 15 May 2009 09:05:00 GMT</pubDate><guid>http://www.blogjava.net/wanghun723/articles/270895.html</guid><wfw:comment>http://www.blogjava.net/wanghun723/comments/270895.html</wfw:comment><comments>http://www.blogjava.net/wanghun723/articles/270895.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wanghun723/comments/commentRss/270895.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wanghun723/services/trackbacks/270895.html</trackback:ping><description><![CDATA[Hibernate一共包括了23个jar包，令人眼花缭乱。<br />
　　下载Hibernate，例如2.0.3稳定版本，解压缩，可以看到一个hibernate2.jar和lib目录下有22个jar包： <br />
<br />
　　hibernate2.jar: <br />
　　Hibernate的库，没有什么可说的，必须使用的jar包 <br />
<br />
　　cglib-asm.jar: <br />
　　CGLIB库，Hibernate用它来实现PO字节码的动态生成，非常核心的库，必须使用的jar包 <br />
<br />
　　dom4j.jar: <br />
　　dom4j是一个Java的XML API，类似于jdom，用来读写XML文件的。dom4j是一个非常非常优秀的Java XML API，具有性能优异、功能强大和极端易用使用的特点，同时它也是一个开放源代码的软件，可以在SourceForge上找到它。在IBM developerWorks上面可以找到一篇文章，对主流的Java XML API进行的性能、功能和易用性的评测，dom4j无论在那个方面都是非常出色的。我早在将近两年之前就开始使用dom4j，直到现在。如今你可以看到越来越多的Java软件都在使用dom4j来读写XML，特别值得一提的是连Sun的JAXM也在用dom4j。这是必须使用的jar包，Hibernate用它来读写配置文件。 <br />
<br />
　　odmg.jar: <br />
　　ODMG是一个ORM的规范，Hibernate实现了ODMG规范，这是一个核心的库，必须使用的jar包。 <br />
<br />
　　commons-collections.jar： <br />
　　Apache Commons包中的一个，包含了一些Apache开发的集合类，功能比java.util.*强大。必须使用的jar包。 <br />
<br />
　　commons-beanutils.jar： <br />
　　Apache Commons包中的一个，包含了一些Bean工具类类。必须使用的jar包。 <br />
<br />
　　commons-lang.jar: <br />
　　Apache Commons包中的一个，包含了一些数据类型工具类，是java.lang.*的扩展。必须使用的jar包。 <br />
<br />
　　commons-logging.jar: <br />
　　Apache Commons包中的一个，包含了日志功能，必须使用的jar包。这个包本身包含了一个Simple Logger，但是功能很弱。在运行的时候它会先在CLASSPATH找log4j，如果有，就使用log4j，如果没有，就找JDK1.4带的java.util.logging，如果也找不到就用Simple Logger。commons-logging.jar的出现是一个历史的的遗留的遗憾，当初Apache极力游说Sun把log4j加入JDK1.4，然而JDK1.4项目小组已经接近发布JDK1.4产品的时间了，因此拒绝了Apache的要求，使用自己的java.util.logging，这个包的功能比log4j差的很远，性能也一般。<br />
<br />
　　后来Apache就开发出来了commons-logging.jar用来兼容两个logger。因此用commons-logging.jar写的log程序，底层的Logger是可以切换的，你可以选择log4j，java.util.logging或者它自带的Simple Logger。不过我仍然强烈建议使用log4j，因为log4j性能很高，log输出信息时间几乎等于System.out，而处理一条log平均只需要5us。你可以在Hibernate的src目录下找到Hibernate已经为你准备好了的log4j的配置文件，你只需要到Apache 网站去下载log4j就可以了。commons-logging.jar也是必须的jar包。 <br />
<br />
　　使用Hibernate必须的jar包就是以上的这几个，剩下的都是可选的。 <br />
<br />
　　ant.jar: <br />
　　Ant编译工具的jar包，用来编译Hibernate源代码的。如果你不准备修改和编译Hibernate源代码，那么就没有什么用，可选的jar包 <br />
<br />
　　optional.jar： <br />
　　Ant的一个辅助包。 <br />
<br />
　　c3p0.jar： <br />
　　C3PO是一个数据库连接池，Hibernate可以配置为使用C3PO连接池。如果你准备用这个连接池，就需要这个jar包。 <br />
<br />
　　proxool.jar： <br />
　　也是一个连接池，同上。 <br />
<br />
　　commons-pool.jar, commons-dbcp.jar: <br />
　　DBCP数据库连接池，Apache的Jakarta组织开发的，Tomcat4的连接池也是DBCP。 <br />
<br />
　　实际上Hibernate自己也实现了一个非常非常简单的数据库连接池，加上上面3个，你实际上可以在Hibernate上选择4种不同的数据库连接池，选择哪一个看个人的偏好，不过DBCP可能更通用一些。另外强调一点，如果在EJB中使用Hibernate，一定要用App Server的连接池，不要用以上4种连接池，否则容器管理事务不起作用。 <br />
<br />
　　connector.jar: <br />
　　JCA 规范，如果你在App Server上把Hibernate配置为Connector的话，就需要这个jar。不过实际上一般App Server肯定会带上这个包，所以实际上是多余的包。 <br />
<br />
　　jaas.jar: <br />
　　JAAS是用来进行权限验证的，已经包含在JDK1.4里面了。所以实际上是多余的包。 <br />
<br />
　　jcs.jar： <br />
　　如果你准备在Hibernate中使用JCS的话，那么必须包括它，否则就不用。 <br />
<br />
　　jdbc2_0-stdext.jar: <br />
　　JDBC2.0的扩展包，一般来说数据库连接池会用上它。不过App Server都会带上，所以也是多余的。 <br />
<br />
　　jta.jar： <br />
　　JTA规范，当Hibernate使用JTA的时候需要，不过App Server都会带上，所以也是多余的。 <br />
<br />
　　junit.jar: <br />
　　Junit包，当你运行Hibernate自带的测试代码的时候需要，否则就不用。 <br />
<br />
　　xalan.jar, xerces.jar, xml-apis.jar: <br />
　　Xerces是XML解析器，Xalan是格式化器，xml-apis实际上是JAXP。一般App Server都会带上，JDK1.4也包含了解析器，不过不是Xerces，是Crimson，效率比较差，不过Hibernate用XML只不过是读取配置文件，性能没什么紧要的，所以也是多余的。
<img src ="http://www.blogjava.net/wanghun723/aggbug/270895.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wanghun723/" target="_blank">L.J.</a> 2009-05-15 17:05 <a href="http://www.blogjava.net/wanghun723/articles/270895.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>NHibernate集合映射中的set, list, map, bag, array</title><link>http://www.blogjava.net/wanghun723/articles/270894.html</link><dc:creator>L.J.</dc:creator><author>L.J.</author><pubDate>Fri, 15 May 2009 09:03:00 GMT</pubDate><guid>http://www.blogjava.net/wanghun723/articles/270894.html</guid><wfw:comment>http://www.blogjava.net/wanghun723/comments/270894.html</wfw:comment><comments>http://www.blogjava.net/wanghun723/articles/270894.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wanghun723/comments/commentRss/270894.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wanghun723/services/trackbacks/270894.html</trackback:ping><description><![CDATA[<br />
另外Iesi.Collections中的SortedSet允许提供一个IComparer接口，这样在列举集合对象时将按照IComparer提供的方法排序。<br />
<br />
bag:<br />
跟set基本一样，唯一不同之处在于bag中允许重复对象。<br />
.Net没有原生的bag类，PowerCollections中有bag实现。<br />
<br />
list:<br />
有序集合，可以重复，使用从0开始的整数作为索引。<br />
.Net中的List、ArrayList、LinkedList等，ArrayList用数组实现，LinkedList用双向链表实现。<br />
<br />
map:<br />
无序集合，key值不可以重复，可以使用任意类型的对象作为索引。<br />
.Net中的map类有Dictionary、SortedDictionary、HashTable、SortedList等，SortedDictionary提供了排序支持。<br />
Java中的map有HashMap和SortedMap。<br />
<strong><br />
set, bag, list, map语义与System.Collections的对应关系</strong><br />
在System.Collections下面，IList跟list语义一致，IDictionary跟map语义一致。对于具体实现类，根据它们实现的接口来确定跟set, bag, list, map语义的对应关系。<br />
例如上面提到SortedList现了IDictionary接口，因此是一个map实现，这使得它的名字跟语义不符。<br />
ICollection接口对语义没有明确声明，完全由具体类的实现决定属于哪种语义。抽象类CollectionBase实现了IList、ICollection接口，因此是list语义。PowerCollections中的Bag&lt;T&gt;是基于ICollection实现bag语义。<br />
<br />
<strong>集合映射中实体（Entity）跟值对象（Value Object）的区别</strong><br />
实体拥有独立的生命周期，拥有自己的实体标识（Entity Identifier）；而值对象的生命周期完全依附于它所属的实体，没有自己的标识（Identifier）。<br />
最基本的值类型是.Net原生的那些value types，业务中简单的值对象常见的如Money、欧美风格的姓名等。复杂的业务中实体跟值对象有时候很难区分，并且同一个概念对象在不同系统环境中也可能不一样，例如在专业的地理信息处理系统中，地址可能是实体，而对于其它系统例如ERP、人力资源管理等，地址可能是值对象。<br />
一些简单的原则可以用于区分实体跟值对象：<br />
1. 生命周期。值对象不能脱离它所属的实体而存在，它在实体创建时或之后被创建，跟随所属的实体一起被销毁。这个生命周期是针对业务面而言，如果用内存中对象的生命周期去理解就会有疑惑，因此结合数据库中的记录（即持久化状态的对象）来理解这个生命周期概念更直观。<br />
2. 共享引用。值对象不能被共享引用。以地址为例，如果user A和user B都有一个地址并且是一样的，设计为值对象时地址表中会有两条记录，一条属于user A一条属于user B，设计为实体时地址表中只有一条记录，user A跟user B都通过地址对象的标识引用。应该采用哪种方案看具体的业务需要。<br />
粗糙的设计将值对象和实体一视同仁，稍微细致一点的设计就会出现不少值对象。<br />
NHibernate中，&lt;set&gt;, &lt;bag&gt;, &lt;list&gt;, &lt;map&gt;等与&lt;element&gt;、&lt;composite-element&gt;结合，完成值对象的集合映射；one-to-one, many-to-one, one-to-many, many-to-many的出现则意味着实体间的关联关系。<br />
值对象的集合映射不需要cascade，因为它的生命周期原则在定义中就已经确定了，cascade只用于实体间的生命周期关联控制。<br />
集合映射中，值对象跟实体保存在不同的表中，但值对象不需要独立的配置文件，在实体映射文件中通过&lt;set&gt;, &lt;bag&gt;, &lt;list&gt;, &lt;map&gt;已经完全描述清楚了。而实体间的one-to-one, many-to-one, one-to-many, many-to-many关联，每个实体都拥有自己的配置文件。<br />
<br />
<strong>&lt;set&gt;, &lt;bag&gt;, &lt;list&gt;, &lt;map&gt;的使用</strong><br />
首先根据语义从&lt;set&gt;, &lt;bag&gt;, &lt;list&gt;, &lt;map&gt;中选择合适的映射配置节点。下表是配置节点与接口类型对应关系：<br />
<table class="mytable" cellspacing="0" cellpadding="0">
    <tbody>
        <tr>
            <td class="mytd" width="180"><em><strong>Mapping Node</strong></em></td>
            <td class="mytd"><em><strong>Interface</strong></em></td>
        </tr>
        <tr>
            <td class="mytd">&lt;set&gt;</td>
            <td class="mytd">Iesi.Collections.ISet</td>
        </tr>
        <tr>
            <td class="mytd">&lt;bag&gt;</td>
            <td class="mytd">IList</td>
        </tr>
        <tr>
            <td class="mytd">&lt;list&gt;</td>
            <td class="mytd">IList</td>
        </tr>
        <tr>
            <td class="mytd">&lt;map&gt;</td>
            <td class="mytd">IDictionary</td>
        </tr>
    </tbody>
</table>
对应的集合属性必须使用接口声明，因为NHibernate返回的集合对象类型，是它内部对这些接口的实现，即NHibernate.Collection命名空间下的PersistentSet、PersistentList、PersistentBag、PersistentMap，而不是ListSet、HashTable等。按照NHibernate的规定使用这些接口的具体类，NHibernate在存取时能够自动转换处理。<br />
.Net中没有set和bag的实现，所以NHibernate使用Iesi.Collections的set，使用IList模拟bag语义。<br />
如果属性不希望使用这些接口，可以使用access。将field设置为接口类型，在property的get, set方法中完成类型转换，通过属性配置中的access设置，让NHibernate绕开get, set方法直接存取field。<br />
<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #0000ff">&lt;</span><span style="color: #800000">set </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="Addresses"</span><span style="color: #ff0000"> table</span><span style="color: #0000ff">="USER_ADDRESS"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">key </span><span style="color: #ff0000">column</span><span style="color: #0000ff">="USER_ID"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">element </span><span style="color: #ff0000">column</span><span style="color: #0000ff">="ADDRESS"</span><span style="color: #ff0000"> type</span><span style="color: #0000ff">="String"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">set</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">set </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="Addresses"</span><span style="color: #ff0000"> table</span><span style="color: #0000ff">="USER_ADDRESS"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">key </span><span style="color: #ff0000">column</span><span style="color: #0000ff">="USER_ID"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">composite-element </span><span style="color: #ff0000">class</span><span style="color: #0000ff">="Address"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">property </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="Country"</span><span style="color: #ff0000"> column</span><span style="color: #0000ff">="COUNTRY"</span><span style="color: #ff0000"> type</span><span style="color: #0000ff">="String"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">property </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="Province"</span><span style="color: #ff0000"> column</span><span style="color: #0000ff">="PROVINCE"</span><span style="color: #ff0000"> type</span><span style="color: #0000ff">="String"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">property </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="ZipCode"</span><span style="color: #ff0000"> column</span><span style="color: #0000ff">="ZIP_CODE"</span><span style="color: #ff0000"> type</span><span style="color: #0000ff">="String"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">property </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="AddressText"</span><span style="color: #ff0000"> column</span><span style="color: #0000ff">="ADDRESS_TEXT"</span><span style="color: #ff0000"> type</span><span style="color: #0000ff">="String"</span><span style="color: #ff0000"> </span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">composite-element</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">set</span><span style="color: #0000ff">&gt;</span></div>
上面是值对象的集合映射，如果是实体间的集合映射，可以在&lt;set&gt;里面使用&lt;many-to-many&gt;, &lt;one-to-many&gt;。<br />
<br />
&lt;bag&gt;的用法跟&lt;set&gt;完全一样，它们只是在语义上有区别而已。<br />
<br />
&lt;list&gt;因为是有序集合，所以必须要有一个整数型索引字段，保证数据在物理存储上的顺序，这个字段的值NHibernate自动维护。其它的跟&lt;set&gt;完全一样。<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #0000ff">&lt;</span><span style="color: #800000">list </span><span style="color: #ff0000">name</span><span style="color: #0000ff">="Addresses"</span><span style="color: #ff0000"> table</span><span style="color: #0000ff">="USER_ADDRESS"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">key </span><span style="color: #ff0000">column</span><span style="color: #0000ff">="USER_ID"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">index </span><span style="color: #ff0000">column</span><span style="color: #0000ff">="ADDR_INDEX"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">element </span><span style="color: #ff0000">column</span><span style="color: #0000ff">="ADDRESS"</span><span style="color: #ff0000"> type</span><span style="color: #0000ff">="String"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">list</span><span style="color: #0000ff">&gt;</span></div>
<br />
&lt;map&gt;与&lt;list&gt;的区别在于，&lt;list&gt;的index是整型，而&lt;map&gt;的index可以为任意类型，所以&lt;map&gt;中的&lt;index&gt;节点可以指定type属性。有的情况下，可能通过关联使用其它实体作为index，因此NHibernate为&lt;map&gt;提供了另外一种index配置方式，&lt;index-many-to-many&gt;和&lt;index-many-to-any&gt;。其它配置跟&lt;set&gt;一样。<br />
<br />
<strong>集合元素的顺序</strong><br />
&lt;set&gt;, &lt;bag&gt;, &lt;map&gt;数据的存储是无序的，在获取数据的时候NHibernate支持排序。排序方法有两种，sort和order-by，详细用法参考NHibernate考察系列 03 many-to-many 集合映射 http://www.cnblogs.com/RicCC/archive/2007/04/08/704557.html。<br />
加载时的排序与list的按照顺序存储有一定差异，list可以完全保留添加到集合中的顺序，而加载时的排序都是固定的规则，因此并不是完全可替代的方案。<br />
<br />
<strong>&lt;idbag&gt;</strong><br />
&lt;many-to-many&gt;和值对象的集合映射，关联表跟值对象表都没有自己的标识字段，&lt;idbag&gt;就是用于需要使用标识字段的情况。
<img src ="http://www.blogjava.net/wanghun723/aggbug/270894.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wanghun723/" target="_blank">L.J.</a> 2009-05-15 17:03 <a href="http://www.blogjava.net/wanghun723/articles/270894.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate jar包详解</title><link>http://www.blogjava.net/wanghun723/articles/270892.html</link><dc:creator>L.J.</dc:creator><author>L.J.</author><pubDate>Fri, 15 May 2009 09:00:00 GMT</pubDate><guid>http://www.blogjava.net/wanghun723/articles/270892.html</guid><wfw:comment>http://www.blogjava.net/wanghun723/comments/270892.html</wfw:comment><comments>http://www.blogjava.net/wanghun723/articles/270892.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wanghun723/comments/commentRss/270892.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wanghun723/services/trackbacks/270892.html</trackback:ping><description><![CDATA[<p align="left">Hibernate一共包括了23个jar包，令人眼花缭乱。下载Hibernate，例如2.0.3稳定版本，解压缩，可以看到一个hibernate2.jar和lib目录下有22个jar包： <br />
<br />
<font color="#0000ff">（1）hibernate2.jar:</font> <br />
　　Hibernate的库，没有什么可说的，必须使用的jar包 <br />
<br />
<font color="#0000ff">（2）cglib-asm.jar:</font> <br />
　　CGLIB库，Hibernate用它来实现PO字节码的动态生成，非常核心的库，必须使用的jar包 <br />
<br />
<font color="#0000ff">（3）dom4j.jar:</font> <br />
　　dom4j是一个Java的XML API，类似于jdom，用来读写XML文件的。dom4j是一个非常非常优秀的Java XML API，具有性能优异、功能强大和极端易用使用的特点，同时它也是一个开放源代码的软件，可以在SourceForge上找到它。在IBM developerWorks上面可以找到一篇文章，对主流的Java XML API进行的性能、功能和易用性的评测，dom4j无论在那个方面都是非常出色的。我早在将近两年之前就开始使用dom4j，直到现在。如今你可以看到越来越多的Java软件都在使用dom4j来读写XML，特别值得一提的是连Sun的JAXM也在用dom4j。这是必须使用的jar包，Hibernate用它来读写配置文件。 <br />
<br />
<font color="#0000ff">（4）odmg.jar:</font> <br />
　　ODMG是一个ORM的规范，Hibernate实现了ODMG规范，这是一个核心的库，必须使用的jar包。 <br />
<br />
<font color="#0000ff">（5）commons-collections.jar： <br />
</font>　　Apache Commons包中的一个，包含了一些Apache开发的集合类，功能比java.util.*强大。必须使用的jar包。 <br />
<br />
<font color="#ff0000"><font color="#0000ff">（6）commons-beanutils.jar：</font> <br />
</font>　　Apache Commons包中的一个，包含了一些Bean工具类类。必须使用的jar包。 <br />
<br />
<font color="#0000ff">（7）commons-lang.jar:</font> <br />
　　Apache Commons包中的一个，包含了一些数据类型工具类，是java.lang.*的扩展。必须使用的jar包。 <br />
<br />
<font color="#0000ff">（8）commons-logging.jar: </font><br />
　　Apache Commons包中的一个，包含了日志功能，必须使用的jar包。这个包本身包含了一个Simple Logger，但是功能很弱。在运行的时候它会先在CLASSPATH找log4j，如果有，就使用log4j，如果没有，就找JDK1.4带的java.util.logging，如果也找不到就用Simple Logger。commons-logging.jar的出现是一个历史的的遗留的遗憾，当初Apache极力游说Sun把log4j加入JDK1.4，然而JDK1.4项目小组已经接近发布JDK1.4产品的时间了，因此拒绝了Apache的要求，使用自己的java.util.logging，这个包的功能比log4j差的很远，性能也一般。<br />
<br />
　　后来Apache就开发出来了commons-logging.jar用来兼容两个logger。因此用commons-logging.jar写的log程序，底层的Logger是可以切换的，你可以选择log4j，java.util.logging或者它自带的Simple Logger。不过我仍然强烈建议使用log4j，因为log4j性能很高，log输出信息时间几乎等于System.out，而处理一条log平均只需要5us。你可以在Hibernate的src目录下找到Hibernate已经为你准备好了的log4j的配置文件，你只需要到Apache 网站去下载log4j就可以了。commons-logging.jar也是必须的jar包。 <br />
<br />
<font color="#ff00ff" size="4"><strong>使用Hibernate必须的jar包就是以上的这几个，剩下的都是可选的。 <br />
</strong></font><br />
　　ant.jar: <br />
　　Ant编译工具的jar包，用来编译Hibernate源代码的。如果你不准备修改和编译Hibernate源代码，那么就没有什么用，可选的jar包 <br />
<br />
　　optional.jar： <br />
　　Ant的一个辅助包。 <br />
<br />
　　c3p0.jar： <br />
　　C3PO是一个数据库连接池，Hibernate可以配置为使用C3PO连接池。如果你准备用这个连接池，就需要这个jar包。 <br />
<br />
　　proxool.jar： <br />
　　也是一个连接池，同上。 <br />
<br />
　　commons-pool.jar, commons-dbcp.jar: <br />
　　DBCP数据库连接池，Apache的Jakarta组织开发的，Tomcat4的连接池也是DBCP。 <br />
<br />
　　实际上Hibernate自己也实现了一个非常非常简单的数据库连接池，加上上面3个，你实际上可以在Hibernate上选择4种不同的数据库连接池，选择哪一个看个人的偏好，不过DBCP可能更通用一些。另外强调一点，如果在EJB中使用Hibernate，一定要用App Server的连接池，不要用以上4种连接池，否则容器管理事务不起作用。 <br />
<br />
　　connector.jar: <br />
　　JCA 规范，如果你在App Server上把Hibernate配置为Connector的话，就需要这个jar。不过实际上一般App Server肯定会带上这个包，所以实际上是多余的包。 <br />
<br />
　　jaas.jar: <br />
　　JAAS是用来进行权限验证的，已经包含在JDK1.4里面了。所以实际上是多余的包。 <br />
<br />
　　jcs.jar： <br />
　　如果你准备在Hibernate中使用JCS的话，那么必须包括它，否则就不用。 <br />
<br />
　　jdbc2_0-stdext.jar: <br />
　　JDBC2.0的扩展包，一般来说数据库连接池会用上它。不过App Server都会带上，所以也是多余的。 <br />
<br />
　　jta.jar： <br />
　　JTA规范，当Hibernate使用JTA的时候需要，不过App Server都会带上，所以也是多余的。 <br />
<br />
　　junit.jar: <br />
　　Junit包，当你运行Hibernate自带的测试代码的时候需要，否则就不用。 <br />
<br />
　　xalan.jar, xerces.jar, xml-apis.jar: <br />
　　Xerces是XML解析器，Xalan是格式化器，xml-apis实际上是JAXP。一般App Server都会带上，JDK1.4也包含了解析器，不过不是Xerces，是Crimson，效率比较差，不过Hibernate用XML只不过是读取配置文件，性能没什么紧要的，所以也是多余的。</p>
<p align="left">
<table style="table-layout: fixed">
    <tbody>
        <tr>
            <td>
            <div class="cnt"><a href="http://ant.apache.org/" target="_blank">ant-1.63.jar</a></div>
            <div class="cnt">http://ant.apache.org/&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; </div>
            <div class="cnt">Ant 的核心包,在构建Hibernate 时会用到</div>
            <div class="cnt"><br />
            <a href="http://www.antlr.org/" target="_blank">antlr-2.7.5H3.jar</a></div>
            <div class="cnt">http://www.antlr.org/&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; </div>
            <div class="cnt">语言转换工,Hibernate利用它实现 HQL 到 SQL的转换</div>
            <div class="cnt"><br />
            <a href="http://asm.objectweb.org/" target="_blank">asm.jar/asm-attrs.jar </a></div>
            <div class="cnt">http://asm.objectweb.org/&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; </div>
            <div class="cnt">ASM 字节转换库</div>
            <div class="cnt"><br />
            <a href="http://sourceforge.net/projects/c3p0" target="_blank">c3p0-0.8.5.2.jar</a></div>
            <div class="cnt">http://sourceforge.net/projects/c3p0&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </div>
            <div class="cnt">C3PO JDBC 连接池工具</div>
            <div class="cnt"><br />
            <a href="http://cglib.sourceforge.net/" target="_blank">cglib-2.1.jar</a></div>
            <div class="cnt">http://cglib.sourceforge.net/&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; </div>
            <div class="cnt">高效的代码生成工具, Hibernate用它在运行时扩展 Java类和实现 Java 接口</div>
            <div class="cnt"><br />
            <a href="http://jakarta.apache.org/commons/collections" target="_blank">commons-collections-2.1.1.jar</a></div>
            <div class="cnt">http://jakarta.apache.org/commons/collections </div>
            <div class="cnt">Apache 的工具集,用来增强Java对集合的处理能力</div>
            <div class="cnt"></div>
            <div class="cnt"></div>
            <div class="cnt" align="left"><a href="http://jakarta.apache.org/commons/logging/" target="_blank">commons-logging-1.0.4.jar</a></div>
            <div class="cnt" align="left">http://jakarta.apache.org/commons/logging/&nbsp;&nbsp; </div>
            <div class="cnt" align="left">Apache 软件基我组所提供的日志工具</div>
            <div class="cnt" align="left"></div>
            <div class="cnt" align="left"></div>
            <div class="cnt"><a href="http://gee.cs.oswego.edu/dl/classes%20/EDU/oswego/cs/dl/util/concurrent/intro.html" target="_blank">concurrent-1.3.2.jar</a></div>
            <div class="cnt">http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; </div>
            <div class="cnt">线程同步工具,在使用JBoss 的树状缓存时需要用到</div>
            <div class="cnt"><br />
            <a href="http://java.sun.com/j2ee/connector/" target="_blank">connector.jar</a></div>
            <div class="cnt">http://java.sun.com/j2ee/connector/&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </div>
            <div class="cnt">用连接多个应用服务器的标准连接器</div>
            <div class="cnt"><br />
            <a href="http://dom4.j.org/" target="_blank">dom4j-1.6.jar</a></div>
            <div class="cnt">http://dom4.j.org/&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </div>
            <div class="cnt">dom4j XML 解析器</div>
            <div class="cnt"><br />
            <a href="http://sourceforge.net/projects/echache" target="_blank">ehcache-1.1.jar</a></div>
            <div class="cnt">http://sourceforge.net/projects/echache&nbsp;&nbsp; </div>
            <div class="cnt">缓存工具.在没有提供其他缓存工具时,这个缓存工具是必不可少的</div>
            <div class="cnt"><br />
            <a href="http://java.sun.com/products/jass/" target="_blank">jaas.jar</a></div>
            <div class="cnt">http://java.sun.com/products/jass/&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </div>
            <div class="cnt">标准的 Java 权限和认证服务包</div>
            <div class="cnt"><br />
            <a href="http://hi.baidu.com/lanren_/blog/item/jaxen.org/" target="_blank">jaxen-1.1-beta-4.jar</a></div>
            <div class="cnt">http:jaxen.org/&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;&nbsp;&nbsp; </div>
            <div class="cnt">通用的 XPath 处理引擎</div>
            <div class="cnt"><br />
            <a href="http://www.jboss.com/products/jbosscache" target="_blank">jboss-cache.jar</a></div>
            <div class="cnt">http://www.jboss.com/products/jbosscache&nbsp;&nbsp; &nbsp;&nbsp; </div>
            <div class="cnt">JBoss 的一种树状缓存实现工具</div>
            <div class="cnt"><br />
            <a href="http://jboss.org/" target="_blank">jboss-common.jar</a></div>
            <div class="cnt">http://jboss.org/&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;&nbsp; </div>
            <div class="cnt">Jboss 的基础包,在使用 JBoss 的树状缓存时必须有此包</div>
            <div class="cnt"><br />
            <a href="http://jboss.org/" target="_blank">jboss-jmx.jar</a></div>
            <div class="cnt">http://jboss.org/&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;&nbsp; </div>
            <div class="cnt">JBoss 的 JMX 实现包</div>
            <div class="cnt"><br />
            <a href="http://jboss.org/" target="_blank">jboss-system.jar</a></div>
            <div class="cnt">http://jboss.org/&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;&nbsp; </div>
            <div class="cnt">JBoss 的核心,包括服务器和部署引擎</div>
            <div class="cnt"><br />
            <a href="http://java.sun.com/products/jdbc/download.html#spec" target="_blank">jdbc2_0-stdext.jar</a></div>
            <div class="cnt">http://java.sun.com/products/jdbc/download.html#spec&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </div>
            <div class="cnt">标准的 JDBC 2.0 扩展API</div>
            <div class="cnt"><br />
            <a href="http://www.jgroups.org/" target="_blank">jgroups2.2.7.jar</a></div>
            <div class="cnt">http://www.jgroups.org/&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; </div>
            <div class="cnt">网络通信工具包</div>
            <div class="cnt"><br />
            <a href="http://java.sun.com/products/jta" target="_blank">jta.jar</a></div>
            <div class="cnt">http://java.sun.com/products/jta&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </div>
            <div class="cnt">标准的 JAVA 事务处理接口</div>
            <div class="cnt"><br />
            <a href="http://www.junit.org/" target="_blank">junit-3.8.1.jar</a></div>
            <div class="cnt">http://www.junit.org/&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; </div>
            <div class="cnt">JUnit 测试框架</div>
            <div class="cnt"><br />
            <a href="http://logging.apache.org/log4j/" target="_blank">log4.j-1.2.9.jar</a></div>
            <div class="cnt">http://logging.apache.org/log4j/&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </div>
            <div class="cnt">log4j 库,Apache 的日志工具</div>
            <div class="cnt"><br />
            <a href="http://www.opensymphony.com/oscache/" target="_blank">oscache-2.1.jar</a></div>
            <div class="cnt">http://www.opensymphony.com/oscache/ &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; </div>
            <div class="cnt">Java 对象的缓存工具</div>
            <div class="cnt"><br />
            <a href="http://proxool.sourceforge.net/" target="_blank">proxool-0.8.3.jar</a></div>
            <div class="cnt">http://proxool.sourceforge.net/&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; </div>
            <div class="cnt">Proxool JDBC 连接池工具</div>
            <div class="cnt"><br />
            <a href="http://swarmcache.sourceforge.net/" target="_blank">swarmcache-1.0rc2.jar</a></div>
            <div class="cnt">http://swarmcache.sourceforge.net/&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </div>
            <div class="cnt">Hibernate 可以使用的一种缓存工具</div>
            <div class="cnt"><br />
            versioncheck.jar&nbsp;</div>
            <div class="cnt">版本检查工具包,用于在构建Hibernate 的时候检查辅助 jar 包文件的版本</div>
            <div class="cnt"><br />
            <a href="http://xml.apache.org/xerces2-j/" target="_blank">xerces-2.6.2.jar</a></div>
            <div class="cnt">http://xml.apache.org/xerces2-j/&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; </div>
            <div class="cnt">SAX XML 解析器</div>
            <div class="cnt"><br />
            <a href="http://xml.apache.org/xerces2-j/" target="_blank">xml-apis.jar</a></div>
            <div class="cnt">http://xml.apache.org/xerces2-j/&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; </div>
            <div class="cnt">Java语言中标准的XML 解析器</div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<img src ="http://www.blogjava.net/wanghun723/aggbug/270892.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wanghun723/" target="_blank">L.J.</a> 2009-05-15 17:00 <a href="http://www.blogjava.net/wanghun723/articles/270892.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>