从源码层面来看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);
分享到:
相关推荐
本篇文章将详细解析Hibernate中的三种主要查询方式——HQL(Hibernate Query Language)、Criteria API和Query API,并着重讨论`load()`与`get()`方法的区别。 一、HQL查询 Hibernate Query Language(HQL)是...
在Java的持久化框架Hibernate中,`get`和`load`方法都是用于从数据库中获取对象,但它们之间存在一些重要的区别。理解这些差异对于优化应用程序的性能和避免潜在问题至关重要。 首先,`get`方法是直接从数据库中...
在Hibernate源码中,`get`方法直接调用了`sessionFactory`的`load`方法,但是传递了一个额外的参数`LockMode.NONE`,这表明它不希望获取任何锁定。而`load`方法允许设置不同的锁模式,以支持并发控制。 在实际开发...
`load`和`get`方法是Hibernate中用于检索实体的两种主要方式,它们都是从Session接口中调用,但有明显的区别和各自的适用场景。 1. `load`方法: - `load`方法主要用于根据主键加载对象,它返回一个代理对象,而...
5. **Session接口**:是Hibernate的核心接口,负责对象的持久化操作,如保存(save())、更新(update())、删除(delete())以及查询(load(), get())等。 6. **Transaction管理**:Hibernate支持JTA(Java ...
Hibernate 是一个著名的开源Java对象关系映射(ORM)框架,它极大地简化了数据库与Java应用程序之间的交互。在本文中,我们将深入探讨Hibernate 3.6.1版本的源码,了解其内部工作原理以及关键组件的功能。 源码分析...
2. **持久化模型**:源码中可以看到,Hibernate通过注解或XML配置文件来定义Java类为持久化实体,实现了对象与数据库表之间的映射。 3. **缓存机制**:Hibernate支持二级缓存,源码中可以深入理解其工作流程,包括...
在深入探讨Hibernate源码之前,我们首先需要理解什么是对象持久化技术。对象持久化是将内存中的对象状态保存到持久存储介质(如数据库)中,以便在后续的程序运行中可以恢复这些对象的状态。它解决了应用程序中的...
**hibernate入门学习笔记+源码** **一、Hibernate简介** Hibernate是一个开源的对象关系映射(ORM)框架,它简化了Java应用与数据库之间的交互。通过提供对象化的数据访问方式,Hibernate消除了传统JDBC代码中的...
4. 加载(Load/Get):根据主键从数据库中获取对象,返回持久化状态的对象。 六、查询语言 1. HQL:Hibernate查询语言,类似SQL但面向对象,可以方便地进行对象间的关联查询。 2. Criteria API:提供更灵活的查询...
《Hibernate源码解析(一)》 在Java开发领域,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。深入理解Hibernate的源码,不仅可以帮助开发者更好地运用该工具,还能提升对Java编程和...
【hibernate_first_new项目源码】是一个关于Hibernate框架学习的项目,主要涵盖了对Hibernate常用接口的详细讲解和实例应用。Hibernate是一个强大的Java持久层框架,它为开发者提供了对象关系映射(ORM)功能,使得...
在Hibernate源码的学习过程中,我们可以深入理解ORM的工作原理,提高我们的Java开发技能,并且能够更好地优化数据库操作。 一、Hibernate核心组件 1. Configuration:配置对象,负责读取hibernate.cfg.xml文件,...
这个"java hibernate 上课源码6"应该包含了一系列示例代码,用于教授如何在实际项目中应用Hibernate。通过深入理解这些源码,我们可以学习到Hibernate的核心概念、API使用以及最佳实践。 1. Hibernate 概述: ...
2. **Hibernate_02**: 在这个阶段,开发者可能学习了如何在Hibernate中使用Session接口进行数据操作,比如保存(save()或persist())、更新(update())、删除(delete())和加载(get()或load())对象。此外,还...
《Hibernate电子版及源码》资源集合是一份珍贵的学习材料,专为那些渴望深入了解Java持久化框架Hibernate的开发者准备。Hibernate作为一个开源的对象关系映射(ORM)框架,它极大地简化了Java应用程序对数据库的操作...
这份资料包含的中文说明将帮助开发者更好地理解和使用Hibernate3.2,而源码则提供了深入学习和研究的宝贵资源。 1. Hibernate ORM概述: Hibernate是一种将Java对象与关系数据库进行映射的技术,它通过提供一种...
Hibernate是一个开源的对象关系映射(ORM)框架,它允许Java开发者将数据库操作转换为对象级别的操作,从而简化了数据访问层的开发。在 Hibernate 3.2 版本中,这个框架已经相当成熟,提供了丰富的功能和性能优化。...
2. **实体类和映射文件**:在Hibernate中,我们创建Java类来表示数据库中的表,通过Hibernate的XML映射文件(或注解)定义这些类与数据库表的对应关系。 3. **SessionFactory和Session**:SessionFactory是...
传智播客李勇hibernate源码1-20课,目录如下:01_hibernate介绍与动手入门体验;02_hibernate入门案例的细节分析; 03_hibernate入门案例的代码优化; 04_Session接口及get|load|persist方法 05_实体对象的三种状态...