1. 循環分頁或者循環進行部分讀取處理資料的時候,使用 session.clear() ;
2. 對應1+n(n+1)問題使用如下解決方式:
1): 使用createcriteria進行查詢(join fetch)
2):hql -> join fetch
3): 使用@fetch設定lazy
4):在@entity下使用注解@batchsize(size=5)
@batchsize 指定每次 讀 取資料的數量
3. list 與 iterate 進行周遊取出資料庫資料的list();
差別1)list 直接取出對象 iterate先會取出元件,需要使用才會使用
差別2)同一個session中每次執行list()取出資料時都會發送sql語句,但是iterate隻會發出一條,預設會去session緩存去找;
4. 緩存,session級别的緩存稱為一級緩存,每個session都有獨立的一級緩存,例如多個線程同時取同一個對象資料;
解決方案:建立一個共用的總緩存(總緩存)二級緩存,如果找不到然後再到各自的session一級混村中尋找;具體操作如下:首先看緩存政策,

type : 其中memory支援緩存記憶體中,disk支援緩存存放硬碟中;
cluster safe :是否支援使用在叢集環境;
query cache supported:是否支援查詢緩存(3級緩存)
假設使用ehcacheprovider二級緩存:
1)修改hibernate.cfg.xml配置檔案:
1
2
<property name="cache.use_second_level_cache">true</property>
<property name="cache.provider_class">org.hibernate.cache.ehcacheprovider</property>
2) 在/hibernate-distribution-3.3.2.ga/project/etc/ehcache.xml 配置檔案拷貝到項目中;
在ehcache.xml中預設如下設定:
<diskstore path="java.io.tmpdir"/>
3
4
5
6
7
<defaultcache
maxelementsinmemory="10000"
eternal="false"
timetoidleseconds="120"
timetoliveseconds="1200"
overflowtodisk="true"
/>
maxelementsinmemory:在記憶體中最多緩存的對象數量
eternal: 緩存記憶體對象是否永久儲存不删除
timetoidleseconds: 當timetoidleseconds 周期時間沒有被使用過,自動清除掉;(秒)
timetoliveseconds: 緩存對象的生存時間(秒)後自動清楚;
overflowtodisk:溢出的時候是否放置在硬碟上
diskstore path:預設臨時存放硬碟緩存的路徑
注意:<cache name=”samplecache1″ /> 可以自定義cache名,不自定義不指定預設是用 <defaulecache ….. />
3)将類使用二級緩存,直接在@entity下使用注解 @cache 其設定如下:
常用的read_only (隻讀), read_write(讀寫)
其中@cache(region=””) 使用自定義ehcache.xml的自定義緩存政策設定 ~
4)加入ehcache的jar包,路徑如下:/hibernate-distribution-3.3.2.ga/lib/optional/ehcache/ehcache.jar
加入 commons-logging.jar包
1. 放入二級緩存如下規則:
a) 經常通路 b) 不經常改動(改動不大) c) 資料不是很大 例如使用者權限;
2. load 預設使用二級緩存,iterate 預設使用二級緩存
3. list 預設往二級緩存加資料,list查詢的使用不使用緩存
4. 如果要 query 查詢語句使用二級緩存,需要打開查詢緩存(同樣的重複的查詢!)
1) hibernate.cfg.xml配置檔案加入配置:
<property name=”cache.use_query_cache”>true</property>
2) 使用query的setcachable(true) 方法指明使用二級緩存 ;
5. 緩存算法:lru 、 lfu 、 fifo
lru: 最近最少被使用的; (時間)
lfu: 使用率比較少的;(次數)
fifo:按照資料從0開始拿走(堆棧)
設定方法:在ehcache.xml繼續設定一個參數: memorystoreevictionpolicy=”lru”
6. 事務隔離機制(為了避免事務并發出現的問題)
1. read-uncommitted : 能讀取沒有送出的資料; 【會出現髒讀等問題,一般不設定此種】
2. read-committed : 隻有送出後才讀;hibernate建議使用!【能解決髒讀但會出現不可重複讀和幻讀問題(手動解決)】
3. repeatable read : 加鎖;(mysql預設使用 repeatable read )
4. serializable : 序列化,解決任何問題,但是效率最低;
mysql 支援這四種事務隔離機制; 事務隔離級别越高效率越慢~
使用 select @@tx_isolation; 查詢事務隔離機制;
設定隔離機制: set session tx_isolation=’xxx’;
hibernate解決并發事務方案:使用hibernate悲觀鎖和樂觀鎖進行設定;
1)事務機制的值為1,2,4,8 (ps. 二進制為0001 ,0010,0100,1000 這樣算法效率高)
1.a)使用悲觀鎖:(依賴于資料庫的鎖 解決 repeatable read問題)
在讀取load資料的時候,加入第三個參數::
session.load(xxx.class, 1,lockmode.xxx);
lockmode的值如下:
一般隻設定lockmode.upgrade
原因:
none: 無鎖的機制,transaction結束時切換到此模式;
read :在查詢的時候 hibernate會自動擷取鎖;
write ,insert, update hibernate 會自動擷取鎖;
以上 3種鎖的模式是hibernate内部使用的;
upgrade—nowait ->是oracle資料庫 支援的鎖;
1.b)使用樂觀鎖:(程式内使用字段version進行加鎖,與資料庫沒有關系)
可以定義一個version屬性,然後在getversion上使用注解 @version
注意:當并發的時候會報錯,那麼找個錯誤交給我們自己來處理;
悲觀與樂觀:悲觀一開始就進行加鎖,不論是否有其他事務來同時并發;但是樂觀鎖則不進行直接加鎖,而是等待更新時候進行檢查對比下,如果與去之前version不一緻那麼更新下即可;樂觀鎖效率高;