Hibernate上路_09-Session中的一级缓存

HIbernate有两级缓存:Session中为一级(内置),SessionFactory中为二级缓存(外置)。

1.缓存中对象的生命周期:

当对象成为持久态,即被放入一级缓存,生命直到session关闭。相关操作:save、update、get/load、Query、Criteria


2.缓存的清空:

一级缓存中的数据,会在某些时间点,同步到数据库。发生此动作时session执行flush操作。

1)提交事务:

transaction.commit();


2)手动刷出:

(1)

session.flush;
  

(2)

session.close();
  session 首先 flush ,然后 close 。 


3)被动刷出:

当调用查询语句时,一级缓存数据已经发生了变化,session会首先刷出缓存同步到数据库,然后返回查询结果。 


3.flush、clear、evict三个方法的使用:

1)证明一级缓存的存在:

(1)JavaBean重写toString()方法:

(2)查询:

@Test
	public void test() {

		Session session = UtilGetSession.openSession();
		Transaction transaction = session.beginTransaction();

		PojoUser user1 = (PojoUser) session.get(PojoUser.class, 3);
		System.out.println("第一次查询:"+user1);

  //第二次的id和上一次查询的id相同,将直接从缓存获取
		PojoUser user2 = (PojoUser) session.get(PojoUser.class, 3);
		System.out.println("第二次查询:"+user2);
		
		transaction.commit();
		session.close();
	}


2)flush方法,同步数据到数据库:

(1)原理:


(2)代码:

public void test() {
		Session session = UtilGetSession.openSession();
		Transaction transaction = session.beginTransaction();
	
		// step3 get方法获得持久化对象,从数据库返回后放入缓存和快照各一份 
		PojoUser user = (PojoUser) session.get(PojoUser.class, 3);
		System.out.println("第一次查询:"+user);
		//step5 set方法使缓存中的数据发生了变化 
		user.setName("Amelie");
		// step6 执行flush前先对比缓存和快照中的数据是否相同,不同则先执行update 
		session.flush();
		
		transaction.commit();
		session.close();
	}


(3)结果:


3)clear方法,清空一级缓存:

(1)代码:

public void test() {
		Session session = UtilGetSession.openSession();
		Transaction transaction = session.beginTransaction();
		
		PojoUser user1=(PojoUser)session.get(PojoUser.class, 3);
		System.out.println(user1);
		
		session.clear();	//清空缓存
		
		//一级缓存中已经没有持久化对象了,重新生成
		PojoUser user2=(PojoUser)session.get(PojoUser.class, 3);
		System.out.println(user2);
		
		transaction.commit();
		session.close();
	}


(2)结果:


4)evit方法,清除指定缓存对象:

public void test() {

		Session session = UtilGetSession.openSession();
		Transaction transaction = session.beginTransaction();
	
		
		PojoUser user1=(PojoUser)session.get(PojoUser.class, 3);
		System.out.println(user1);
		
		session.evict(user1);	//清空缓存中的指定持久化对象
		
		//一级缓存中已经没有指定的持久化对象了,重新生成
		PojoUser user2=(PojoUser)session.get(PojoUser.class, 3);
		System.out.println(user2);
		
		transaction.commit();
		session.close();
	}


4.快照:

在一级缓存中存放数据时,都会保存一个备份,即快照。执行flush操作时,会对比缓存数据是否和快照相同,否则执行update。

持久化对象因为快照的存在,会自动更新数据库;无需手动update。


5.refresh,刷新一级缓存:

重新从数据库加载数据,覆盖原一级缓存。

(1)代码:

public void test() {
		Session session = UtilGetSession.openSession();
		Transaction transaction = session.beginTransaction();
	
		PojoUser user=(PojoUser)session.get(PojoUser.class, 3);
		System.out.println(user);
		user.setName("Michael Jackson");	//更新一级缓存
		
		//从数据库读取数据,覆盖原一级缓存。导致上面的set操作无效 
		session.refresh(user);
		System.out.println(user);
		
		System.out.println(user);
		
		transaction.commit();
		session.close();
	}


(2)结果:


6.flushmode,设置一级缓存刷出时间:

AUTO:介于COMMIT和ALWAYS。默认。 

COMMIT:事务提交Transaction.commit()时进行刷出 

ALWAYS:每次查询前都会刷出 

MANUAL:必须手动调用Session.flush()才会刷出。当事务提交亦不会刷出;Query查询亦不刷出 

刷出力度:Session.flush > Transaction.commit > Query查询

1)级别为manual:

    Session.flush();  

2)级别为commit:

    Session.flush();  

    Transaction.commit;  

3)级别为always:

    Session.flush();  

    Transaction.commit;  

    Query查询操作;  

刷出级别:MANUAL > COMMIT > AUTO > ALWAYS。


代码:

Session.setFlushMode(FlushMode.ALWAYS);


- end

转载于:https://my.oschina.net/vigiles/blog/175739

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值