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对象中有一个可以存放对象的集合.

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

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

原文地址:https://www.cnblogs.com/qlqwjy/p/9351542.html