Hibenrnate之缓存(一)

概述:


    Hibernate是一个持久层框架,经常访问物理数据库。为了降低应用程序对物理数据源访问的频次,从


提高应用程序的运行性能,缓存的合理使用就尤为重要。缓存内的数据是对物理数据源中的数据的复制,


用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据。


一级和二级缓存:


计算机生成了可选文字:S"slon内,不目被卸载义、‘。n的透存是,务范豆不典卜一级饭存中挤久化里的公个立甸筱异有唯一犷,:..一州..……。......……,。‘一如一级(Session)一白醚扮丈鱼尸丛些匹鱼也斑猫‘云蓬~;一~冬、”"'存放数胭的方式~入一到,妥丽乃鲤~一今又止丝生叫甸、,..一!Hib晰at.=级姗存是班口范.成有抽群范口的饭存有可叫出砚井,引面因此翻钾采用适当的井发访问抽咚东多货略允被透俘史匆抢甩七,整尔二嗯石并知方问蔽蔽甭飞州瘫丽卜物理介质续每吹件实砚于州存在形式卜尸桩,耳任卜HIb帅at创祖供70,hi比mat.c邢h,cac卜”p,o己”r碑口它二兰,译卜十一卜刃,三一云冬朴..1…,.'..--一对比:,,,........-::一、、使用1.:兄:.的刁、会敌月发访问「户教据白动用辰飞叫迪竺红…“.…,.......一‘...……一州二级(5essionFactory)41常从效握“·一”..,..."".."~”一了一州!理翻ic叹Oa".rgo)·…二“'‘一的~久化放扮、二级疲存中.俘砚二二二,:二:存二\型丝列鱼些些业卫一圣常用播件一,


应用原理:


    当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓


存,那么从二级缓存中查;如果都查不到,再查询数据库,把结果按照ID放入到缓存删除、更新、增加数据


的时候,同时更新缓存。

 

一级缓存的应用:


    当session对象调用save()方法保存一个对象后,该对象会被放入到session的缓存中。get()和


load()。当session对象调用get()或load()方法从数据库取出一个对象后,该对象也会被放入到session的缓


存中。使用HQL和QBC等从数据库中查询数据。

 

<span style="font-size:18px;">public class Client
{
    public static void main(String[] args)
    {
        Session session =HibernateUtil.getSessionFactory().openSession();
        Transaction tx = null;
        try
        {
            /*开启一个事务*/
            tx =session.beginTransaction();
            /*从数据库中获取id="001"的Person对象*/
            Person person= (Person )session.get(Person .class,"001");
            System.out.println("person.getUsername is"+person.getUsername());
            /*事务提交*/
            tx.commit();
            
           System.out.println("-------------------------------------");
            
            /*开启一个新事务*/
            tx =session.beginTransaction();
            /*从数据库中获取id="402881e534fa5a440134fa5a45340002"的Customer对象*/
            Person person1= (Person )session.get(Person .class,"001");
            System.out.println("person1.getUsername is"+person1.getUsername());
            /*事务提交*/
            tx.commit();
            
           System.out.println("-------------------------------------");
            
            /*比较两个get()方法获取的对象是否是同一个对象*/
            System.out.println("person== person1result is "+(person==person1));
        }
        catch (Exceptione)
        {
            if(tx!=null)
            {
                tx.rollback();
            }
        }
        finally
        {
            session.close();
        }
    }
}</span>


结果:


Hibernate: 
    select
        person0_.id asid0_0_,
        person0_.username asusername0_0_,
        person0_.balance asbalance0_0_ 
    from
       person person0_ 
    where
        person0_.id=?
person.getUsernameislisi
-------------------------------------
person.getUsernameislisi
-------------------------------------
person== person1result is true

    结果中只包含了一条SELECTSQL语句,而且person==person1 result istrue说明两个取出来的对象是


一个对象。其原理是:第一次调用get()方法,Hibernate先检索缓存中是否有该查找对象,发现没有,


Hibernate发送SELECT语句到数据库中取出相应的对象,然后将该对象放入缓存中,以便下次使用,第二次调


用get()方法,Hibernate先检索缓存中是否有该查找对象,发现正好有该查找对象,就从缓存中取出来,不


再去数据库中检索。

 

总结:


   Hibernate 的缓存只从下面两个方面发生作用 :1.通过主键值加载对象 2.延迟加载 。通过主键值


加载就会存在N+1问题,我们将在下篇文章介绍通过二级缓存解决N+1问题。而延迟加载实现要解决两个问


题:

  

  1.正常关闭连接和确保请求中访问的是同一个session。


  2.http请求结束后正确的关闭session(过滤器实现了session的正常关闭),延迟加载必须保证是同一个


   session(session绑定在ThreadLocal)。

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值