hibernate一级缓存

 

  对象分为三种状态:瞬时状态、持久化状态、游离状态.其实我们调用session.save或者session.update或者session.saveOrUpdate只是为了将对象的状态改变为持久态(将对象存入session一级缓存)。一级缓存

中的对象就是和session关联,session中有一级缓存区和快照区,执行事务提交的时候会判断快照中对象和缓存中对应的对象是否一致,如果一致不会执行修改SQL、不一致会执行修改SQL。

 

 

1.Hibernate一级缓存介绍:

    

 

 2.一级缓存也是为了提高操作数据库的效率.

 1.测试一级缓存的存在

复制代码
    @Test
    //证明一级缓存存在
    public void fun1(){
        //1 获得session
        Session session = HibernateUtil.openSession();
        //2 控制事务
        Transaction tx = session.beginTransaction();
        //3执行操作
        
        Customer c1 = session.get(Customer.class, 1l);
        Customer c2 = session.get(Customer.class, 1l);
        Customer c3 = session.get(Customer.class, 1l);
        Customer c4 = session.get(Customer.class, 1l);
        Customer c5 = session.get(Customer.class, 1l);
        
        System.out.println(c3==c5);//true
        //4提交事务.关闭资源
        tx.commit();
        session.close();// 游离|托管 状态, 有id , 没有关联
        
        
    }
    
复制代码

 

结果:只发出一次SQL请求,而且五个对象的内存地址一样,证明查询了一次SQL,然后后四个对象直接取的session缓存的对象。

  由于第一次查询的时候先从session缓存中取,没有取到对应的数据,所以发出SQL从数据库中取出来并且会存到session缓存中; 第二次查询的时候从session缓存中取数据取到所以不发出SQL。

复制代码
Hibernate: 
    select
        customer0_.cust_id as cust_id1_0_0_,
        customer0_.cust_name as cust_nam2_0_0_,
        customer0_.cust_source as cust_sou3_0_0_,
        customer0_.cust_industry as cust_ind4_0_0_,
        customer0_.cust_level as cust_lev5_0_0_,
        customer0_.cust_linkman as cust_lin6_0_0_,
        customer0_.cust_phone as cust_pho7_0_0_,
        customer0_.cust_mobile as cust_mob8_0_0_ 
    from
        cst_customer customer0_ 
    where
        customer0_.cust_id=?
true
复制代码

 

 

2.一级缓存提高效率的手段:

 (1)查询的时候提高查询手段:提高查询效率,原理如下:

 

 (2)减少不必要的修改语句发送

  hibernate在查询到的数据的时候会将一份存入缓存,一份存入快照,缓存会和内存中的对象保持一致,最后执行事务提交的时候会对比快照中的对象和session中的对象有没有修改,有修改的话没执行修改SQL,否则不会发出修改SQL。

复制代码
    @Test
    //
    public void fun2(){
        //1 获得session
        Session session = HibernateUtil.openSession();
        //2 控制事务
        Transaction tx = session.beginTransaction();
        //3执行操作
        
        Customer c1 = session.get(Customer.class, 1l);
        
        c1.setCust_name("哈哈");
        c1.setCust_name("测试");
        
        //4提交事务.关闭资源
        tx.commit();
        session.close();// 游离|托管 状态, 有id , 没有关联
        
        
    }
复制代码

 

结果:

复制代码
Hibernate: 
    select
        customer0_.cust_id as cust_id1_0_0_,
        customer0_.cust_name as cust_nam2_0_0_,
        customer0_.cust_source as cust_sou3_0_0_,
        customer0_.cust_industry as cust_ind4_0_0_,
        customer0_.cust_level as cust_lev5_0_0_,
        customer0_.cust_linkman as cust_lin6_0_0_,
        customer0_.cust_phone as cust_pho7_0_0_,
        customer0_.cust_mobile as cust_mob8_0_0_ 
    from
        cst_customer customer0_ 
    where
        customer0_.cust_id=?
复制代码

解释:原来数据库的Cust_name的值就是测试,所以在两次修改完成之后还是测试,所以只发出查询SQL而未发出修改SQL。Hibernate快照的作用就是确保一级缓存中的数据和数据库中的数据一致。

 

 

  

 

 

总结:

缓存: 为了提高效率.
  一级缓存:为了提高效率.session对象中有一个可以存放对象的集合.

查询时: 第一次查询时.会将对象放入缓存.再次查询时,会返回缓存中的.不再查询数据库.

  修改时: 会使用快照对比修改前和后对象的属性区别.只执行一次修改.

 

posted @   QiaoZhi  阅读(395)  评论(0编辑  收藏  举报
编辑推荐:
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示