zoukankan      html  css  js  c++  java
  • hibernate一级缓存的源码初窥

      hibernate的一级缓存的存在使得hibernate可以在操作实体化对象的时候减少对于数据库的访问.hibernate的一级缓存实际上就是指的session缓存,它的生命周期和session相同.hibernate通过Map来实现一级缓存,Map里存储了持久化类的更新后的状态以及持久化类的副本(又称为快照).

      hibernate的session对象于一级缓存相关的结构图如下图所示:

      下面通过在eclipse环境下debug,来观察一级缓存在session进行刷新的时候,所涉及到的数据结构和操作.

      准备工作:

      在数据库中有一个category的表,它有两个字段,cid和cname,其中cid是auto_increment(自动增长)的.在domain包下面建立一个Category的实体类,它的属性名和字段完全保持一致.

      编写以下的代码,在session.flush这一行处打一个断点,debug运行,进入该行

    @Test
        public void testContent() {
            Session session=HibernateUtils.getCurrentSession();
            Transaction transaction = session.beginTransaction();
            Category category3=session.get(Category.class,2);
            category3.setCname("我很爱吃");
            session.flush();
            transaction.commit();
        }

      在断点处进入,并且向下运行,会跳入AbstractFlushingEventListener的flushEntities方法.从这个方法的描述如下:

      1.detect any dirty entities

      2. schedule any entity updates

      3.search out any reachable collections

      可以看出来,这个方法就是发现脏数据并且为更新操作做准备.这个方法有如下代码:

    final Map.Entry<Object,EntityEntry>[] entityEntries = persistenceContext.reentrantSafeEntityEntries();

      将鼠标移动到entityEntries这个对象上,可以发现,它是一个键为实体类对象,值为EntityEntry的一个Map的entry对象,相关解释如下图:

      方法继续进行,将会把Entry对象的键和值交给一个onFlushEntity的方法,这个方法将会判断有没有脏数据,并且最终判断需不需要向数据库中发送SQL语句.进入这个方法.可以看出这个方法获取到了实体类.原来Entry对象的键和EntityEntry这个对象(原来Entry对象的值.里面包含快照).随后调用EntityEntry对象的requiresDirtyCheck方法,判断是否需要进行脏检查.

      判断结果将会赋值给一个叫做mightBeDirty的boolean类型的变量.然后根据此变量判断是否需要向数据库发出sql语句.

      这就是在一级缓存中的实体类对象发生更新后,hibernate进行脏检查和内存中的快照(实际上,就是loadState数组.它的长度取决于具有业务含义的字段的个数)进行比对,并且发出sql语句的大致过程.由于水平的原因,只能分析源代码到这里,感觉hibernate的源代码还是相当复杂的,在以后的学习中也要多多看看源代码,观看大神的代码规范和理解它们的思路,对于自己进行编码一定会有很大的帮助!

  • 相关阅读:
    .NetCore Grpc 客服端 工厂模式配置授权
    DOCKER 拉取 dotnet 镜像太慢 docker pull mcr.microsoft.com too slow
    Introducing .NET 5
    VSCode 出现错误 System.IO.IOException: The configured user limit (128) on the number of inotify instances has been reached.
    Omnisharp VsCode Attaching to remote processes
    zookeeper3.5.5 centos7 完全分布式 搭建随记
    Hadoop2.7.7 centos7 完全分布式 配置与问题随记
    MySQL索引 索引分类 最左前缀原则 覆盖索引 索引下推 联合索引顺序
    SQL基础随记3 范式 键
    MySQL调优 优化需要考虑哪些方面
  • 原文地址:https://www.cnblogs.com/hlhdidi/p/6139020.html
Copyright © 2011-2022 走看看