Hibernate 所有快取機制詳解

2021-09-02 09:54:28 字數 2780 閱讀 2759

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生命週期一樣,一級...