1. 程式人生 > >hibernate隨筆(知識盲點)

hibernate隨筆(知識盲點)


get與load的區別


相同點:都是根據物件的id來載入物件
不同點:當查詢id不存在時,get會返回一個null,而load會丟擲異常(當載入的id不存在時,get返回空值,load丟擲異常)


為什麼呢?

load採用的是延遲載入,get是直接載入。異常是什麼時候報出來的?load採用的是代理模式,load執行完後返回的是一個代理物件,此時不會報出異常,這個代理物件沒有被初始化,其中沒有目標物件,當訪問物件中詳情的時候,會發送lelect語句返回為null也不會報錯,而拿這個空值來初始化代理物件就會丟擲異常,因為代理物件的目標物件不能為空。(因為在代理模式中代理物件必須要有目標物件)

extra特別懶載入能用聚合查詢絕不做詳情查詢,聚合函式查詢效率遠大於詳情查詢效率。


session.get都做了哪些工作?
1)將資料從DB中讀取出來
2)將資料轉換為物件放到堆記憶體中
3)將物件的id放入session Map的key值,將物件的引用放入session快取Map的value值中
4)將物件的資料(物件的詳情)放入到“快照”中
當事務提交時做的工作,將堆記憶體中的資料與快照中的資料進行對比,若比較結果不相同,則進行update操作


執行重新整理的時間點(refresh)只有一個:事務的提交
執行同步的時間點(flush)的時間點:1)Query查詢操作  2)顯示的呼叫session.flush()方法  3)事務的提交



修改重新整理點:session.setFlushMode(?);FlushMode


二級快取:
內建快取:只讀,不可修改,預設開啟
外接快取:引用第三方產品
根據快取內容不同分為三類:1)類快取:快取物件為實體類物件
2)集合快取 3)查詢快取
類快取:快取的是物件詳情(存放在專門的一個稱為實體區域的快取中,快取的內容為物件的詳情)
集合快取:快取的是所有包含物件的ID(存放在一個專門稱為集合區域的快取中,快取內容為所有包含物件的id)

Query查詢快取:其從Query快取中查詢的依據不再是查詢物件的id,而是根據Query語句來的,也就是說Query查詢結果存放到Query快取中時其key為Query的查詢語句,value為查詢結果。根據Query語句進行匹配是否從快取中讀取資料。(不是很好用)


當使用query.executeUpdate()時會繞過一級快取而直接更新到資料庫。
之後在使用get查詢修改的資料,查詢到的仍然是修改之前的資料。按照之前學習的理論,這裡的get查詢會先查詢一級快取,結果沒有,再查詢二級快取,結果是有的。但為什麼沒有從二級快取中讀取這個資料,而是從DB中直接查詢?
因為query的executeUpdate方法,會修改二級快取中的一個屬性:updateTimestamp,修改時間戳
什麼意思呢?實際上二級快取物件中快取的內容要比一級快取物件中快取的內容要多一個屬性,修改時間戳。
一旦這個屬性被修改,那麼,查詢會不從二級快取物件中讀取資料,而是直接從DB中直接讀取。
使用executeUpdate進行修改操作與快照無任何關係。


事務的四大特性:1)原子性  2)一致性  3)隔離性  4)永續性
事務的併發所引出的問題:不可重複讀:1)更新了資料 2)增加了資料 3)刪除了資料  ;後兩種現象稱為幻影現象
當隔離級別設定為可重複讀後,會引發幻讀


隔離級別:
mysql 的預設隔離級別:4
oracle 的預設隔離級別:2


一般有業務需求的時候才會寫級聯關係。


悲觀鎖:在select語句後新增for update,則會給每一條符合條件的記錄新增寫鎖(悲觀鎖不太懂)
變數命名不要用:sVersion。這樣在解析的時候可能會出問題,應直接寫成sversion(版本號)


hibernate用的是JPA的註解並不是hibernate自己的,所以導包的時候要導javax的包。