Hibernate
一、 基礎知識
① Hibernate是對象/關系映射(Object/Relation Mapping)的解決方案。
② Hibernate架構
● POJO類
● hibernate.cfg.xml
● *.hbm.xml
● Hibernate應用
二、 幾個重要的類
● Configuration類 (負責管理Hibernate的配置信息)
當創建SessionFactory時,Configuration實例可以指定使用哪一個映射文擋。應用程序通常只是創建一個Configuration實例,并通過它創建一個SessionFactory實例。
● SessionFactory類 (負責創建Session實例)
它是線程安全的,可以被多線程調用以取得Session,而且構造SessionFactory很消耗資源,所以多數情況下一個應用中只初始化一個SessionFactory,為不同的線程提供Session。
● Session類
Session是Hibernate運作的中心,對象的生命周期、事務的管理、數據庫的存取都與Session息息相關。Session不是線程安全的,多個執行線程共享一個Session,將會發生數據共享而發生混亂問題。為了解決此問題,可以采用ThreadLocal變量,使用它可以有效隔離執行所使用的數據,也就避開了Session的多線程之間的數據共享問題。
如何調用hibernate API?
1、創建Configuration對象。(解析配置文件)
Configuration config = new Configuration();
2、通過Configuration創建Session Factory(線程安全的重量級組件)。
Config = config.configure(); //configure()方法會在CLASSPATH下尋找hibernate.cfg.xml
SessionFactory = config.buildSessionFactory();
3、通過SessionFactory創建Session會話對象。
Session session = sessionFactory.openSession();
4、通過Session取得事務對象。
Transaction trans = session.beginTransaction();
5、通過session與數據庫進行會話。
session.save(object o); //增
session.delete(object o); //刪
session.update(object o); //改
session.get (Class clazz, Serializable id); //根據Id查找對象
session.createQuery(String sql); //自己拼HQL語言查找對象返回一個Query對象。
6、提交操作,結束事務。
Trans.commit();
7、關閉Session
session.close();
注:第一步和第二步一般放在靜態初始化代碼塊中執行。
三、Hibernate中自帶ID的generator的含義:
1、identity:用于MySql數據庫。特點:遞增
<id name="id" column="id">
<generator class="identity"/>
</id>
注:對于MySql數據庫使用遞增序列時需要在建表時對主鍵指定為auto_increment屬性。
2、sequence:用于Oracle數據庫
<id name="id" column="id">
<generator class="sequence">
<param name="sequence">序列名</param>
</generator>
</id>
3、native:跨數據庫時使用,由底層方言產生。
Default.sequence為hibernate_sequence
<id name="id" column="id">
<generator class="native"/>
</id>
注:使用native時Hibernate默認會去查找Oracle中的hibernate_sequence序列。
如果Oracle中沒有該序列,連Oracle數據庫時會報錯。
4、hilo:通過高低位合成id,先建表hi_value,再建列next_value。必須要
有初始值。
<id name="id" column="id">
<generator class="hilo">
<param name="table">high_val</param>
<param name="column">nextval</param>
<param name="max_lo">5</param>
</generator>
</id>
5、sequencehilo:同過高低位合成id,建一個sequence序列,不用建表。
<id name="id" column="id">
<generator class="hilo">
<param name="sequence">high_val_seq</param>
<param name="max_lo">5</param>
</generator>
</id>
6、assigned:用戶自定義id;
<id name="id" column="id">
<generator class="assigned"/>
</id>
7、foreign:用于一對一關系共享主健時,兩id值一樣。
四、Hibernate類關系的處理:
1、One―to―One關系在數據庫中如何體現,在JavaBean中如何體現,在Hibernate中如何映射one-to-one關系。
1、數據庫中:一個表的外健對應另一個表的主健,外健要加上Unique約束?;蛘呤莾蓚€表共享一個主健。
2、javaBean中:在JavaBean中增加一個屬性,即另外一個對象的引用,可以單向也可以雙向。
3、在hibernate中:
主健映射:都是one-to-one要用foreign生成策略。
外健映射:主表中用one-to-one,副表通過property-ref many-to-one
create table car_pk (
id number(10,0) not null,
name varchar2(15),
serial varchar2(30),
manufacturer varchar2(50),
producedate date,
primary key (id)
);
create table engine_pk (
id number(10,0) not null,
model varchar2(20),
manufacturer varchar2(50),
producedate date,
primary key (id)
);
alter table engine_pk
add constraint fk_engine_car_pk
foreign key (id)
references car_pk(id);
|
One-to-One PK主鍵映射 (詳見代碼)
Table car_pk
Id
|
name
|
serial
|
manufacturer
|
producedate
|
|
|
|
|
|
Table engine_pk
Id
|
model
|
manufacturer
|
producedate
|
|
|
|
|
特點:engine_pk 表的Id 與 car_pk表共享主鍵。
One-to-One FK外鍵映射 (詳見代碼)
Table car_pk
Id
|
name
|
serial
|
manufacturer
|
producedate
|
|
|
|
|
|
Table engine_fk
Id
|
carid
|
model
|
manufacturer
|
producedate
|
|
|
|
|
|
特點:engine_fk表多了carid外鍵字段來維護與car_fk 表的關系。
建表語句如下:
create table engine_fk (
id number(10,0) not null,
model varchar2(20) not null,
manufacturer varchar2(50) not null,
producedate date,
carid number(10,0) unique,
primary key (id)
);
alter table engine_fk
add constraint fk_engine_car_fk
foreign key (carid)
references car_fk(id);
|
2、Many-to-One關系在數據庫中如何體現,在JavaBean中如何體現,在
Hibernate中如何映射many-to-on關系。
1、數據庫中:一個表的主健對應另一個表的外健。
2、javaBean中:一個對象包含另一個對象的一個引用,另一個對象包含這個對象的一組(集合,用set)引用。
3、在hibernate中:用set.key指定具體列。
在Set一端一定要寫inverse=“true”表示忽略集合一端的變化。
以Order類和Item類 的一對多關系為例子(詳見代碼):
Item
-id: Integer
-product: String
-amount: int
-order: Order
-
-
|
Order
-id: Integer
-owner: String
-phone: String
-address: String
-items: Set<Item>
|
小結: 對象的關聯關系有一對一、一對多、多對一和多對多,其中多對一和一對多關系比較常見。
一對一關系有兩中方式:以主鍵關聯和以外鍵關聯。
一對多和多對一通常應設置為雙向關聯,并在“一”這一方設置inverse="true"(比如一個班級對應多個學生,在班級這一邊設置inverse="true")。設置了inverse="true"這一端比較清閑,它把控制權交給了另一端。讓“多”這一端有控制權。
多對多 可以借助中間表來保存兩個實體之間的關系。
對象在Hibernate中的狀態圖:
對象3種狀態: Transient(瞬時) Persistent(持久) Detached(托管)
get()
load()
find()
iterate()
etc.
|
evict()
close()*
clear()*
|
update()
saveOrUpdate
lock()
|