zoukankan      html  css  js  c++  java
  • Hibernate之一级缓存

    时间:2017-1-20 14:48

    ——一级缓存

    1、什么是缓存
        缓存是将数据库、硬盘上的文件中的数据,放入到缓存中。
        缓存就是内存中的一块空间,当再次使用数据时,可以直接从内存中获得。

    2、缓存的优点
        提高程序运行的效率,缓存技术是Hibernate的一个优化手段。

    3、Hibernate分为两个级别的缓存:
        1)一级缓存:
            Session级别的缓存,一级缓存与Session生命周期一致,是自带的,不可卸载。
            一级缓存缓存的是对象的引用。
     
        2)二级缓存:
            SessionFactory级别的缓存,不是自带的,如果想要使用,则必须配置。

    4、理解Session缓存(一级缓存)
        1)在Session接口的实现中包含了一系列的Java集合,这些Java集合构成了Session缓存,只要Session实例没有结束生命周期,存放在它缓存中的对象也不会结束生命周期。
        2)当Session的save()方法持久化一个对象时,该对象被载入一级缓存,以后即使程序中不再引用该对象,只要缓存不清空,该对象仍然处于生命周期中,当视图get()、load()获取对象时,会判断缓存中是否存在该对象,有则返回,此时不再查询数据库,没有再查询数据库。
        3)Session能够在某些时间点,按照缓存中对象的变化来执行相关的SQL语句,来同步更新数据库,这一过程被成为刷出缓存(flush)
        4)默认情况下,Session在以下时间点刷出缓存:
            *   当应用程序调用Transaction的commit()方法时,该方法先刷出缓存(session.flush()),然后再向数据库提交事务。
            *   当应用程序执行一些查询操作时,如果缓存中持久化对象的属性已经发生了变化,会先刷出缓存,以保证查询结果能够反应持久化对象的最新状态。
            *   调用session的flush()方法。

    ——证明Hibernate一级缓存的存在

    示例代码:

        public void fun3(){
            Session session = HibernateUtils.openSession();
            Transaction tx = session.beginTransaction();
     
            // save()方法可以向一级缓存中存放数据
            Book book = new Book();
            book.setName("Hibernate");
            book.setAuthor("张三");
            book.setPrice(50D);
     
            Integer id = (Integer)session.save(book);
     
            // 第一次查询会发送SQL语句
            Book book1 = (Book)session.get(Book.class, 1);
     
            System.out.println(book1);
     
     
            // 第二次查询不会发送SQL语句,并且获取到的对象地址也是相同的,因为第一次查询已经将对象放入缓存了
            Book book2 = (Book)session.get(Book.class, 1);
     
            System.out.println(book2);
     
            tx.commit();
            session.close();
        }


    ——Hibernate快照区

    当session加载了customer对象后,会为customer对象的值类型的属性复制一份快照。
    当刷出缓存时,通过比较对象的当前属性和快照,来判断对象的哪些属性发生了变化,如果对象的属性和快照区一致,则不执行update操作。
    自动更新数据库是依赖了快照区。

    快照的存才提高了Hibernate的执行效率。

    可以通过断点进行查看。 
     

    示例代码:
        public void fun4(){

            Session session = HibernateUtils.openSession();
            Transaction tx = session.beginTransaction();
     
            // 获得一个持久态对象
            Book book = (Book)session.load(Book.class, 2);
            book.setName("Hibernate");
     
            /*
             * 当修改对象和数据库中数据一致时,不会提交更新语句
             * 通过快照区来判断数据是否一致
             */
     
            tx.commit();
            session.close();
        }


    ——一级缓存的管理

    一级缓存与Session的生命周期相关,Session的生命周期结束,一级缓存也就销毁了。

    Session中的方法:
        *   flush()
            将缓存中的数据刷出到数据库。
        *   clear()
            清空缓存中所有数据。
        *   evict()
            清空指定对象一级缓存数据,使对象变为离线态。
        *   refresh()
            使用快照区将一级缓存中的数据覆盖,使一级缓存中的数据变为从数据库查询时的初始状态。

    示例代码:

        // 一级缓存的管理:clear() / evict()
        public void fun5(){
            Session session = HibernateUtils.openSession();
            Transaction tx = session.beginTransaction();
     
            Book book1 = (Book) session.get(Book.class, 1);
            Book book2 = (Book) session.get(Book.class, 2);
            System.out.println(book1);
            System.out.println(book2);
     
            // session.clear(); // 清空一级缓存区域
            session.evict(book1); // 清空一级缓存中的指定对象
     
            Book book3 = (Book) session.get(Book.class, 1);
            Book book4 = (Book) session.get(Book.class, 2);
            System.out.println(book3);
            System.out.println(book4);
     
            tx.commit();
            session.close();
        }


    ——一级缓存的刷出时机

    FlushMode类:
        常量:
            *   ALWAYS
                普通查询、手动flush()、事务提交都会刷新。
            *   AUTO(默认值)
                有些查询会刷出缓存,手动调用flush()、事务提交会刷出。
            *   COMMIT
                只有在事务提交时、手动调用flush()会刷出。
            *   MANUAL
                只有在flush()时刷出。
            *   NEVER
                已过时,用MANUAL替代。

        严格程度:MANUAL > COMMIT > AUTO > ALWAYS


    通过session.setFlushMode(FlushMode.AUTO)进行设置,一般不会修改其值。


    ——操作持久化对象的方法

    1、save()
        1)session的save()方法使一个瞬时对象转变为持久态对象
        2)session的save()方法完成以下操作:
            *   把瞬时对象加入到Session缓存中,使它进入持久化状态。
            *   选用映射文件指定的标识符生成器,为持久化对象分配唯一的OID,在使用代理主键的情况下,setId()方法为瞬时对象设置OID是无效的。
            *   计划执行一条insert语句,把Customer对象当前的属性值组装到insert语句中。
        3)Hibernate通过持久化对象的OID来维持它和数据库相关记录的对应关系,当Customer对象处于持久化状态时,不允许程序随意修改它的ID。

    2、update()
        1)session的update()方法使一个脱管对象转变为持久化对象,并且计划执行一条update语句。
        2)在<class>标签上设置select-brefore-update="true",会在更新之前先查询,如果数据存在并且与待更新数据一致,则不执行更新。

    3、saveOrUpdate()
        1)根据对象的不同状态执行save()或update()方法。
            *   如果一个对象是瞬时态对象:执行save()方法
            *   如果对象是一个脱管态对象:执行update()方法
        如果在执行update()时设置的id不存在,会报错,可以在<id>标签上设置一个unsaved-value="-1",这样如果设置的id是-1,则会继续自动生成主键并save()

    4、delete()
        将持久态对象转换为瞬时态对象。

    5、get() / load()
        获得一个持久态对象。

    ——总结

    1、Hibernate中两个基本缓存
        *   一级缓存:与Session生命周期一致
        *   二级缓存:与SessionFactory生命周期一致
    2、证明一级缓存的存在
    3、一级缓存的结构 - 快照区
        *   用来自动完成数据库更新操作
    4、Hibernate一级缓存的管理
        *   clear()
        *   evict()
        *   flush()
        *   refresh()
    5、一级缓存刷出时机
        *   ALWAYS
        *   AUTO:默认值
        *   COMMIT:事务提交/flush()时刷出
        *   MANUAL:手动flush()时刷出
    6、操作持久化对象常用方法
        *   save()
        *   update()
        *   saveOrUpdate()
        *   delete()
        *   get() / load() 

  • 相关阅读:
    linux(不会考特别难,牢记下面即可)
    ajax
    Javascript 和 Jquery
    开发环境及配置
    网络协议考点
    面向对象考点
    会话控制
    文件操作
    正则表达式
    自定义函数和内部函数
  • 原文地址:https://www.cnblogs.com/wwwwyc/p/6375458.html
Copyright © 2011-2022 走看看