hibernate(二)缓冲机制

                                         Hibernate的缓存机制

       缓存(Cache): 计算机领域非常通用的概念。它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能。缓存中的数据是数据存储源中数据的拷贝。缓存的物理介质通常是内存,所以读写速度很快。但如果缓存中存放的数据量非常大时,也会用硬盘作为缓存介质。缓存的实现不仅仅要考虑存储的介质,还要考虑到管理缓存的并发访问和缓存数据的生命周期。

. 为什么要用Hibernate缓存:

    Hibernate是一个ORM框架,会经常访问物理数据库。因此为了降低应用程序对数据库的访问频次,从而提高了应用程序的运行性能。

. Hibernate二种缓存(session缓存和sessionFactory缓存)

1. Session的缓存。

           Session内置的缓存是不能被卸载的,Session的缓存是事务范围的缓存,即对应一个数据库事务或者一个应用事务的生命周期(例如买火车票这个动作,库存减一,买家加一,这就是一个事务),一级缓存中,持久化类的每个实例都具有唯一的OID,一级缓存存放的是数据库数据的拷贝。

(1)持久化对象:把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的对象存储在关系型的数据库中,当然也可以存储在磁盘文件中、XML数据文件中等等。

持久化对象有三种状态,分别是:

1、构造对象--瞬时状态  session中没有,数据库中没有

2、持久状态--被session管理  session 中有 数据库中有

3、游离状态(托管状态)--不在Session的缓存中,不与任何的Session实例相关联。在数据库中存在与之相对应的记录。(前提条件是没有其他Session实例删除该条记录)。

具体转换过程:

       新new出来的对象如Student stu = new Student(),就是瞬时对象,它在内存中孤立存在,它的意义是携带信息的载体,不和数据库的数据有任何关联。

      通过Sessionsave()saveOrUpdate()方法可以把一个瞬时对象与数据库相关联,并把瞬时对象携带的信息通过配置文件所做的映射插入到数据库中,这个瞬时对象就转化成了持久对象

      如果这时候使用delete()方法删除stud对象,它就会变回瞬时对象,删除了数据库与这个对象关联的记录,对象与数据库不再有任何的关联

扫描二维码关注公众号,回复: 10463262 查看本文章

      使用get(),load()等方法查询到的数据对象,一开始就是持久对象),并拥有和数据库记录相同的id标识(Hibernate自动将id值赋予它).

      当一个Session指定close()clear(),evict()之后,持久对象就变成游离状态。游离对象的引用依然有效,对象可以继续被修改,当它重新被关联到某个新的Session上时,会再次变成持久对象(游离状态期间的改动将被持久化到数据库上(脏数据检查))。游离对象拥有数据库识别值id,所以它可以通过update(),saveOrUpdate(),lock()等方法,再度与持久层关联。

                                      

(2)脏数据检查

         脏数据:状态前后发生变化的数据

         我们看下面的代码:


Transaction tx=session.beginTransaction();

User user=(User)session.load(User.class,”1”);//从数据库中加载符合条件的数据

user.setName(“zx”);//改变了user对象的姓名属性,此时user对象成为了所谓的“脏数据”

tx.commit();

      当事务提交时,Hibernate会对session中的PO(持久化对象)进行检测,判断持久化对象的状态是否发生了改变,如果发生了改变就会将改变更新到数据库中。这里就存在一个问题,Hibernate如何来判断一个实体对象的状态前后是否发生了变化。也就是说Hibernate是如何检查出一个数据已经变脏了。

      通常脏数据的检查有如下两种办法: 

         A、数据对象监控:

        数据对象监控是通过拦截器对数据对象的setter方法进行监控来实现的,这类似于数据库中的触发器的概念,当某一个对象的属性调用了setter方法而发生了改变,这时拦截器会捕获这个动作,并且将改属性标志为已经改变,在之后的数据库操作时将其更新到数据库中。这个方法的优点是提高了数据更新的同步性,但是这也是它的缺点,如果一个实体对象有很多属性发生了改变,势必造成大量拦截器回调方法的调用,这些拦截器都是通过Dynamic Proxy或者CGLIB实现的,在执行时都会付出一定的执行代价,所以有可能造成更新操作的较大延时。

        B、数据版本比对:

        这种方法是在持久化框架中保存数据对象的最近读取版本,当提交数据时将提交的数据与这个保存的版本进行比对,如果发现发生了变化则将其同步跟新到数据库中。这种方法降低了同步更新的实时性,但是当一个数据对象的很多属性发生改变时,由于持久层框架缓存的存在,比对版本时可以充分利用缓存,这反而减少了更新数据的延迟。

       在Hibernate中是采用数据版本比对的方法来进行脏数据检查的

抄自:https://blog.csdn.net/zhangzeyuaaa/article/details/18353127

       

    2.SessionFactory的缓存。由于SessionFactory对象的生命周期和应用程序的整个过程对应,因此Hibernate二级缓存是进程范围或者集群范围的缓存,有可能出现并发问题,因此需要采取并发访问策略达到事务隔离。通俗点将:基于应用程序级别的缓存, 可以跨多个session,即不同的session都可以访问缓存数据

SessionFactory的缓存可以分为两类:

       内置缓存: SessionFactory的内置缓存和Session的缓存在实现方式上比较相似,前者是SessionFactory对象的一些集合属性包含的数据,后者是指Session的一些集合属性包含的数据。内置缓存中存放了映射元数据和预定义SQL语句,映射元数据是映射文件中数据的拷贝,而预定义SQL语句是在Hibernate初始化阶段根据映射元数据推导出来,SessionFactory的内置缓存是只读的,应用程序不能修改缓存中的映射元数据和预定义SQL语句,因此SessionFactory不需要进行内置缓存与映射文件的同步。

       外置缓存(二级缓存): SessionFactory的外置缓存是一个可配置的插件。在默认情况下,SessionFactory不会启用这个插件。外置缓存的数据是数据库数据的拷贝,外置缓存的介质可以是内存或者硬盘。SessionFactory的外置缓存也被称为Hibernate的第二级缓存。第二级缓存是可选的,可以在每个类或每个集合的粒度上配置第二级缓存。

    什么数据适合存放在二级缓存中呢?

    1)很少被修改的数据

    2)不太重要的数据,允许偶尔出现并发的数据

    3)不会被并发访问的数据

    4)常量数据

. Hibernate缓存何时被清除:

    1. commit()方法被调用的时候。

    2. 执行查询时会清除缓存,从而保证查询结果能反映对象的最新状态。

    3. 显式调用sessionflush()方法。

4. 当对象使用native生成器时,会立刻清理缓存向数据库中插入记录。

综合自:(1)https://blog.csdn.net/xc121566/article/details/78830253

              (2)https://www.jb51.net/article/113116.htm

 

发布了14 篇原创文章 · 获赞 1 · 访问量 5529

猜你喜欢

转载自blog.csdn.net/Vpn_zc/article/details/82784003