从入门到绝望javaEE系列之Hibernate框架中的一级缓存

缓存这玩意,可能好多电脑小白都不知道是什么…小编当初选电脑的时候,CPU里面都有个配置参数叫做:三级缓存…大家都知道如今的CPU每秒可以处理数以亿计的数据(总之就是很快很快啦…)而我们的磁盘的转速,拿机械硬盘来说有5400转每分钟和7200转每分钟的…如今流行的固态硬盘处理速度也不过500m/s(总之就是相比CPU,硬盘的读取速度很慢很慢啦…),缓存的作用有:预读取,写入以及临时存储…而在咱们的Hibernate框架中的缓存的作用也不外乎这三种….好啦。不吹牛了,不逼逼上代码….

.缓存

    Session session = HibernateUtils.openSession();
    session.beginTransaction();
    //------------------------------------------------
    User u1 = (User) session.get(User.class, 1);// 发送select语句,从数据库取出记录.并封装成对象
                                               // 持久化状态对象=> 存到缓存
    User u2 = (User) session.get(User.class, 1);//再次查询时,会从缓存中查找,不会发送select

    User u3 = (User) session.get(User.class, 1);//再次查询时,会从缓存中查找,不会发送select

    System.out.println(u1==u2);
    System.out.println(u1==u3);
    //------------------------------------------------
    session.getTransaction().commit();
    session.close(); // 游离状态

当运行如上代码时显示如下结果:

Hibernate: 
    select
        user0_.id as id0_0_,
        user0_.name as name0_0_,
        user0_.password as password0_0_ 
    from
        t_user user0_ 
    where
        user0_.id=?
true
true

hibernate框架只发送了一条sql语句,并且u1,u2,u3为三个相同的对象(即在内存中指向同一块内存),why???
图1

其实session缓存中是以Map 的形式存放,key==Serializable为对象ID,value==Object就是实体类对象…

二.缓存中的快照

1.

Session session = HibernateUtils.openSession();
        session.beginTransaction();
        //------------------------------------------------
        User u1 = (User) session.get(User.class, 1);// 发送select语句,从数据库取出记录.并封装成对象

        session.update(u1);

        //------------------------------------------------
        session.getTransaction().commit();
        session.close(); // 游离状态

执行结果:

Hibernate: 
    select
        user0_.id as id0_0_,
        user0_.name as name0_0_,
        user0_.password as password0_0_ 
    from
        t_user user0_ 
    where
        user0_.id=?

2.

Session session = HibernateUtils.openSession();
        session.beginTransaction();
        //------------------------------------------------
        User u1 = new User();
        u1.setId(1);
        u1.setName("jerry");
        u1.setPassword("1234");

        session.update(u1);

        //------------------------------------------------
        session.getTransaction().commit();
        session.close(); // 游离状态

执行结果:

Hibernate: 
    update
        t_user 
    set
        name=?,
        password=? 
    where
        id=?

问题来了,两片代码最后都是执行update()语句,为什么hibernate发送的语句却不相同…
2
3
从图片中可以看出,当第一块代码执行了select语句后,在session缓存中存放了两份,一份缓存,一份快照,当对User对象没有做任何修改时,程序就调用update()方法,hibernate首先会对比缓存中的对象与快照中的对象是否发生变化…如果发生变化就发送update()语句…如果没有发生变化就不会执行update()语句…
第二块代码块,new出User对象,并设置id,此时User对象就成了游离状态…当调用update()方法后,User对象就成了持久状态…并放入Session缓存中,当提交事务后…Session依旧会对比缓存中的对象与快照中的对象…可是快照中的对象并不存在,于是Hibernate就执行update语句…

三.感受一级缓存中效率的提高…

Session session = HibernateUtils.openSession();
        session.beginTransaction();
        //------------------------------------------------
        User u1 = (User) session.get(User.class, 1);

        u1.setName("tom");
        session.update(u1);
        u1.setName("jack");
        session.update(u1);
        u1.setName("rose");
        session.update(u1);
        //------------------------------------------------
        session.getTransaction().commit();
        session.close(); // 游离状态

假设id为1的User对象在数据库中的Name为baobao,执行上述代码后…会打印哪些语句…………好多秒……….思考完毕…上结果:

Hibernate: 
    select
        user0_.id as id0_0_,
        user0_.name as name0_0_,
        user0_.password as password0_0_ 
    from
        t_user user0_ 
    where
        user0_.id=?
Hibernate: 
    update
        t_user 
    set
        name=?,
        password=? 
    where
        id=?

如果你还很奇怪调用了那么多次update()方法,却只执行了一次update()方法…建议从头再看一遍….体会下缓存.

以上缓存都指一级缓存,二级缓存等小编过几天研究完再来详解…

互利共勉!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值