hibernate學習筆記 1

來源:互聯網
上載者:User

1-hb初步

第一個hibernate項目

1、建立java項目

2、建立User Library,加入如下jar
 * HIBERNATE_HOME/hibernate3.jar
 * HIBERNATE_HOME/lib/*.jar
 * MySql jdbc驅動
 
3、建立hibernate設定檔hibernate.cfg.xml,為了便於調試最好加入log4j設定檔

4、定義實體類

5、定義User類的對應檔User.hbm.xml

6、將User.hbml.xml檔案加入到hibernate.cfg.xml檔案中

7、編寫hbm2ddl工具類,將實體類產生資料庫表

8、開發用戶端
 
為了方便跟蹤sql執行,在hibernate.cfg.xml檔案中加入<property name="hibernate.show_sql">true</property>

2-測試實體物件的生命週期

junit簡介:
 * 編寫測試類別xxxTest,需要繼承TestCase
 * 編寫單元測試方法,測試方法必須以test開頭,測試方法不能含有參數和傳回值,如:
   public void testHello1() {}
 * 最好單元測試的代碼單獨建立一個目錄
 
瞭解Hibernate中CRUD操作

瞭解get和load的區別?
 * get不支援lazy,load支援lazy
 * 採用get載入資料,如果沒有匹配的資料,返回null,而load則拋出異常
 
transient狀態的特徵?
 * 在資料庫中沒有與之匹配的資料
 * 沒有納入session的管理
 
persistent狀態的特徵?
 * persistent狀態的對象在資料庫中有與之匹配的資料
 * 納入了session的管理
 * 在清理緩衝(髒資料檢查)的時候,會和資料庫同步
 
detached狀態的特徵?
 * 在資料庫中有與之匹配的資料
 * 沒有納入session的管理  

3-hibernate基本映射

實體類---表
實體類中的普通屬性---表欄位

採用<class>標籤映射成資料庫表,通過<property>標籤將普通屬性對應成表欄位
所謂普通屬性指不包括自訂類、集合和數組等

注意:如果實體類和實體類中的屬性和sql中的關鍵字重複,必須採用table或column重新命名

實體類的設計原則:
 * 實現一個預設的(即無參數的)構造方法(constructor)
 * 提供一個識別屬性(identifier property)(可選)
 * 使用非final的類 (可選)
 * 為持久化欄位聲明訪問器(accessors) 

主鍵建置原則:
 uuid、native和assigned

4-hibernate多對一關聯映射

關聯映射的本質:
 * 將關聯關係映射到資料庫,所謂的關聯關係是物件模型在記憶體中的一個或多個引用

<many-to-one>會在多的一端加入一個外鍵,指向一的一端,這個外鍵是由<many-to-one>
中的column屬性定義的,如果忽略了這個屬性那麼預設的外鍵與實體的屬性一致

<many-to-one>標籤的定義樣本:
  * <many-to-one name="group" column="groupid"/>
 
理解級聯的含義?
 * 是對象的連鎖操作 
   <many-to-one name="group" column="groupid" cascade="all"/>

5-hibernate一對一關聯映射

hibernate一對一主鍵關聯映射(單項關聯Persoon -- > IdCard)

一對一主鍵關聯映射:讓兩個實體物件的id保持相同,這樣可以避免多餘的欄位被建立

具體映射:

<id name="id">
       <!-- person的主鍵來源idCard, 也就是共用idCard的主鍵 -->
       <generator class="foreign">
                   <param  name="property">idCard</param>
        </generator>
</id>
<property name="name"/>
<!--
one-to-one標籤的含義, 指示hibernate怎麼載入它的關聯對象,預設根據主鍵載入,
constrained="true", 表明當前主鍵上存在一個約束,person的主鍵作為外鍵參照了idCard
-->
<one-to-one name="idCard" constrained="true" />

 

hibernate一對一主鍵關聯映射(雙向關聯Person<---->IdCard)

需要在idcard對應檔中加入<one-to-one>標籤指向person,指示hibernate如何載入person
預設根據主鍵載入

 

hibernate一對一唯一外部索引鍵關聯映射(單向關聯Person---->IdCard)

一對唯一外部索引鍵關聯映射是多對一關聯映射的特例

可以採用<many-to-one>標籤,指定多的一端的unique=true,這樣就限制了多的一端的多重性為一
通過這種手段映射一對一唯一外部索引鍵關聯

hibernate一對一唯一外部索引鍵關聯映射(雙向關聯Person<---->IdCard)

一對一唯一外部索引鍵關聯雙向,需要在另一端(idcard),添加<one-to-one>標籤,指示hibernate如何載入
其關聯對象,預設根據主鍵載入person,外部索引鍵關聯映射中,因為兩個實體採用的是person的外鍵維護的關係,
所以不能指定主鍵載入person,而要根據person的外鍵載入,所以採用如下映射方式:
<one-to-one name="person" property-ref="idCard"/>

 

6-session-flush測試

session flush方法主要做了兩件事:
 * 清理緩衝
 * 執行sql
 
session在什麼情況下執行flush
 * 預設在事務提交時
 * 顯示的調用flush
 * 在執行查詢前,如:iterate
 
hibernate按照save(insert),update、delete順序提交相關操作 

7-hihernate一對多關聯映射

 

(單向Classes----->Student)

一對多關聯映射利用了多對一關聯映射原理

多對一關聯映射:在多的一端加入一個外鍵指向一的一端,它維護的關係是多指向一
一對多關聯映射:在多的一端加入一個外鍵指向一的一端,它維護的關係是一指向多

也就是說一對多和多對一的映射策略是一樣的,只是站的角度不同

在一一端維護關係的缺點:
 * 如果將t_student表裡的classesid欄位設定為非空,則無法儲存
 * 因為不是在student這一端維護關係,所以student不知道是哪個班的,
   所以需要發出多餘的update語句來更新關係

 

(雙向Classes<----->Student)

一對多雙向關聯映射:
 * 在一一端的集合上使用<key>,在對方表中加入一個外鍵指向一一端
 * 在多一端採用<many-to-one>
 
注意:<key>標籤指定的外鍵欄位必須和<many-to-one>指定的外鍵欄位一致,否則引用欄位的錯誤
 
如果在”一“一端維護一對多關聯關係,hibernate會發出多餘的udpate語句,所以我們一般在多
的一端來維護關聯關係

關於inverse屬性:
 inverse主要用在一對多和多對多雙向關聯上,inverse可以被設定到集合標籤<set>上,
 預設inverse為false,所以我們可以從”一“一端和”多“一端維護關聯關係,
 如果設定成inverse為true,則我們只能從多一端來維護關聯關係
 
 注意:inverse屬性,隻影響資料的儲存,也就是持久化
  
inverse和cascade
 * inverse是關聯關係的控制方向
 * cascade操作上的連鎖反應

 

 <class name="Classes" >
  <id name="id">
   <generator class="uuid" />
  </id>
  <property name="name"/>
  <set name="students" inverse="true" cascade="all">
   <key column="classesid"/>
   <one-to-many class="Student"/>
  </set>
 </class>

 

 <class name="Student" >
  <id name="id">
   <generator class="uuid" />
  </id>
  <property name="name"/>
  <many-to-one name="classes" column="classesid"/>
 </class>

 

package com.wang.vo;

import java.util.Set;

public class Classes {
 private String id;
 private String name;
 private Set students;
 public String getId() {
  return id;
 }
 public void setId(String id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public Set getStudents() {
  return students;
 }
 public void setStudents(Set students) {
  this.students = students;
 }
}

public class Student {
 private String id;
 private String name;
 private Classes classes;
 public String getId() {
  return id;
 }
 public void setId(String id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public Classes getClasses() {
  return classes;
 }
 public void setClasses(Classes classes) {
  this.classes = classes;
 }
}

8-hibernate多對多關聯映射

hibernate多對多關聯映射(單向User---->Role)

具體映射方式:
 <set name="roles" table="t_user_role">
  <key column="userid"/>
  <many-to-many class="com.wang.hibernate.Role" column="roleid"/>
 </set>

 

hibernate多對多關聯映射(雙向User<---->Role)

映射方法:
  <set name="roles" table="t_user_role">
   <key column="userid"/>
   <many-to-many class="com.wang.hibernate.Role" column="roleid"/>
  </set>
table屬性值必須和單向關聯中的table屬性值一致
<key>中column屬性值要與單向關聯中的<many-to-many>標籤中的column屬性值一致
在<many-to-many>中的column屬性值要與單向關聯中<key>標籤的column屬性值一致

9-hibernate-lazy策略

hibernate-lazy策略可以使用在:
 * <class>標籤上,可以取值:true/false
 * <property>標籤上,可以取值:true/false需要類增強工具
 * <set><list>標籤上,可以取值:true/false/extra
 * <one-to-one><many-to-one>單端關聯上,可以取值:false/proxy/noproxy
 
lazy概念:只有真正使用該對象時,才會建立,對於hibernate而言,正真使用的時候才會發出sql

hibernate支援lazy策略只有在session開啟狀態下有效

<class>標籤上的lazy特性只對普通屬性起作用

 

hibernate在集合上的lazy策略,可以取值:true/false/extra   (設定成extra會調優)

<class>標籤上的lazy不會影響到集合上的lazy特性

 

hibernate在單端關聯上的lazy策略,可以取值:false/proxy/noproxy

<class>標籤上的lazy不會影響到單端關聯上的lazy特性

9-hibernate繼承映射

每棵繼承樹映射成一張表

1、理解如何映射
  因為類繼承樹肯定是對應多個類,要把多個類的資訊存放在一張表中,必須有某種機制來區分哪些記錄是屬於哪個類的。
 這種機制就是,在表中添加一個欄位,用這個欄位的值來進行區分。用hibernate實現這種策略的時候,有如下步驟:
 父類用普通的<class>標籤定義
 在父類中定義一個discriminator,即指定這個區分的欄位的名稱和類型
 如:<discriminator column=”XXX” type=”string”/>
 子類使用<subclass>標籤定義,在定義subclass的時候,需要注意如下幾點:
 Subclass標籤的name屬性是子類的全路徑名
 在Subclass標籤中,用discriminator-value屬性來標明本子類的discriminator欄位(用來區分不同類的欄位)
 的值Subclass標籤,既可以被class標籤所包含(這種內含項目關聯性正是表明了類之間的繼承關係),也可以與class標
 簽平行。 當subclass標籤的定義與class標籤平行的時候,需要在subclass標籤中,添加extends屬性,裡面的值
 是父類的全路徑名稱。子類的其它屬性,像普通類一樣,定義在subclass標籤的內部。

2、理解如何儲存
 儲存的時候hibernate會自動將鑒別欄位值插入到資料庫中,在載入資料的時候,hibernate能根據這個鑒別值
 正確的載入對象
 
多態查詢:在hibernate載入資料的時候能鑒別出正真的類型(instanceOf)

get支援多態查詢
load只有在lazy=false,才支援多態查詢
hql支援多態查詢

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.