Hibernate(三)session缓存机制和三种对象状态

    xiaoxiao2021-08-14  131

    Hibernate(三)session缓存机制和三种对象状态

    hibernate向我们提供的主要的操纵数据库的接口,Session就是其中的一个,它提供了基本的增,删,改,查方法.而且具有一个缓存机制,能够按照某个时间点,按照缓存中的持久化对象属性的变化来更新数据库,着就是Session的缓存清理过程. 在Hibernate中对象分为三个状态,临时,持久化,游离. 如果我们希望Java里的一个对象一直存在,就必须有一个变量一直引用着这个对象.当这个变量没了.对象也就被JVM回收了. 这篇博客我们就带大家一起来看一下session的缓存机制,也就是hibernate的一级缓存,还有hibernate三种对象状态的详细情况。 当Session的save()方法持久化一个Customer对象时,Customer对象被加入到Session的缓存中,以后即使应用程序中的引用变量不再引用Customer对象,只要Session的缓存还没有被清空,Customer对象仍然处于生命周期中。

    tx = session.beginTransaction(); Customer c1=new Customer(“zhangsan",new HashSet()); //Customer对象被持久化,并且加入到Session的缓存中 session.save(c1); Long id=c1.getId(); //c1变量不再引用Customer对象 c1=null; //从Session缓存中读取Customer对象,使c2变量引用Customer对象 Customer c2=(Customer)session.load(Customer.class,id); tx.commit(); //关闭Session,清空缓存 session.close(); //访问Customer对象 System.out.println(c2.getName()); // c2变量不再引用Customer对象,此时Customer对象结束生命周期。 c2=null;

    当session调用save保存一个对象时,这个对象就被加载到session缓存当中,其实save方法有一个返回值,返回一个seriaseble接口类型的数据,我们知道像基本数据类型的包装类型都实现了这个接口,其实这个返回值我们可以理解为保存对象的id,我们在很多时候都能用到这个返回值,这是一个应该注意的地方。 当对象被save到缓存中时,我们就可以调用对象的getid方法来获得他的id了。 在上面的示例中我们可以看到,虽然c1被复位null了,但是此时在session缓存里面还是有一个变量指向着该对象,所以该对象才不被垃圾回收器回收,当我们在此利用该对象的id去用load查询时,其实还是去到session缓存去找并且返回该对象,当session关闭后。缓存清空。



    tx = session.beginTransaction(); Customer c1=(Customer)session.load(Customer.class,new Long(1)); Customer c2=(Customer)session.load(Customer.class,new Long(1)); System.out.println(c1==c2); // true or false ?? tx.commit(); session.close();

    很明显,这个示例最后打印出来的是***true***,load没有生成出来sql语句,load方法在查询时,其实是获得的该对象的一个代理的对象,当我们用到查询到的对象时,他才会去数据库进行查询. 如果我们***调用c1.getName方法,这时就会打印出sql语句来***,这时候他才真正的去数据库查询,而get方法,他在执行get的方法的时候就会去数据库查询,产生sql语句


    Session缓存的作用

    (1)减少访问数据库的频率。应用程序从内存中读取持久化对象的速度显然比到数据库中查询数据的速度快多了,因此Session的缓存可以提高数据访问的性能。

    (2)保证缓存中的对象与数据库中的相关记录保持同步。当缓存中持久化对象的状态发生了变化,Session并不会立即执行相关的SQL语句,这使得Session能够把几条相关的SQL语句合并为一条SQL语句,以便减少访问数据库的次数,从而提高应用程序的性能。


    Session的清理缓存

    清理缓存是指按照缓存中对象的状态的变化来同步更新数据库,下面我们还是具体来看一段代码:以下程序代码对Customer的name属性修改了两次:

    tx = session.beginTransaction(); Customer customer=(Customer)session.load(Customer.class, new Long(1)); customer.setName("Jack"); customer.setName("Mike"); tx.commit();

    当Session清理缓存时,只需执行一条update语句:

    update CUSTOMERS set NAME= ‘Mike’…… where ID=1;

    其实第一次调用setName是无意义的,完全可以省略掉。

    Session缓存在什么时候才清理呢?我们来看一下:

    Session会在下面的时间点清理缓存:

    1. 当应用程序调用org.hibernate.Transaction的commit()方法的时候,commit()方法先清理缓存,然后再向数据库提交事务。

    2. 当应用程序显式调用Session的flush()方法的时候,其实这个方法我们几乎很少用到,因为我们一般都是在完成一个事务才去清理缓存,提交数据更改,这样我们直接提交事务就可以。


    Hibernate中java对象的三种状态:

    1、临时状态(transient):刚刚用new语句创建,还没有被持久化,不处于Session的缓存中。处于临时状态的Java对象被称为临时对象。

    2、持久化状态(persistent):已经被持久化,加入到Session的缓存中。处于持久化状态的Java对象被称为持久化对象。

    3、***游离状态(托管状态)***(detached):已经被持久化,但不再处于Session的缓存中。处于游离状态的Java对象被称为游离对象,session被关闭时。


    持久化状态和临时状态的不同点在于:

    1、对象持久化状态时,他已经和数据库打交道了,在数据库里面存在着该对象的一条记录。

    2、持久化状态的对象存在于session的缓存当中。

    3、持久化状态的对象有自己的OID。

    游离状态的对象与持久化状态的对象不同体现在游离状态的对象已经不处于session的缓存当中,并且在数据库里面已经不存在该对象的记录,但是他依然有自己的OID。


    转载请注明原文地址: https://ju.6miu.com/read-676299.html

    最新回复(0)