Hibernate缓存复习

引言

Session的缓存其实就是一块内存空间,在这个内存空间里存放了相互关联的java对象。这种位于缓存内的对象也叫做

持久化对象,Session负责根据持久化对象的状态变化来同步更新数据库。

一级缓存

当应用程序调用Session的save(),update,saveOrUpdate(),load(),get()或find,
以及调用查询接口的list(),iterate()或filter()方法时,如果在Session的缓存中
还不存在相应的对象,Hibernate就会把该对象加入到第一级缓存中。当清理缓存时,
Hibernate会根据缓存中对象的状态变化来同步更新数据库。
我们可以调用下面的方法来清除缓存。
1.session.evict(Object obj):从缓存中清除参数指定的持久化对象。
2.session.clear():清空缓存中所有持久化对象。
当session.evict()将对象从缓存中清除后,如果session再次加载OID相同的Student对象,
它会重新创建一个Studnet对象,如下:

StudentModel stu=new StudentModel(new Integer(10), "yanan");
		
		SessionFactory sessionFactory=MySessionFactory.getInstance(StudentModel.class);
		Session session=sessionFactory.openSession();
		
		session.evict(stu);
		
		StudentModel stu2=(StudentModel) session.load(StudentModel.class, new Integer(10));
		System.out.println(stu2==stu);
		System.out.println(session.contains(stu2));
		System.out.println(session.contains(stu));

注意:

1.get(),load()区别:
区别1:如果数据库中,没有userId的对象。如果通过get方法加载,则返回的是一个null;
如果通过load加载,则返回一个代理对象,如果后面代码如果调用user对象的某个属性(比如user.getPassword())会
抛出异常:org.hibernate .ObjectNotFoundException;
区别2:load支持延迟加载,get不支持延迟加载。
也就是说:
Java代码
Users user = (Users)session.load(Users. class , userId);  
这句代码不会去执行数据库查询,只有用到user时才会去执行数据库查询。
而:
Java代码
Users user = (Users)session.get(Users. class , userId);  
则立即去执行数据库查询。 所以Users user = (Users)session.load(Users.class, userId);不会执行任何sql。
注意:
Java代码
Users user = (Users)session.load(Users. class , userId);  
System.out.println(user.getId());  
上面这2句代码,不会去执行数据库操作。因为load后会在hibernate 的一级缓存里存放一个map对象,
该map的key就是userId的值,但是当你getId()时,它会去一级缓存里拿map的key值,而不去执行数据库查询。
所以不会报任何错。不会执行任何数据库操作。

2.OID:
在关系数据库中,主键用来识别记录,并保证每天记录的唯一性。在Java语言中,
通过比较两个变量所引用对象的内存地址是否相同,或者比较两变量引用的对象
是否相等。Hibernate为了解决两者之间的不同,使用对象标识符(OID)来标识
对象的唯一性。OID是关系数据库中主键在Java对象模型中的等价物。
在运行时,Hibernate根据OID来维持Java对象和数据库中的对应关系。如下所示:
Transaction tx = session.beginTransaction();
User user1 = (User)session.load(User.class,new Long(1));
User user2 = (User)session.load(User.class,new Long(1));
User user3 = (User)session.load(User.class,new Long(3));
应用程序在执行上述代码时,第一次OID为1的对象,从数据库中查找ID为1的记录,
然后创建想要的User实例,并把它保存到session的缓存中,最后将该实例的引用
赋值给变量user1,第二次加载OID为1的对象时,直接把session缓存中的OID为1的
实例的引用赋值给user2,因此user1=user2的结果为true

当通过Session的evict()方法清除缓存中一个对象,如果在映射文件中映射关联关系
的cascade属性为all或者all-delete-orphan,会级联清除关联的对象。

通常不提倡通过session的evict()和clear()来管理一级缓存,因为他们并不能显著提高
程序性能。管理一级缓存最有效的办法是:采用合理的检索条件和检索方式。


二级缓存

你可能感兴趣的:(Hibernate,cache)