Hibernate 中 get 和 load的区别

来源:互联网 发布:湖南创盈商城网络关闭 编辑:程序博客网 时间:2024/05/17 23:43

Hibernate中get和load的区别

   1  load会默认数据库中记录一定存在,如果不存在会报org.hibernate.ObjectNotFoundException 异常 ; 如果数据库记录不存在get会返回null值

    2 如果配置lazy="true"  load() 会在一级缓存中创建对象代理类,而不是先查数据库,在真正使用该对象属性时才会查数据库  如果数据库中记录不存在就会报异常 

        get() 方法会直接查数据库


     3 在同一session中调用load() 和 get() 方法:配置lazy="true" ,如果数据库中记录不存在

               BaseDAO basedao = new BaseDAO(Bmenum.class);
Session _session = basedao.getSession() ;
Bmenum _b = (Bmenum)_session.load(Bmenum.class, "123") ;
System.out.println("load 结束");
if( _session.contains(_b) ){
System.out.println("包含 b");
}
System.out.println("------------------");

Bmenum _b1 = (Bmenum)_session.get(Bmenum.class, "123") ;

if( _session.contains(_b1) ){
System.out.println("包含 b1");
}

         执行结果如下:

 load 结束
包含 b
------------------
Hibernate: 
    select
        bmenum0_.enumname as enumname0_0_,
        bmenum0_.enumvalues as enumvalues0_0_,
        bmenum0_.type as type0_0_ 
    from
        bmenum bmenum0_ 
    where
        bmenum0_.enumname=?
Exception in thread "main" org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.chinadigitalvideo.hibernate.Bmenum#123]
at org.hibernate.impl.SessionFactoryImpl$1.handleEntityNotFound(SessionFactoryImpl.java:375)
at org.hibernate.event.def.DefaultLoadEventListener.returnNarrowedProxy(DefaultLoadEventListener.java:223)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:187)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:103)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:878)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:815)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:808)
at com.chinadigitalvideo.Test.test02(Test.java:75)
at com.chinadigitalvideo.Test.main(Test.java:14)     
   

       发现:get() 方法竟报出:ObjectNotFoundException

       

       如果记录存在:

       // TODO Auto-generated method stub
BaseDAO basedao = new BaseDAO(Bmenum.class);
Session _session = basedao.getSession() ;

Bmenum _b = (Bmenum)_session.load(Bmenum.class, "是否单片") ;

System.out.println("load 结束");

if( _session.contains(_b) ){
System.out.println("包含 b");
}

System.out.println("------------------");

Bmenum _b1 = (Bmenum)_session.get(Bmenum.class, "是否单片") ;

if( _session.contains(_b1) ){
System.out.println("包含 b1");
}
Bmenum _b2 = (Bmenum)_session.get(Bmenum.class, "是否单片") ;
if( _session.contains(_b2) ){
System.out.println("包含 b2");
}
System.out.println(_b1 == _b2);
_session.close() ;

         执行结果如下:

load 结束
包含 b
------------------
Hibernate: 
    select
        bmenum0_.enumname as enumname0_0_,
        bmenum0_.enumvalues as enumvalues0_0_,
        bmenum0_.type as type0_0_ 
    from
        bmenum bmenum0_ 
    where
        bmenum0_.enumname=?
包含 b1
包含 b2
true

       发现调用load()方法在一级缓存中存在Bmenum 的代理对象,但该代理对象未被延迟加载过的情况下get()方法仍然需要查询了数据库获取实体对象,然后第二次执行get()方法后 直接从一级缓存中获取实体对象

       修改load()的处理,让其调用属性 进行对象加载:

       BaseDAO basedao = new BaseDAO(Bmenum.class);
Session _session = basedao.getSession() ;

Bmenum _b = (Bmenum)_session.load(Bmenum.class, "是否单片") ;

System.out.println(_b.getEnumvalues());

System.out.println("load 结束");

if( _session.contains(_b) ){
System.out.println("包含 b");
}

System.out.println("------------------");

Bmenum _b1 = (Bmenum)_session.get(Bmenum.class, "是否单片") ;

if( _session.contains(_b1) ){
System.out.println("包含 b1");
}

Bmenum _b2 = (Bmenum)_session.get(Bmenum.class, "是否单片") ;

if( _session.contains(_b2) ){
System.out.println("包含 b2");
}

System.out.println(_b1 == _b2);
_session.close() ;

      执行结果如下:

Hibernate: 
    select
        bmenum0_.enumname as enumname0_0_,
        bmenum0_.enumvalues as enumvalues0_0_,
        bmenum0_.type as type0_0_ 
    from
        bmenum bmenum0_ 
    where
        bmenum0_.enumname=?
单片节目,集合节目             
load 结束
包含 b
------------------
包含 b1
包含 b2
true

     发现调用load()方法在一级缓存中存在Bmenum 的代理对象,在对代理对象被延迟加载过之后,再调用get()方法,get()方法就能从缓存中获取该代理对象 而不是从数据库中获取实体对象



0 0