hibernate學習筆記 1
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支援多型查詢
相關文章
- hibernate學習筆記(1)筆記
- hibernate學習筆記(2)筆記
- Hibernate學習筆記二筆記
- 學習筆記1筆記
- 學習筆記-1筆記
- swift學習筆記《1》Swift筆記
- Vue學習筆記1Vue筆記
- Numpy學習筆記 1筆記
- HTML學習筆記1HTML筆記
- flex:1學習筆記Flex筆記
- Numpy學習筆記(1)筆記
- SLAM學習筆記(1)SLAM筆記
- Oracle學習筆記1Oracle筆記
- mysql學習筆記-1MySql筆記
- Zynq學習筆記(1)筆記
- scapy學習筆記(1)筆記
- Git—學習筆記1Git筆記
- perl學習筆記1筆記
- Oracle學習筆記-1Oracle筆記
- git學習筆記 1Git筆記
- HTML學習筆記(1)HTML筆記
- git學習筆記1Git筆記
- golang 學習筆記1Golang筆記
- Scrapy 框架 (學習筆記-1)框架筆記
- React學習筆記1—起步React筆記
- webpack1學習筆記Web筆記
- python學習筆記(1Python筆記
- ADworld學習筆記(1)筆記
- spring學習筆記(1)Spring筆記
- Android學習筆記(1)Android筆記
- PhoneGap學習筆記1筆記
- Linux學習筆記1Linux筆記
- GTK+學習筆記1筆記
- 機器學習的學習筆記1機器學習筆記
- PL/SQL學習筆記-1SQL筆記
- ruby 字串學習筆記1字串筆記
- Flex學習筆記(Day 1)Flex筆記
- oracle 學習筆記---效能優化學習(1)Oracle筆記優化