SSH系列:Hibernate中的一级缓存和快照

      一级缓存session:线程级别。 二级缓存:进程级别
      快照:
      1、快照是数据的副本 
      2、快照属于一级缓存 
      3、快照是在堆内存中的 
      4、快照的作用:保证数据一致性 
      5、快照的理解:当执行session.getTransaction().commit()时,
      Hibernate同时会清理session的一级缓存(flush),
      也就是将堆内存中的数据与快照中的数据进行对比,如果不一致,则会执行同步(update)操作,
      若相同,则不执行update。
    

举个栗子:
例1、如下代码的执行过程就是如图所示的执行过程,调用session.get()方法获取user对象是持久态,堆区存在一级缓存和快照。

@Test
	public void testCache1() {
		Session session = hibernateUtils.getOpenSession();
		User u1 = (User) session.get(User.class,1);  //持久态:有缓存,且有快照
		//u1.setUsername("");
		session.update(u1);
		session.beginTransaction().commit();
		session.close();
	}

 例2、如下代码的执行过程就是如图所示的执行过程,用new User()方法获取user对象是瞬时态,当执行session.update()时,对象转成持久态,堆区只存在一级缓存。


	@Test
	public void testCache2() {
		Session session = hibernateUtils.getOpenSession();
		User u1 = new User(); //瞬时态
		u1.setUsername("张三");
		session.update(u1);  //有缓存,但没有快照
		session.beginTransaction().commit();
		session.close();
	}
	

 

 3、如下案例根据sql语句的打印次数,判断存不存在一级缓存。

package hibernate;

import static org.junit.Assert.*;

import java.util.List;

import hibernateUtils.hibernateUtils;

import org.hibernate.Session;
import org.junit.Before;
import org.junit.Test;

public class TestCache {
	
	@Test
	/*三条查同一个id的语句,只会查找一次数据库,然后放进一级缓存session中,
	    第二第三次调用get方法就不会再查数据库,直接从一级缓存中取出
	 */
	public void testCache() {
		Session session = hibernateUtils.getOpenSession();
		User u1 = (User) session.get(User.class,1);
		User u2 = (User) session.get(User.class,1);
		User u3 = (User) session.get(User.class,1);
		System.out.println(u1);
		session.close();
	}
	
	@Test
	//hql:查询语句一共输出三次,所以hql没有缓存,更没有快照
	public void testCache3() {
		Session session = hibernateUtils.getOpenSession();
		List<User> list = session.createQuery("from User").list();
		List<User> list1 = session.createQuery("from User").list();
		List<User> list2 = session.createQuery("from User").list();
		session.close();
	}
	
	@Test
	//hql:createQuery 下面再调用Get方法就存在缓存了
	public void testCache4() {
		Session session = hibernateUtils.getOpenSession();
		List<User> list = session.createQuery("from User").list();  //打印select数据库的语句
		User u1 = (User) session.get(User.class,1);  //不打印sql语句,也就是没有查找数据库,说明有缓存
		session.close();
	}
	
	@Test
	//查询语句一共输出三次,所以createCriteria没有缓存
	public void testCache5() {
		Session session = hibernateUtils.getOpenSession();
		List<User> list = session.createCriteria(User.class).list();  
		List<User> list1 = session.createCriteria(User.class).list();  
		List<User> list2 = session.createCriteria(User.class).list();  
		session.close();
	}
	@Test
	//查询语句一共输出三次,所以createSQLQuery没有缓存
	public void testCache6() {
		Session session = hibernateUtils.getOpenSession();
		List list = session.createSQLQuery("select * from t_user").list();  
		List list1 = session.createSQLQuery("select * from t_user").list();
		List list2 = session.createSQLQuery("select * from t_user").list();
		session.close();
	}

	@Test
	//查询语句一共输出三次,所以createCriteria没有缓存
	public void testCache7() {
		Session session = hibernateUtils.getOpenSession();
		List<User> list = session.createSQLQuery("select * from t_user").addEntity(User.class).list();  
		List<User> list1 = session.createSQLQuery("select * from t_user").addEntity(User.class).list();  
		List<User> list2 = session.createSQLQuery("select * from t_user").addEntity(User.class).list();  
		session.close();
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_37891342/article/details/85727255