Hibernate 的 session 物件有一種 cache 機制, 可維護一份您存取資料後的 instance.
因為存取資料庫的連線, 需要不小的開銷. 該機制將存取 persistence object 的結果讀進記憶體(利用一份map物件來維護), 若在 session 結束後, 有相同的SQL操作, 則 cache 機制可以直接將物件回傳, 不用再執行額外的資料庫連線動作; 而這種存活於 session 內的 cache 機制, 又稱為 session Level cache.
用一簡例說明:
....
session.beginTransaction();
Person aPerson = (Person) session.load(Person.class, personId);
aPerson.getAge();
Person aPerson2 = (Person) session.load(Person.class, personId);
aPerson2.getAge();
session.getTransaction().commit();
session.close();
....
您可以觀察 console 內SQL的執行:
Hibernate: select person0_.PERSON_ID as
PERSON1_2_0_, person0_.age as age2_0_, person0_.firstname as
firstname2_0_, person0_.lastname as lastname2_0_ from PERSON person0_
where person0_.PERSON_ID=?
我們可以發現, 雖然 session.load() 呼叫了兩次, 但由於 cache 機制,會直接回傳記憶體中的物件給 aPerson2 存取, 如此便減少了一次資料庫的連線成本
但有時存取過於頻繁, cache 內有太多的物件有可能會導致 OutOfMemory,
若您想釋放 cache 中的記憶體, 可以使用 session.clear(), session.evict(object),
另外 session.close() 也會結束該段 cache.
以上例而言:
...
Person aPerson = (Person) session.load(Person.class, personId);
aPerson.getAge();
session.evict(aPerson);
//session.clear()
Person aPerson2 = (Person) session.load(Person.class, personId);
aPerson2.getAge();
...
您會發現 console 會執行兩段SQL指令, 因為 session 中的 cache 已被清除了,session.load()找不到對應的資料, 就會再重起一段資料連線.
Reference:
Hibernate Gossip: 簡介快取(Session Level)
Reference Documentation
0 意見:
張貼留言