‘Hibernate 完全手冊’ 讀書筆記(三) 映射、操作對象

來源:互聯網
上載者:User

1、對象關係映射

1-1、單向多對一關聯

 產品和分類的關係:多個不同產品屬於同一種分類。
private Category category;
<many-to-one name="category" column="categoryId" not-null="true" />

1-2、一對多映射
private Set products = new HashSet();
<set name="products"  <!--Category 中集合屬性名稱為 products-->
  table="product"  <!--集合屬性對應表的名稱為 product-->
  schema="test"   <!--表的 schema 名稱為 test-->
  lazy="true"   <!--此集合採用延時載入策略-->
  inverse="true"  <!--由關聯屬性的另一方作為關聯的主控方-->
  cascade="delete"  <!--採用串聯刪除,當 Category 被刪除時關聯的此集合內容也將被刪除-->
  sort="natural"  <!--自然排序集合內容-->
  order-by="productId asc" <!--按 productId 欄位升序排列集合內容-->
  >
  <key column="category_fk" />
 
  <one-to-many class="petstore.domain.Product" />
</set>

1-3、繼承映射

 

2、Hibernate 操作對象

2-1、對象的三種狀態

 

● 瞬時態(Transient)--VO(Value Ojbect)
  對象執行個體產生到被 JVM 記憶體回收為止並不受 Hibernate 架構管理。

● 持久態(Persistent)--PO(Persistent Ojbect)
  對象執行個體被 Hibernate 架構管理,該對象可能是剛被儲存的,或剛從資料庫中被載入的。Hibernate 會檢測處於持久態的對象任何改動,在當前操作單元執行完畢將對象與資料庫同步,即將對象的屬性儲存到資料庫映射對應的欄位中。簡單點說就是該實體物件與 session 發生關係,而且處於 session 的有效期間內。
 
● 託管態(Detached)--VO(Value Ojbect)
  與持久對象關聯的 Session 被關閉後,對象就變為託管的,可繼續被修改。託管對象如果重新關聯到某個新的 Session 上,會再次變為持久的,同時改動也將會被持久化到資料庫。這個期間的轉變過程可以看作是應用程式事務,即中間會給使用者考慮時間的長時間啟動並執行操作單元。
  處於託管態對象具有與資料庫表記錄間的聯絡(持久化標識,identifier)。

2-2、對象操作的應用程式介面

● 修改對象

  對於已經持久化的對象,不需要調用某個特定的方法就可以實現修改持久化,因為 Hibernate 會自動調用 flush() 方法保證與資料庫的同步。

  對於處於託管狀態的執行個體,Hibernate 通過提供 Session.update() 或 Session.merge() 方法,重新關聯受管理的執行個體。但是需要注意的是:如果具有持久化標識(identifier)的對象之前已經被另一個會話串連(secondSession)裝載了,應用程式關聯操作會發生異常。

  使用 merge() 方法時,使用者不必考慮 session 的狀態,可隨時將修改儲存到資料庫中。例如:Session 中存在相同標識的持久化執行個體時,Hibernate 便會根據使用者給出的對象狀態覆蓋原有的持久化執行個體的狀態。

  另外,Hibernate 還提供了 saveOrUpdate()方法,它即可分配新持久化標識(identifier),儲存瞬時(transient)對象,又可更新/重新關聯託管的(identifier)執行個體。

● 刪除對象
  通過 HQL 語句,調用重載的 delete(),可以一次刪除多個對象。
  session.delete("from Customer as c where c.customerId <3");

● 查詢對象
  已知對象表示符值查詢
  物件識別碼未知查詢 HQL
  根據某些特定條件查詢 QBC,Query By Criteria
  按詳例查詢 QBE,Query By Example
  調用資料庫查詢 native SQL

  查詢條件參數 ? 查詢條件參數索引,由 0 開始。
  查詢條件實名 :name
  外置命名查詢

    在對應檔定義查詢語句,將程式與查詢語句分離:
    <query name="CategoryById"
 <! [CDATA[
  from Category c where c.categoryId>? ]]>
    </query>

    程式調用:
      Query q = sess.getNamedQuery("CategoryById");
      q.setLong(0, name);
      List cats = q.List();
   
  用 Query 提供的 iterate() 方法遍曆查詢結果,如果查詢的結果在 session 或二級緩衝(second-level cache)中,那麼使用 iterate() 方法可以得到更好的效能。

  如果 JDBC 驅動支援可滾動的 ResuleSet,Query 介面可以使用 ScrollableResults,允許你在查詢結果中靈活移動(需要保持資料庫連接和遊標 cursor 處於抑制開啟狀態)。

ScrollableResults cates = q.scroll();
cates.first()
cates.scroll(5);

● cascade 和 inverse 級聯操作

inverse
  只對 set,one-to-many(或 many-to-many)有效,對於 many-to-one,one-to-one 無效
  對集合起整體作用

cascade
  對關係標記都有效
  對集合的一個元素起作用,如果集合為空白,那麼 cascade 不會引發關聯操作
 
  作用時機:在 flush 時(commit 會自動執行 flush),hibernate 會自行判斷每個 set 是否有變化,對有變化的 set 執行相應的 SQL,if (inverse) return。即:cascade 在前,inverse 在後。

異常:
org.hibernate.exception.ConstraintViolationException: could not insert

原因是 category_fk 欄位約束不可為空,而在建立的 Product 對象時插入了空值,而且關聯關係由 Caterogy 對象維持,而被關聯的 Product 對象不知道自己與哪個 Category 對象關聯。說到底就是 pro 對象的 categoryId 值為空白。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.