1 hibernate get 主要源码:
public Object get(String entityName, Serializable id) throws HibernateException { LoadEvent event = new LoadEvent(id, entityName, false, this); boolean success = false; try { fireLoad(event, LoadEventListener.GET); success = true; return event.getResult(); } finally { afterOperation(success); } }
load源码:
public Object load(String entityName, Serializable id) throws HibernateException { LoadEvent event = new LoadEvent(id, entityName, false, this); boolean success = false; try { fireLoad( event, LoadEventListener.LOAD ); if ( event.getResult() == null ) { getFactory().getEntityNotFoundDelegate().handleEntityNotFound( entityName, id ); } success = true; return event.getResult(); } finally { afterOperation(success); } }
由上可知:hibernate的get和load的加载上前半部分调用方法基本差不多,只是加载类型不一致,一个是get,一个是load;
两种方式同样调用了fireLoad方法,在fireLoad里两者处理相同,都是调用了load事件对应的listener,调用listener的onLoad()方法,
onLoad方法又会调用proxyOrLoad()方法,在proxyOrLoad方法上出现了差异:
Object proxy = persistenceContext.getProxy(keyToLoad); if ( proxy != null ) { return returnNarrowedProxy( event, persister, keyToLoad, options, persistenceContext, proxy ); } else { if ( options.isAllowProxyCreation() ) {//分支1 return createProxyIfNecessary( event, persister, keyToLoad, options, persistenceContext ); } else {//分支2 // return a newly loaded object return load(event, persister, keyToLoad, options); } }
看了如上代码,在看看LoadEventListener.GET和LoadEventListener.LOAD的区别
public static final LoadType GET = new LoadType("GET") .setAllowNulls(true)//允许为空 .setAllowProxyCreation(false)//不允许创建代理对象 .setCheckDeleted(true) .setNakedEntityReturned(false); public static final LoadType LOAD = new LoadType("LOAD") .setAllowNulls(false)//允许为空 .setAllowProxyCreation(true)//不允许创建代理对象 .setCheckDeleted(true) .setNakedEntityReturned(false);
get方式允许为空,不允许创建代理对象;load恰恰相反不允许为空,允许创建代理对象
所以在方法proxyOrLoad()里load会走分支1,get会走分支2
分支1 :get的实际操作在此:
protected Object doLoad( final LoadEvent event, final EntityPersister persister, final EntityKey keyToLoad, final LoadEventListener.LoadType options) { if ( log.isTraceEnabled() ) { log.trace( "attempting to resolve: " + MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() ) ); } Object entity = loadFromSessionCache( event, keyToLoad, options ); if ( entity == REMOVED_ENTITY_MARKER ) { log.debug( "load request found matching entity in context, but it is scheduled for removal; returning null" ); return null; } if ( entity == INCONSISTENT_RTN_CLASS_MARKER ) { log.debug( "load request found matching entity in context, but the matched entity was of an inconsistent return type; returning null" ); return null; } if ( entity != null ) { if ( log.isTraceEnabled() ) { log.trace( "resolved object in session cache: " + MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() ) ); } return entity; } entity = loadFromSecondLevelCache(event, persister, options); if ( entity != null ) { if ( log.isTraceEnabled() ) { log.trace( "resolved object in second-level cache: " + MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() ) ); } return entity; } if ( log.isTraceEnabled() ) { log.trace( "object not resolved in any cache: " + MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() ) ); } return loadFromDatasource(event, persister, keyToLoad, options); }
由上可见:get先去一级缓存里去查找是否存在要返回的对象,如果不存在,则去二级缓存里查找,如果没有则从数据库中加载。
分支2:load加载数据方式:
Object existing = persistenceContext.getEntity( keyToLoad ); if ( existing != null ) { // return existing object or initialized proxy (unless deleted) log.trace( "entity found in session cache" ); if ( options.isCheckDeleted() ) { EntityEntry entry = persistenceContext.getEntry( existing ); Status status = entry.getStatus(); if ( status == Status.DELETED || status == Status.GONE ) { return null; } } return existing; } else { log.trace( "creating new proxy for entity" ); // return new uninitialized proxy Object proxy = persister.createProxy( event.getEntityId(), event.getSession() ); persistenceContext.getBatchFetchQueue().addBatchLoadableEntityKey(keyToLoad); persistenceContext.addProxy(keyToLoad, proxy); return proxy; }
load首先会去缓存里查找,否则则创建代理对象(load的代理对象在获取对象属性时究竟如何加载数据?在以后的分析中再做详细分析)
相关推荐
- 错误排查:当遇到问题时,源码分析能更准确地定位问题所在,提高解决问题的效率。 - 自定义扩展:熟悉源码后,我们可以根据需求自定义拦截器、事件监听器等,实现特定功能。 总结来说,Hibernate源码解析是一个...
5. **Session接口**:是Hibernate的核心接口,负责对象的持久化操作,如保存(save())、更新(update())、删除(delete())以及查询(load(), get())等。 6. **Transaction管理**:Hibernate支持JTA(Java ...
通过阅读和分析Hibernate 3.2的源码,我们可以深入了解ORM框架的设计理念,学习如何优化数据库操作,以及如何在实际项目中灵活运用Hibernate提供的各种功能。同时,这也有助于我们掌握Java反射、代理、元数据解析等...
源码分析: 1. **对象关系映射(ORM)**:Hibernate的核心功能是实现ORM,它将Java类映射到数据库表,对象的属性对应于表的列。在Hibernate 3.6.1中,这一映射主要通过`hibernate.cfg.xml`配置文件和`.hbm.xml`映射...
5. **CRUD操作**:通过Session的save、update、delete、get和load方法进行创建、读取、更新和删除操作。 6. **查询**:使用HQL或Criteria API进行复杂查询,如分页、条件筛选等。 **四、实战应用** 1. **事务管理**...
7. 源码分析:通过阅读和理解源码,加深对Hibernate内部工作原理的认识,如对象状态管理、持久化机制等。 8. 实战项目:结合实例,将学到的知识应用到实际项目中,例如构建一个简单的Web应用,实现数据的持久化操作...
**六、源码分析** `hibernate_test`、`hibernate_test3`、`hibernate_test2`这些文件可能包含了示例项目的源代码,包括配置文件、实体类、DAO层操作以及测试用例。通过分析这些源码,你可以更好地理解Hibernate在...
3.托管状态:对象已由Session的load()或get()方法加载,或通过事务提交后的瞬时对象。 4.脱管状态:Session关闭后,持久化对象变为脱管状态,其数据库连接断开。 三、实体映射 - @Entity表示一个Java类作为数据库表...
04_Session接口及get|load|persist方法 05_实体对象的三种状态与saveOrUpdate方法 06_完善HibernateUtil类及hql查询入门 07_实体类或属性名与数据库关键字冲突问题 10_使用Hibernate完成CRUD实验的步骤说明 11_...
这个"java hibernate 上课源码6"很可能包含了以上这些知识点的实例,通过分析和运行这些代码,你可以更好地理解和掌握Hibernate的使用。每个文件可能对应一个特定的主题,例如配置文件的设置、CRUD操作的实现、关联...
Hibernate的源码分析对于深入理解其工作原理至关重要。通过阅读源码,可以了解如何实现对象的持久化、事务管理、缓存策略等核心功能。特别地,SessionFactory的创建过程、Session的生命周期管理以及查询机制的实现...
此外,源码分析有助于提升开发者对Java反射机制、动态代理以及JPA规范的理解。 Hibernate的核心特性包括: 1. 对象关系映射:Hibernate允许开发者将Java类与数据库表进行映射,通过对象的方式来操作数据,使得开发...
Java Hibernate 是一个强大的对象关系映射(ORM)框架,它允许...通过分析和运行这些源码,你可以更直观地了解Hibernate的工作流程,加深对ORM框架的理解。记得结合理论知识和实际代码,逐步掌握Hibernate的精髓。
5. **持久化操作**: 使用Session的`save()`, `update()`, `delete()`, `load()`和`get()`等方法进行数据操作。 6. **查询数据**: 可以使用HQL(Hibernate Query Language)或Criteria API来执行查询。 7. **提交...
源码分析是深入理解其工作原理的关键,以下将详细探讨Hibernate的核心概念、设计模式以及主要模块。 一、Hibernate 概述 Hibernate 提供了一种在Java应用中持久化对象的机制,它通过映射Java类到数据库表来实现。...
接下来,我们分析`Hibernate操作数据字典源码(3)`文档中的关键内容。在Hibernate中,数据字典对应的实体类会包含一系列属性,每个属性对应数据库表中的字段。例如,数据字典可能有一个实体类`Dictionary`,其中...
查询数据则通过`Session.get()`或`Session.load()`,或者使用`Criteria`或`HQL`(Hibernate查询语言)进行更复杂的查询;更新对象时调用`Session.update()`,而删除则使用`Session.delete()`。 在文件列表中,`...
本主题聚焦于Hibernate中的一对一(OneToOne)关系的源码分析,这对于理解Hibernate的工作原理和优化数据访问性能至关重要。 在Hibernate中,一对一关系是指两个实体类之间存在一个唯一的对应关系,通常通过主键...
源码分析可以帮助深入理解Hibernate的工作原理,例如,查看Session是如何通过Criteria API或HQL执行查询的,以及如何处理事务。同时,实践操作,如搭建一个简单的示例项目,从创建数据库表到编写实体类,再到实现...
4.2 CRUD操作:通过Session的save()、update()、delete()和get()、load()方法实现对数据库的增删改查。 4.3 查询语言HQL:Hibernate Query Language是Hibernate提供的面向对象的查询语言,类似于SQL但更面向对象。 ...