`

从源码层面来看load与get的区别(二): Hibernate源码研究碎得(6)

阅读更多

从源码层面来看load与get的区别(二): Hibernate源码研究碎得(5)

接着上一篇问题的引入,本篇中我们先从Session里我们很熟悉的get(Class entityClass, Serializable id)起步.小菜这用的例子是Hibernate里自带那个,
 程序的入口为下面的Java语句:
 person = (Person) session.get(Person.class, 1L);

 在DB中已事先插入下面一条记录:
 PERSON_id age firstname  lastname
  1                0         Foozy   Beary

下面将记录下用Eclipse里用Debug跟踪时发现的很值得关注的Breakpoints:

进入Session的实现类SessionImpl后,将调用方法
 get(String entityName, Serializable id)   ----(1)
其中entityName就是Person.class.getName()的值.

进入方法(1)后,将通过LoadEvent的构造方法
 LoadEvent(Serializable entityId, String entityClassName, boolean isAssociationFetch, EventSource source)    ----(2)
创建一个LoadEvent对象,构造方法中传入的参数依次为,尖括号中的为通过Eclipse的Debug时Variables看到的实参值.
 id<1>,entityName<events.Person>,isAssociationFetch<false>,EventSource<SessionImpl的实例引用,也就是this>

前两个参数无需说明,先看下形参isAssociationFetch对其的赋值为false,我猜想,通过这个false告诉下面代码块这个Persion类在此次get时以notAssociationFetch来进行(这时有点疑问:若想从这样get得到的Instance里获取那些与之关联的数据会怎样呢?是Hibernate会自动再到DB中去取?当然这样的再取是很不efficient的,毕竟从DB取数时最忌讳一次能获得的而要来回地折腾多次.或在某种特定的情况下--比如说想查找下这个Person对象的所有信息,想一次性地获得与Person对象关联的所有数据又该怎么来做?用get好像就不行了吧?load行吗?通过Query接口以HQL的形式?对了,在HQL里是可以写fetch这个准关键字的....看Java Persistence with Hibernate这本书时,看到了如下的一句说明:
 All entity associations and collections aren't retrieved.If you access any proxied association or uninitialized collection, a second SELECT  is executed to retrieve the data on demand.

 也就是说Hibernate会给那些关联的entity创建一个proxy,在默认情况下,当访问这些proxy里的数据时,Hibernate再去DB中取去相应的数据.

 那是不是可以通过在xxx.hbm.xml中改变那个默认fetch策略的方式来达到利用一个简单的get方法就可以获得相关的数据呢?好像不行吧,因为到现在的创建LoadEvent对象为止,还没有看到任何读取配置信息的操作..........
).

 最后一个参数EventSource没什么可说的,SessionImpl类实现了EventSource接口,不过这里顺便说下的是Hibernate大量应用了Event-Action模式.

 在构造方法(2)里又调用构造方法
 private LoadEvent(Serializable entityId,String entityClassName,Object instanceToLoad,LockMode lockMode,boolean isAssociationFetch,EventSource source)  ---(3)
与(2)处的构造方法相比,(3)处的构造方法又多了两个形参
 Object:instanceToLoad与LockMode:lockMode
与这两个形参对应的实参都是null.这个null本身没什么可考虑的,在此值得再进一步联想的是这个instanceToLoad,既然已是一个instance了,还需要再load吗?难道说是通过这个可以达到refresh的功能?进一步看源码一探虚实.带着这个问题,利用Eclipse的"Open Call Hierarchy"功能顺藤摸瓜地看到Session中的一个load方法就是利用了这个instanceToLoad的特性,这个load是没有返回值的,这样也就暗合了基refresh的功能.

 LockMode在此没什么多说的,先从Hibernate源码中把LockMode里所定义的6种限制级别列举一下,它们依次是:
 NONE,READ,UPGRADE,UPGRADE_NOWAIT,WRITE,FORCE.
BYW,从这个类里可以很好地看出Java里枚举类型的雏形.在这个LoadEvent类里(更准确地说是在当前的这个private的构造方法里.),若loadMode为null时,就将其设为了值为LockMode.NONE的DEFAULT_LOCK_MODE模式.
 
 (BTW,从LoadEvent类的构造方法的设计上也多少看出了点以后自己有用的东西:用private来修饰那个参数最多的构造方法,其余的构造方法视具体的调用而通过this结合null的方式调用那个private的.)

 这样这个LoadEvent就创建出来了.

这些都是前期工作,下一篇中将看实质一点的方法
 fireLoad(event, LoadEventListener.GET);

3
0
分享到:
评论
3 楼 rmn190 2009-03-07  
谢谢hantsy!

看了你的文章, 又链接到了http://gmarwaha.blogspot.com/2007/01/hibernate-difference-between-sessions.html上.

谢谢分享!
2 楼 hantsy 2009-03-07  
我以前写过的一篇文章。。。
http://blog.chinaunix.net/u/1096/showart_252658.html
1 楼 rmn190 2009-02-21  
这个load是没有返回值的,这样也就暗合了基refresh的功能. --> 可能通过这个方法来将一个托管态的实例转为persistent状态,也就是refresh的功能吧? 数据上会不会更新呢?

相关推荐

    hibernate 三种 查询 方式 load与get的区别

    NULL 博文链接:https://cici9898-007.iteye.com/blog/1847710

    hibernate中get和load方法的区别

    NULL 博文链接:https://ysj5125094.iteye.com/blog/1897557

    Hibernate的get和load方法的区别

    NULL 博文链接:https://811417208-qq-com.iteye.com/blog/506950

    传智播客李勇hibernate源码1-20课

    传智播客李勇hibernate源码1-20课,目录如下:01_hibernate介绍与动手入门体验;02_hibernate入门案例的细节分析; 03_hibernate入门案例的代码优化; 04_Session接口及get|load|persist方法 05_实体对象的三种状态...

    Hibernate查询 load与get的区别及其它查询测试

    NULL 博文链接:https://quicker.iteye.com/blog/658451

    hibernate get/load/saveOrUpdate/statistics

    博文链接:https://log-cd.iteye.com/blog/205166

    spring_MVC源码

    15. &lt;load-on-startup&gt;1&lt;/load-on-startup&gt; 16. &lt;/servlet&gt; 17. &lt;servlet-mapping&gt; 18. &lt;servlet-name&gt;spring&lt;/servlet-name&gt; &lt;!-- 这里在配成spring,下边也要写一个名为spring-servlet.xml的文件,主要用来...

    ssh(structs,spring,hibernate)框架中的上传下载

     需要指定的是Spring 1.2.5提供了两套Hibernate的支持包,其中Hibernate 2相关的封装类位于org.springframework.orm.hibernate2.*包中,而Hibernate 3.0的封装类位于org.springframework.orm.hibernate3.*包中,...

    DWR.xml配置文件说明书(含源码)

    因为指定属性转换只有针对bean才有效(基本类型的转换没有必要指定属性),这个功能只能应用与特定的converter即BeanConverter和从次类派生的所有类.相关配置语法如下 , property2"/&gt; 这样就可以限定DWR不能调用Fred...

    springmybatis

    mybatis实战教程mybatis in action之五与spring3集成附源码 mybatis实战教程mybatis in action之六与Spring MVC 的集成 mybatis实战教程mybatis in action之七实现mybatis分页源码下载 mybatis实战教程mybatis in ...

    cms后台管理

    解压缩jeecms-3.0.2-final-src,在src文件夹下会看到有三个压缩文件,如果只想进行普通的二次开发,可以只导入cms这个源码,删除jeecms-cms-identity-3.0.2-final.jar即可,如果想进行深入的二次开发,需要导入...

Global site tag (gtag.js) - Google Analytics