Hibernate持久层状态变化

Hibernate里有三种对象状态:临时状态 (Transient)、持久状态(Persistent)、游离状态(Detached)

状态表格

表格中是否在缓存指Session缓存或者JPA的Persistence Context

状态对象是否在缓存是否在数据库当前对象与数据库是否有对应关系备注
临时状态 (Transient)临时对象new一个对象,或者从另外两个状态转换来
持久状态(Persistent)持久对象进行了增加,更新操作,或者加载自数据库
游离状态(Detached)游离对象曾经有,现在无从session缓存中移除,但是不移除数据库记录

一级缓存

    也称为session缓存,它和session生命周期相同,周期比较短,属于事务隔离级别。

  1. Session内置不能被卸载
  2. Session的缓存是事务范围的缓存
  3. Session对象的生命周期通常对应一个数据库事务或者一个应用事务
实现原理:

  hibernate的缓存是通过集合实现的,hibernate中封装了list和map的集合。hibernate向一级缓存中存放数据时,同时保存快照数据,当执行flush()时,会对比一级缓存中的数据和快照中的数据是否一致,如果不一致,则执行更新。

用处:

    当要查询的数据在缓存中已经存在时,hibernate将不会再向数据库发送查询语句,而是直接从缓存中获取对象。

session方法
flush()
evict()
load()
save()
saveOrUpdate()
update()
merge()
persist()
delete()
refresh()
get()
PS:

    session.get()、load(支持一级缓存。createQuery()不支持一级缓存,即即使是两次相同的查询,获得list也是相同的,也会向数据库发起2次查询

Session方法概要解说:

flush()
将缓存同步到数据库,首先会将缓存数据和快照区数据进行对比,如果相同,就不会发送update()语句,如果不同,则执行update()语句,所以不一定会很发生update()语句到数据库。

      session.beginTransaction();  

        // 通过ID从数据库中获取值,此时会产生快照  
        Book book1 = (Book) session.get(Book.class, 1);  
        // 修改属性值  
        book1.setName("xxx");  
        // 手动flush,刷新缓存到数据库,此时只是生成SQL语句,但是数据库中并没有发生变化,只有commit后,数据库才会发生相应的变化。  
        session.flush();  
        // 手动提交事务  
        session.getTransaction().commit();  
        // 关闭session的资源  
        session.close();

refresh()
将数据库中的数据同步到缓存中,这个过程一定会产生更新语句(是查询语句吧?),同步一级缓存和快照

        session.beginTransaction();  

        // 从数据库中查询book,并放置到Session缓存中一份  

        Book book1 = (Book) session.get(Book.class, 1);   
        //修改缓存对象的值  
        book1.setName("xxx");   

        //又进行了一次查询操作,此时把快照中的数据与数据库一致  
        session.refresh(book1);  

        System.out.println(book1);  

        // 4.提交食物  
        session.getTransaction().commit();  
        // 5.关闭session资源 
        session.close();

clear()
清除所有对象的一级缓存,对对象的所有操作,全部失效,回复到当初和快照一样
   

        // 启动事务操作  
        session.beginTransaction();  

        // session.setFlushMode(FlushMode.MANUAL);  

        // 通过ID从数据库中获取值,此时会产生快照  
        Book book1 = (Book) session.get(Book.class, 1);  
        // 修改属性值  
        book1.setName("xxx");  
        //清除一级缓存操作,此时当作事务提交的时候,数据库中并没有发生任何的变化  
        session.clear();  
        // 手动提交事务  
        session.getTransaction().commit();  
        // 关闭session的资源  
        session.close(); 

evict()
对指定的对象清除一级缓存

         session.beginTransaction();  

        //当执行一次操作后,会把对象放置到Session缓存中  
        Book book1 = (Book) session.get(Book.class, 1);  
        Book book2 = (Book) session.get(Book.class, 2);   
        // 从缓存中清除book2对象所做的修改 
        session.evict(book2); 
        // 当再次执行操作时,book2还会发出SQL语句操作  
        Book book11 = (Book) session.get(Book.class, 1);   
        Book book22 = (Book) session.get(Book.class, 2);  

        // 手动提交事务  
        session.getTransaction().commit();  
        // 关闭资源  
        session.close(); 

session缓存中entity生命周期图

一、Hibernate中Session方法

get()/load()/Query.list()/Query.uniqueResult()/Query.iterator()/Query.scoll() 从数据库载出来的对象,即是持久对象,对应状态为持久状态

这里写图片描述

JPA中的EntityManager

在我们介绍EntityManager API之前,我们先来看看Persistence Context的概念。一个Persistence Context就是针对一个事物中一段时间内一群被管理的Entity的集合。多个具有相同唯一标识的Entity实例不能存在于同一个Persistence Context中。例如,一个Book实例的ID是12,此时就不能有第二个ID也是12的Book实例存在于相同的Persistence Context中了。只有存在于Persistence Context中的Enitity才会被EntityManager所管理,它们的状态才会反映到数据库中。Persistence Context可以被看成一个一级缓存,它可以被EntityManager当作存放Entity的缓存空间。默认情况下,Entity在Persistence Context存活,直到用户的事物结束。

事务范围内的缓存Persistence Context

这里写图片描述

EntityManager中entity生命周期

在JPA中,所有的Entity都是通过javax.persistence.EntityManager的API来管理和操纵的。当EntityManager管理Entity时,所有的Entity都会有一个唯一标识(这个标识通常是主键列),Entity的状态将会和数据库同步。当Entity脱离EntityManager的管理时,Entity就变成了一个普通的Java对象实例,这时它的状态是detached。
当我们用new关键字创建一个新Entity时,这个Entity对象存在于内存中,JPA对它没有任何了解。只有当EntityManager开始管理它时,它的状态才会和数据库同步。当调用了EntityManager.remove方法后,它就会从数据库中删除掉,但Java对象还会在内存中存在,直到被垃圾回收掉

这里写图片描述

EntityManager的方法

persist()
merge()
remove()
find()
flush()
refresh()
detach()
getReference()

session方法与Entitymanager方法对比

二者的联系

SessionFactory 对应 EntityManagerFactory;

Session 对应 EntityManager;

SessionFactory是线程安全的,Session不是线程安全的;

EntityManager 是线程安全的;


引用文章:

https://www.cnblogs.com/yuwenhui/p/7494076.html
https://blog.csdn.net/tantexian/article/details/50523270
https://blog.csdn.net/54powerman/article/details/61196215

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值