1. 程式人生 > >Hibernate 映射及查詢

Hibernate 映射及查詢

外鏈接 實體類 映射 類屬性 數據庫 名稱 個學生 通過 cal

實體類和實體之間的關系:一對多,多對多

數據庫設計:e_r 一個實體對象就是一個表格, 如果是1對多的關系,將多方的主鍵拿到1方做外鍵。 多對多:重新建立一張新的表格,將雙方的主鍵拿到這裏做外鍵

1、一對多的關系映射。

班級和學生為例:

1、創建班級實體類和學生實體類

2、在班級實體類中用set集合屬性來表示班級中有多個學生。

3、在學生實體類中,用班級屬性來表示這個學生屬於哪個班級

4、在映射文件裏面:班級(一方)通過《set》標簽來描述我的set屬性,然後再set標簽裏面通過<key>開表示我的主鍵在多方做外鍵的時候 外鍵的名稱。再用<one-to-mang>

標簽來制定我和誰是這個關系,將來hibernate會自動將我的主鍵放到這個類對應的表格裏面做外鍵,外鍵字段名就是key標簽制定的哪個。

5、在映射文件裏面:學生(多方)通過<mang-to-one>來表示我和class屬性表示那個類是這個關系,同時用column 來制定對方如果要將主鍵放到我這裏做外鍵,那麽外鍵的名字就是column制定的哪個。

一對多的級聯保存:將班級和學生的關系在代碼裏面體現完成後,只保存班級信息,那麽學生信息也一並保存進去,不用單獨寫代碼去保存學生對象。 需要配置

1個班級對象,這個班級對象裏面有三個學生,現在我要把這四個對象統統保持到數據庫裏面。

Session.save()

一對多的級聯刪除:

找到要刪除的實體對象,直接刪除,他下面的學生實體對象一並會被刪除。

一對多的修改:

將李四(2)這個對象調到理工班級(3

Session獲得李四中個對象,獲得理工班級對象。把李四加到理工班級對象的set集合裏面,更新數據庫。

2、多對多關系的映射

課程和學生的例子

創建兩個實體對象,分別在這兩個實體對象裏面維護他們之間的多對多的關系,

在映射文件中配置好。

級聯保存:出現了一個重復的主鍵錯誤。多對多關系是有第三表來維護,創建的時候是有映射文件去配置創建的,沒有給他制定主鍵,那麽會把兩個外鍵看作是主鍵(聯合主鍵)。

hibernate裏面關系的一個維護使由兩個對象共同完成的,是雙向維護的一個關系,保持學生他會將學生和課程的關系保持到我們的第三個表格裏面,去保存課程課程的時候,課程也要去講關系保存到第三張表格。

如何解決:就是讓其中一方放棄對第三張表格的一個維護:<set inverse=”true”>

級聯刪除:我刪除某個學生,那麽和這個學生有關系的課程也會被刪除。(一般不會在開發過程中使用)

多對多關系如何維護第三張表格:讓張三不選修ssh

單表查詢(基本查詢)

HQL的基礎語法

語法和sql語法基本相同。

sql語句的一個區別:操縱對象不同。

HQL語句是被Query這個對象使用的。

1、HQL查詢所有: from 實體類的名稱:

2、HQL的條件查詢:from 實體類名 where 實體類屬性名=

3、排序查詢: order by 屬性 asc

4、分頁查詢:rownum+字查詢 不同數據庫實現分頁的手段不一樣。Query對象裏面封裝了兩個方法去實現分頁。

5、查詢實體對象的部分屬性:select 屬性名,屬性名 from 類名在HQL語句的select後面不允許跟著* from 類名:

6、聚合函數的使用 select count(*) from 類名

QBC查詢

借助於Criteria對象進行查詢:不需要寫任何語句,直接使用它封裝的方法來完成查詢。

1、查詢所有:list();

2、條件查詢:使用封裝的方法:add(條件) Restrictions進行條件的設置。

3、排序: criteria.addOrder(Order.asc("sid"));

4、分頁:criteria.setFirstResult(0); criteria.setMaxResults(3);

5、統計:criteria.setProjection(Projections.rowCount());

限制條件:CriteriaQuery只能是在session對象產生之後,再產生。Criteria因為所有的功能都是有方法來執行,因此這個對象所查詢的條件只有在產生session之後才能進行添加。

萬一我 有一個需求:要求在頁面階段就得把條件拼接好,那麽Criteria對象沒有辦法完成這個需求:另外一個對象:DetachedCriteria對象可以完成:這個對象可以獨立產生,不需要借助任何session,因此使用這個對象進行的查詢我們稱之為:離線查詢.

離線查詢

借助於:DetachedCriteria:和Criteria的查詢方法都一致。唯一不同就是可以離線生成。

HQL多表查詢

內聯接:符合條件的行出現在結果集,不符合的不出現

// 查詢班級裏面有哪些學生

From MyClass m inner join m.stuSet

查詢的結果是一個一個小數組

如果要求返回的結果是對象形式的,那麽使用迫切內聯接:

迫切內聯接:

From MyClass m inner join fetch m.stuSet

左外鏈接:不管是否符合條件:主表裏面的記錄一定會出現在結果集裏面。

From MyClass m left join m.stuSet

From MyClass m left join fetch m.stuSet

f

右外鏈接(沒有迫切)

From MyClass m right join m.stuSet

檢索策略

1、立刻查詢:只要執行到我的查詢指令,hibernate立刻發送sql指令到數據庫吧相應的內容查詢出來:get ()就是一個立刻查詢的方法

2、延時查詢:load():這個方法不會立刻查詢數據,只有到不得不去查的時候才去查詢。如要獲得這個對象裏面的主鍵的話,load方法直接將第二個參數返回給你。只有不得不去查詢的時候才發送sql去查。

延時分為兩類:

1級別類型的延時:根據id查詢類,並且使用時load方法,不會發送sql指令。

2 關聯延時:查詢班級,如果要班級裏的學生信息,那麽這個學生信息的查詢時機(立刻執行還是延時執行)

Hibernate 默認給我們做了一個優化策略,我查詢班級的時候,不會立刻將學生的信息查詢出來,當你真的要獲得當前班級的學生的時候,hibernate會自動發送sql,將屬於這個班級的學生信息查詢出來。

可以通過在〈set>設置加載方式 fetch="select" lazy="true"

極其懶惰的加載方式:如果你要查詢這個班級的學生的名字,那麽這個加載方式只會發送sql指令將學生姓名查詢出來。

Hibernate 映射及查詢