Hibernate的Orders OrderItem類
Hibernate還是比較常用的,于是我研究了一下Orders OrderItem,在這里拿出來和大家分享一下,希望對大家有用。
Orders OrderItem
有時一個一個地操縱對象確實可行,但是我們希望能夠級聯(lián)加載和更新?,F(xiàn)在我們來看如何做到這一點。
我們需要同時檢查Order OrderItem。就如前面所提到的,我們添加一項Product到一個Order中,它將變成一個Order OrderItem在內(nèi)部保存一個OrderItem集。我們希望保存Order,讓Hibernate來做其他工作:保存OrderItem和更新所添加的Product的可用庫存(數(shù)量)。聽起來很復雜,但實際上非常簡單。Hibernate知道如何處理一對一、一對多、多對一和多對多方式中的相關對象。我們將從映射文件開始。
Order.hbm.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">- <hibernate-mapping>
- <class name="test.hibernate.Order" table="orders">
- <id name="id" type="string" unsaved-value="null" >
- <column name="id" sql-type="char(32)" not-null="true"/>
- <generator class="uuid.hex"/>
- </id>
- <property name="date">
- <column name="order_date"sql-type="datetime" not-null="true"/>
- </property>
- <property name="priceTotal">
- <column name="price_total"sql-type="double" not-null="true"/>
- </property>
- <set name="orderItems" table="order_items" inverse="true"cascade="all">
- <key column="order_id" />
- <one-to-many class="test.hibernate.OrderItem" />
- </set>
- </class>
- </hibernate-mapping>
這個映射文件非常易于理解,除了最后一個元素<set>。它表示了不同類之間的連接,在我們的例子中,這些類是Order和 OrderItem。屬性和子元素很容易理解:一個Set類型的字段,名為orderItems(參見上面的Order源代碼),它包含類型為test.hibernate.OrderItem的對象,正如<one-to-many>子元素所解釋的那樣。這些對象被持久化在表order_items中,order_id列包含OrderItem類型的對象的鍵。
cascade="all"是一個非常重要的屬性。它解釋了在操縱連接到的對象時,Hibernate如何動作。在我們的例子中,當創(chuàng)建一個Order時,我們無疑希望它所有的OrderItem也被創(chuàng)建;當然,當一個Order被刪除時,我們也希望它所有的OrderItem也被刪除。Cascade屬性還有另外三個選項(none、save-update和delete),我們將在下面的示例中看一下如何使用它們。
這個對象比較有意思。它的實例自動在Order中創(chuàng)建,基本上不會存在于其外。然而,由于它們在創(chuàng)建Order時代表Product,所以我們需要它們。如果一項產(chǎn)品的價格改變了,我們無疑不希望所有相關的OrderItem以及Order的價格被改變。我們需要的只是在OrderItem創(chuàng)建時更新Product的可用庫存。最后,當一項Order被刪除時,其OrderItem也被刪除,但我們不能改變Product!聽上去很復雜,特別是要編寫所有這些SQL語句的話。但Hibernate把它們壓縮成了映射文件中的兩行!
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">- <hibernate-mapping>
- <class name="test.hibernate.OrderItem"table="order_items">
- <id name="id" type="string" unsaved-value="null" >
- <column name="id" sql-type="char(32)"not-null="true"/>
- <generator class="uuid.hex"/>
- </id>
- <property name="orderId" insert="false"update="false">
- <column name="order_id" sql-type="char(32)"not-null="true"/>
- </property>
- <property name="productId" insert="false"update="false">
- <column name="product_id" sql-type="char(32)"not-null="true"/>
- </property>
- <property name="amount">
- <column name="amount" sql-type="int"not-null="true"/>
- </property>
- <property name="price">
- <column name="price" sql-type="double"not-null="true"/>
- </property>
- <many-to-one name="order"class="test.hibernate.Order"column="order_id" />
- <many-to-one name="product"class="test.hibernate.
Product"cascade="save-update"column="product_id"/>- </class>
- </hibernate-mapping>
到目前為止,我們了解了關于<id>和<property>元素的一切,但<many-to-one>是一個新元素。這個元素非常簡單。第一個<many-to-one>元素指出OrderItem的名為order的字段是test.hibernate.Order 類型,并且通過表order_items的order_id列來引用(參見class元素的table屬性)。第二個many-to-one元素類似于第一個,除了它具有cascade="save-update"屬性。它在定義的內(nèi)容之前進行解釋。在這個例子中,我們假設Hibernate只在保存(創(chuàng)建)或更新(更改)OrderItem時傳遞Product的更改,而在刪除時不傳遞更改。因此,上述的復雜SQL語句就被壓縮為單個屬性!現(xiàn)在這個問題解決了!
【編輯推薦】