標籤:基礎 sel 實現 單表查詢 iter 更新 hql 條件查詢 inverse
實體類和實體之間的關係:一對多,多對多
資料庫設計: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());
限制條件: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 映射及查詢