1. 程式人生 > >Hibernate的一級快取與快照

Hibernate的一級快取與快照

什麼是一級快取

Hibernate的一級快取就是指session快取。當Hibernate查詢物件時,會先通過oid屬性查詢一級快取,若一級快取中存在物件,則直接從一級快取中取出該物件。若一級快取中不存在則從資料庫中查詢,從資料庫中查詢到資料,該資料也會放置到一級快取當中。

一級快取的作用就是減少對資料庫的訪問次數,提高效率

證明一級快取的存在

@Test
	//證明一級快取的存在,若一級快取存在獲取多個物件只會列印一個sql語句,並輸出結果為true,證明他們是同一個物件
	public void test(){
		Session s = HibernateUtils.openSession();
		Transaction t = s.beginTransaction();
	
		Customer c = new Customer();
		Customer customer = s.get(Customer.class, 1l);
		Customer customer2 = s.get(Customer.class, 1l);
		//輸出結果為true
		System.out.println(customer==customer2);
		
		t.commit();
		s.close();
	}

一級快取的內部結構 快照區

Hibernate向一級快取中寫入資料時,會同時複製一份資料到一級快取中的快照區。當事務使用commit()方法提交時,同時會清理一級快取。這時會通過oid進行查詢屬性,若一級快取中的屬性與快照區的屬性不同,則使用update()方法進行更新,然後再寫入資料庫。如相同則不執行update()方法

快照區的作用是確保Hibernate的資料與資料庫的資料一致

證明快照的存在1

//證明快照的存在,最終修改的值等於快照的值,那它就不會列印sql語句update資料
	@Test
	public void test2(){
		Session s = HibernateUtils.openSession();
		Transaction t = s.beginTransaction();
		
		Customer c = s.get(Customer.class,1l);
		c.setCust_name("快照中不存在的資料");
		
		//我資料庫中oid為1L的資料name為“聯想”
		c.setCust_name("聯想");
		
		t.commit();
		s.close();
	}

證明快照的存在2

@Test
	//無論如何都會列印update語句,因為經過資料庫返回才有快照,這裡快照和以及快取不一致
	public void test3(){
		Session s = HibernateUtils.openSession();
		Transaction t = s.beginTransaction();
		
		Customer c = new Customer();//瞬時狀態
		c.setCust_id(1l);//遊離態
		s.update(c);	//持久態
		Customer c2 = s.get(Customer.class, 1l);
		
		t.commit();
		s.close();
	}