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

     

    一级缓存:

      Hibernate的一级缓存是指Session(属于事务范围的缓存,由Hibernate管理,无需干预)

      它是一块内存空间,用来存放从数据库查询出的java对象,有了一级缓存,应用程序可以减少访问数据库的次数,提高了性能

      在使用Hibernate查询对象的时候,首先会使用对象属性的OID值(对应表中的主键)在Hibernate的一级缓存进行查找

        如果找到,则取出返回,不会再查询数据库

        如果没有找到,再到数据库中进行查询操作。然后将查询结果存放到Session一级缓存中

      Test:

            //第一次查询(会查询数据库)
            Customer c1 = session.get(Customer.class, 15);
            System.out.println(c1);
            
            //第二次查询(不会查询数据库)
            Customer c2 = session.get(Customer.class, 15);
            System.out.println(c2);
    tx.commit(); session.close();

      Console:

    Hibernate: 
        select
            customer0_.c_id as c_id1_0_0_,
            customer0_.c_name as c_name2_0_0_,
            customer0_.c_gender as c_gender3_0_0_,
            customer0_.c_age as c_age4_0_0_,
            customer0_.c_level as c_level5_0_0_ 
        from
            t_customer customer0_ 
        where
            customer0_.c_id=?
    com.roxy.hibernate.pojo.Customer@31c269fd
    com.roxy.hibernate.pojo.Customer@31c269fd

    ----- 只执行一次SQL语句

      Test2:测试一级缓存的范围

            //第一次查询(会查询数据库)
            Session session1 = HibernateUtil.openSession();
            Transaction tx1 = session1.beginTransaction();
             
            Customer c1 = session1.get(Customer.class, 15);
            System.out.println(c1);
            
            tx1.commit();
            session1.close();
            
            //第二次查询(会查询数据库)
            Session session2 = HibernateUtil.openSession();
            Transaction tx2 = session2.beginTransaction();
            
            Customer c2 = session2.get(Customer.class, 15);
            System.out.println(c2);
            
            tx2.commit();
            session2.close();

      Console:

    Hibernate: 
        select
            customer0_.c_id as c_id1_0_0_,
            customer0_.c_name as c_name2_0_0_,
            customer0_.c_gender as c_gender3_0_0_,
            customer0_.c_age as c_age4_0_0_,
            customer0_.c_level as c_level5_0_0_ 
        from
            t_customer customer0_ 
        where
            customer0_.c_id=?
    com.roxy.hibernate.pojo.Customer@31c269fd
    Hibernate: 
        select
            customer0_.c_id as c_id1_0_0_,
            customer0_.c_name as c_name2_0_0_,
            customer0_.c_gender as c_gender3_0_0_,
            customer0_.c_age as c_age4_0_0_,
            customer0_.c_level as c_level5_0_0_ 
        from
            t_customer customer0_ 
        where
            customer0_.c_id=?
    com.roxy.hibernate.pojo.Customer@4593ff34

    ----- 执行两次SQL查询,说明一级缓存的作用范围是session

    快照机制:

        当执行commit()时,Hibernate同时会清理session的一级缓存(flush),也就是将堆内存中的数据与快照中的数据进行对比,如果不一致,会执行同步操作(update)操作,如果一致,则不执行update

      只有持久化对象能走快照机制

      快照是数据的副本

      快照属于一级缓存

      快照是在堆内存中的

      快照的作用:保证数据的一致性

       Test:

            Customer c1 = session.get(Customer.class, 15);
            c1.setName("harry");
            
            tx.commit();
            session.close();

      Console:

    Hibernate: 
        select
            customer0_.c_id as c_id1_0_0_,
            customer0_.c_name as c_name2_0_0_,
            customer0_.c_gender as c_gender3_0_0_,
            customer0_.c_age as c_age4_0_0_,
            customer0_.c_level as c_level5_0_0_ 
        from
            t_customer customer0_ 
        where
            customer0_.c_id=?
    Hibernate: 
        update
            t_customer 
        set
            c_name=?,
            c_gender=?,
            c_age=?,
            c_level=? 
        where
            c_id=?

    ----- 自动执行update方法

    一级缓存管理:

       如果对象不在一级缓存中,无法进行对比,数据库不能自动更新

      一级缓存默认开启,无法关闭,只能清空(evict | clear | close),持久态转化为游离态

        evict:清除一级缓存中某个对象

        clear:清除一级缓存所有对象

           close:关闭Session,清除一级缓存

      Test:

            Session session = HibernateUtil.openSession();
            Transaction tx = session.beginTransaction();
            
            //查询
            Customer c1 = session.get(Customer.class, 16);
            c1.setName("draco");
            
            //session.evict(c1);
            session.clear();
                    
            tx.commit();
            session.close();

      Console:

        select
            customer0_.c_id as c_id1_0_0_,
            customer0_.c_name as c_name2_0_0_,
            customer0_.c_gender as c_gender3_0_0_,
            customer0_.c_age as c_age4_0_0_,
            customer0_.c_level as c_level5_0_0_ 
        from
            t_customer customer0_ 
        where
            customer0_.c_id=?

    ----- 只执行select,没有自动更新

       其他操作:

        flush:

          修改一级缓存,针对内存操作,在session执行flush操作时,将缓存变化同布在数据库

        refresh:

          重新查询数据库,更新快照和一级缓存

     Session手动控制缓存:

      Always:每次查询时,session都会flush,即自动更新

      Auto:在某些查询时,session会默认flush,例如commit

      Commit:在事务提交时

      Manual:只有手动提交事务才会同步到数据库

      参考链接:http://blog.csdn.net/luckyzhoustar/article/details/47665495

  • 相关阅读:
    解决IE8不兼容通过class名获取元素的方法
    移动端页面遇到过的各种坑
    强大的正则表达式
    弹性盒子布局
    vue环境搭建
    fullpage.js使用指南
    ES5原生api(1)
    双色球中奖率分析(python)
    使用python脚本的3D引擎Panda3d
    Python lambda介绍
  • 原文地址:https://www.cnblogs.com/roxy/p/7640216.html
Copyright © 2011-2022 走看看