Hibernate:一級快取
阿新 • • 發佈:2018-12-17
什麼是快取:
快取將資料庫/硬碟上檔案中資料,放入到快取中(就是記憶體中一塊空間).當再次使用的使用,可以直接從記憶體中獲取.
快取的好處:
提升程式執行的效率.快取技術是Hibernate的一個優化的手段.
Hibernate分成兩個基本的快取:
-
一級快取:Session級別的快取.一級快取與session的生命週期一致.自帶的.不可解除安裝.
-
二級快取:SessionFactory級別的快取.不是自帶的.
一級快取的生命週期和session的生命週期一致,當前sessioin一旦關閉,一級快取就消失,session間不能共享一級快取的資料,因此一級快取也叫session級的快取或事務級快取。一級快取只存實體物件的 ,它不會快取一般的物件屬性(查詢快取可以),即當獲得物件後,就將該物件的快取起來,如果在同一session中如果再去獲取這個物件時,它會先判斷快取中有沒有該物件的id,如果有就直接從快取中取出,反之則去資料庫中取,取的同時將該物件的快取起來.
圖解:
以下對hibernate的一級快取進行程式碼測試: 1.1:hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- 1. 資料庫相關 --> <property name="connection.username">root</property> <property name="connection.password">123</property> <property name="connection.url">jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <!-- 連線MySQL資料庫 --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 2.配置本地事務(No CurrentSessionContext configured!) --> <property name="hibernate.current_session_context_class">thread</property> <!-- 3. 除錯相關 --> <property name="show_sql">true</property> <property name="format_sql">true</property> <!-- 4.hibernate需要管理的資料庫表對應的實體類對映檔案 --> <mapping resource="com/zking/one/entity/User.hbm.xml"></mapping> </session-factory> </hibernate-configuration>
1.2:實體類:User.java
public class User implements Serializable { private Integer id; private String userName; private String userPwd; public User() { super(); } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPwd() { return userPwd; } public void setUserPwd(String userPwd) { this.userPwd = userPwd; } @Override public String toString() { return "User [id=" + id + ", userName=" + userName + ", userPwd=" + userPwd + ", realName=" + realName + ", sex=" + sex + ", birthday=" + birthday + ", createDatetime=" + createDatetime + ", remark=" + remark + "]"; } }
1.3:User.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class table="t_hibernate_user" name="com.zking.one.entity.User">
<id name="id" type="java.lang.Integer" column="id">
<generator class="increment"></generator>
</id>
<property name="userName" type="java.lang.String" column="user_name"></property>
<property name="userPwd" type="java.lang.String" column="user_pwd"></property>
</class>
</hibernate-mapping>
1.4:測試方法:
public class Demo3 {
Session session= SessionFactoryUtils.getSession();
Transaction transaction = session.beginTransaction();
User user = session.get(User.class, 2); // 馬上生成sql語句去查詢
System.out.println(user.getRealName());
User user = session.get(User.class, 2); //不會發出sql,因為使用一級快取的資料
System.out.println(user.getRealName());
// 3.提交事務
tx.commit();
// 4.關閉資源
session.close();
}
1.5:深入理解一級快取中快照區:
public void demo4(){
// 1.建立Session
Session session= SessionFactoryUtils.getSession();
// 2.開啟事務
Transaction transaction = session.beginTransaction();
// 獲得一個持久態的物件.然後資料會分別放到一級快取區和一級快取快照區
User user = session.get(User.class, 2);
//user的名字改變了,一級快取和快照區資料不一致,事務提交的時候傳送SQL進行更新
user.setRealName("是不是傻");
// 3.提交事務
tx.commit();
// 4.關閉資源
session.close();
}
結論:向一級快取存入資料的時候,放入一級快取區和一級快取快照區,當更新了一級快取的資料的時候,事務一旦提交,比對一級快取和快照區,如果資料一致,不更新,如果資料不一致,自動更新資料庫.