Hibernate(二)一级缓存、快照机制和三种状态

一、Hibernate的一级缓存
  Hibernate的一级缓存就是指Session缓存,Session缓存是一块内存空间,用来存放相互管理的java对象,在使用Hibernate查询对象的时候,首先会使用对象属性的OID值在Hibernate的一级缓存中进行查找,如果找到匹配OID值的对象,就直接将该对象从一级缓存中取出使用,不会再查询数据库;如果没有找到相同OID值的对象,则会去数据库中查找相应数据。当从数据库中查询到所需数据时,该数据信息也会放置到一级缓存中。Hibernate的一级缓存的作用就是减少对数据库的访问次数。(实体类中映射主键的字段就是OID 在映射文件中对应数据库主键的属性)
  Hibernate通过一级缓存实现事务的开始begin(),回滚rollback(),提交commit()

  • 对缓存的操作
    • evict(object)清除指定对象的缓存
    • clear()清除一级缓存中所有数据
    • flush()强刷一级缓存到数据库中 (事务提交commit()和session.close()都会调用flush())

二、快照机制
  Hibernate向一级缓存放入数据时,同时复制一份数据放入到Hibernate快照中,当使用commit()方法提交事务时,同时会清理Session的一级缓存,这时会使用OID判断一级缓存中的对象和快照中的对象是否一致,如果两个对象中的属性发生变化,则执行update语句,将缓存的内容同步到数据库,并更新快照;如果一致,则不执行update语句。Hibernate快照的作用就是确保一级缓存中的数据和数据库中的数据一致。

证明快照和缓存的存在

package testall;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import test.User;

public class testcfg { 

	public static void main(String[] args) { 
		//1、加载classpath下的hibernate.cfg.xml配置文件(配置文件位置一定放对)
		Configuration configure = new Configuration().configure();
		//2、创建会话连接工厂
		SessionFactory sessionFactory = configure.buildSessionFactory();
		//3、创建session
		Session session = sessionFactory.openSession();
		//4、开启事务
		Transaction transaction = session.beginTransaction();
		
		User user = session.get(User.class, 1);
		session.evict(user);	//从一级缓存中移除user,证明缓存的存在
		user.setName("Allen");	//测试是否会发送update语句,证明快照的存在
		//5、提交事务
		transaction.commit();
		//6、关闭连接
		session.close();
		sessionFactory.close();
	}

}

结果只生成了一条sql语句
《Hibernate(二)一级缓存、快照机制和三种状态》
发生的变化如图
《Hibernate(二)一级缓存、快照机制和三种状态》
解析: 通过清除一级缓存中的user,再提交事务,令一级缓存中的数据与快照区中的进行对比,但此时一级缓存中已经没有user对象了,所以没有与快照区中user相同OID的缓存数据,不会生成Update语句

三、hibernate的三种状态

《Hibernate(二)一级缓存、快照机制和三种状态》
瞬时状态(transient)
  刚new出来的一个对象,session中和数据库中都不存在该对象
持久化状态(persistent)
  存在于session缓存当中,瞬时对象调用save或update方法,或者离线对象调用get或load方法可以使该状态变为持久化状态
脱管状态(detached)
  数据库中存在该对象,但是该对象又没有被session托管
《Hibernate(二)一级缓存、快照机制和三种状态》

误区
1、在事务提交前使用evict(Object)、clear()都会使session中对应Object的缓存清空,导致提交对应事务时,没有发生变化。
2、当对象由瞬时状态变为持久化状态后,如果修改他的OID,就会发生异常,因为OID是快照和缓存的对象识别标志。
3、在没有对缓存进行操作时,commit前多次update(obj)和save(obj)持久化状态是冗余的。
4、持久化状态的对象可以在数据库中,也可以不在。
5、get找不到对象时,返回null,load找不到对象时,抛异常

    原文作者:「已注销」
    原文地址: https://blog.csdn.net/Another_dream/article/details/89161888
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞