hibernate提供的一級快取
hibernate是乙個執行緒對應乙個session,乙個執行緒可以看成乙個使用者。也就是說session級快取(一級快取)只能給乙個執行緒用,別的執行緒用不了,一級快取就是和執行緒繫結了。
hibernate一級快取生命週期很短,和session生命週期一樣,一級快取也稱session級的快取或事務級快取。如果tb
事務提交或回滾了,我們稱session就關閉了,生命週期結束了。
快取和連線池的區別:快取和池都是放在記憶體裡,實現是一樣的,都是為了提高效能的。但有細微的差別,池是重量級的,裡面的資料是一樣的,比如乙個池裡放100個connection連線物件,這個100個都是一樣的。快取裡的資料,每個都不一樣。比如讀取100條資料庫記錄放到快取裡,這100條記錄都不一樣。
快取主要是用於查詢
//同乙個session中,發出兩次load方法查詢
student student = (student)session.load(student.class, 1);
system.out.println("student.name=" + student.getname());
//不會發出查詢語句,load使用快取
student = (student)session.load(student.class, 1);
system.out.println("student.name=" + student.getname());
第二次查詢第一次相同的資料,第二次load方法就是從快取裡取資料,不會發出sql語句到資料庫裡查詢。
//同乙個session,發出兩次get方法查詢
student student = (student)session.get(student.class, 1);
system.out.println("student.name=" + student.getname());
//不會發出查詢語句,get使用快取
student = (student)session.get(student.class, 1);
system.out.println("student.name=" + student.getname());
第二次查詢第一次相同的資料,第二次不會發出sql語句查詢資料庫,而是到快取裡取資料。
//同乙個session,發出兩次iterate查詢實體物件
iterator iter = session.createquery
("from student s where s.id<5").iterate();
while (iter.hasnext()) catch(exception e) finally catch(exception e) finally catch(exception e) finally catch(exception e) finally catch(exception e) finally catch(exception e) finally catch(exception e) finally catch(exception e) finally {
hibernateutils.closesession(session);
執行結果是第二個session發出的list方法查詢普通屬性,沒有發出sql語句到資料庫中查詢,而是到查詢快取裡取資料,這說明查詢快取和session生命週期沒有關係。
//開啟快取,關閉二級快取,採用iterate方法查詢普通屬性
//在兩個session中呼叫iterate方法查詢
執行結果是第二個session的iterate方法還是發出了sql語句查詢資料庫,這說明iterate迭代查詢普通屬性不支援查詢快取。
//關閉查詢快取,關閉二級快取,採用list方法查詢實體物件
//在兩個session中呼叫list方法查詢
執行結果第乙個session呼叫list方法查詢實體物件會發出sql語句查詢資料,因為關閉了二級快取,所以第二個session呼叫list方法查詢實體物件,還是會發出sql語句到資料庫中查詢。
//開啟查詢快取,關閉二級快取
//在兩個session中呼叫list方法查詢實體物件
執行結果第乙個session呼叫list方法查詢實體物件會發出sql語句查詢資料庫的。第二個session呼叫list方法查詢實體物件,卻發出了很多sql語句查詢資料庫,這跟n+1的問題是一樣的,發出了n+1條sql語句。為什麼會出現這樣的情況呢?這是因為我們現在查詢的是實體物件,查詢快取會把第一次查詢的實體物件的id放到快取裡,當第二個session再次呼叫list方法時,它會到查詢快取裡把id乙個乙個的拿出來,然後到相應的快取裡找(先找一級快取找不到再找二級快取),如果找到了就返回,如果還是沒有找到,則會根據乙個乙個的id到資料庫中查詢,所以乙個id就會有一條sql語句。
注意:如果配置了二級快取,則第一次查詢實體物件後,會往一級快取和二級快取裡都存放。如果沒有二級快取,則只在一級快取裡存放。(一級快取不能跨session共享)
//開啟查詢快取,開啟二級快取
//在兩個session中呼叫list方法查詢實體物件
執行結果是第乙個session呼叫list方法會發出sql語句到資料庫裡查詢實體物件,因為配置了二級快取,則實體物件會放到二級快取裡,因為配置了查詢快取,則實體物件所有的id放到了查詢快取裡。第二個session呼叫list方法不會發出sql語句,而是到二級快取裡取資料。
查詢快取意義不大,查詢快取說白了就是存放由list方法或iterate方法查詢的資料。我們在查詢時很少出現完全相同條件的查詢,這也就是命中率低,這樣快取裡的資料總是變化的,所以說意義不大。除非是多次查詢都是查詢相同條件的資料,也就是說返回的結果總是一樣,這樣配置查詢快取才有意義。
Hibernate 所有快取機制詳解
hibernate 提供的一級快取 hibernate是乙個執行緒對應乙個session,乙個執行緒可以看成乙個使用者。也就是說session級快取 一級快取 只能給乙個執行緒用,別的執行緒用不了,一級快取就是和執行緒繫結了。hibernate一級快取生命週期很短,和session生命週期一樣,一級...
Hibernate 所有快取機制詳解
hibernate 提供的一級快取 hibernate是乙個執行緒對應乙個session,乙個執行緒可以看成乙個使用者。也就是說session級快取 一級快取 只能給乙個執行緒用,別的執行緒用不了,一級快取就是和執行緒繫結了。hibernate一級快取生命週期很短,和session生命週期一樣,一級...
Hibernate 所有快取機制詳解
hibernate 提供的一級快取 hibernate是乙個執行緒對應乙個session,乙個執行緒可以看成乙個使用者。也就是說session級快取 一級快取 只能給乙個執行緒用,別的執行緒用不了,一級快取就是和執行緒繫結了。hibernate一級快取生命週期很短,和session生命週期一樣,一級...