Hibernate 映射及查詢
實體類和實體之間的關系:一對多,多對多
數據庫設計:e_r 一個實體對象就是一個表格, 如果是1對多的關系,將多方的主鍵拿到1方做外鍵。 多對多:重新建立一張新的表格,將雙方的主鍵拿到這裏做外鍵
1、一對多的關系映射。
班級和學生為例:
1、創建班級實體類和學生實體類
2、在班級實體類中用set集合屬性來表示班級中有多個學生。
3、在學生實體類中,用班級屬性來表示這個學生屬於哪個班級
4、在映射文件裏面:班級(一方)通過《set》標簽來描述我的set屬性,然後再set標簽裏面通過<key>開表示我的主鍵在多方做外鍵的時候 外鍵的名稱。再用<one-to-mang>
5、在映射文件裏面:學生(多方)通過<mang-to-one>來表示我和class屬性表示那個類是這個關系,同時用column 來制定對方如果要將主鍵放到我這裏做外鍵,那麽外鍵的名字就是column制定的哪個。
一對多的級聯保存:將班級和學生的關系在代碼裏面體現完成後,只保存班級信息,那麽學生信息也一並保存進去,不用單獨寫代碼去保存學生對象。 需要配置
有1個班級對象,這個班級對象裏面有三個學生,現在我要把這四個對象統統保持到數據庫裏面。
Session.save()
一對多的級聯刪除:
找到要刪除的實體對象,直接刪除,他下面的學生實體對象一並會被刪除。
一對多的修改:
將李四(2)這個對象調到理工班級(3)
Session獲得李四中個對象,獲得理工班級對象。把李四加到理工班級對象的set集合裏面,更新數據庫。
2、多對多關系的映射
課程和學生的例子
創建兩個實體對象,分別在這兩個實體對象裏面維護他們之間的多對多的關系,
在映射文件中配置好。
級聯保存:出現了一個重復的主鍵錯誤。多對多關系是有第三表來維護,創建的時候是有映射文件去配置創建的,沒有給他制定主鍵,那麽會把兩個外鍵看作是主鍵(聯合主鍵)。
在
如何解決:就是讓其中一方放棄對第三張表格的一個維護:<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());
限制條件:Criteria、Query只能是在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 映射及查詢