`
catalin
  • 浏览: 16822 次
  • 来自: ...
社区版块
存档分类
最新评论

Hibernate经典问题收集1-Lazy Loading (Load&Get)

阅读更多

http://www.iteye.com/topic/491288

Hibernate的get函数

<script type="text/javascript"></script><script type="text/javascript"></script>

<!--[if !supportLists]-->1.        <!--[endif]-->从方法调用到事件处理

hibernate当中,大部分操作最终都是转化为事件,然后由对应的事件处理函数来处理。而事件内部主要包含的就是对Session实例的引用

<!--[if !vml]--><!--[endif]-->

<!--[if !supportLists]-->2.        <!--[endif]-->数据加载

数据加载主要在LoadEventListenerdoLoad()内部完成。doLoad在加载数据时,会查询他的两级缓存。当在缓存当中找不到时,才会进行实际的数据库操作。

<!--[if !vml]--><!--[endif]-->

 

<!--[if !supportLists]-->2.1.       <!--[endif]-->loadFromSessionCache

Session的缓存主要是指他的PersistenceContext,每次当SessionFactory要创建一个新的Session时,他都会为其创建一个新的PersistenceContext实例。一般情况下,Session的生命周期都非常短,所以PersistenceContext作为缓存的作用并不明显。但是在Web开发当中,我们经常会在一个Long Conversation中重用同一个Session,此时,PersistenceContext作为缓存的意义将会变得重要。

如果我们在PersistenceContext中找不到所需的实例,则他将会通过Session所关联的Interceptor来获取实例,这里就给了我们一个绕开数据库注入实例的机会。

 

<!--[if !supportLists]-->2.1.1.      <!--[endif]-->代码

public Object getEntityUsingInterceptor(EntityKey key) throws HibernateException {

final Object result = persistenceContext.getEntity(key);

if ( result == null ) {

     final Object newObject = interceptor.getEntity( key.getEntityName(), key.getIdentifier() );           if ( newObject != null ) {

lock( newObject, LockMode.NONE );

}

return newObject;

}else {

return result;

}

}

 

     注:这段代码是主要的数据加载部分,从代码可以看到在加载数据时,首先调用的是

         persistenceContext.getEntity(),当失败时则调用interceptor.getEntity()

 

<!--[if !supportLists]-->2.2.       <!--[endif]-->loadFromSecondLevelCache

如果我们在hibernate的配置文件中启用了cache,那么在这里他将会查询二级缓存。查询Cache的过程比较简单,首先是生成一个CacheKey,并根据这个来查询。

 

<!--[if !supportLists]-->2.2.1.      <!--[endif]-->代码

protected Object loadFromSecondLevelCache(

              final LoadEvent event,

              final EntityPersister persister,

              final LoadEventListener.LoadType options) throws HibernateException {

        

         final SessionImplementor source = event.getSession();

        

         final boolean useCache = persister.hasCache() &&

              source.getCacheMode().isGetEnabled() &&

              event.getLockMode().lessThan(LockMode.READ);

        

         if (useCache) {

              final SessionFactoryImplementor factory = source.getFactory();           

              final CacheKey ck = new CacheKey(

                       event.getEntityId(),

                       persister.getIdentifierType(),

                       persister.getRootEntityName(),

                       source.getEntityMode(),

                       source.getFactory()

                   );

              Object ce = persister.getCache()

                   .get( ck, source.getTimestamp() );

              ……

              if ( ce != null ) {

                   CacheEntry entry = (CacheEntry) persister.getCacheEntryStructure()

                            .destructure(ce, factory);

                   // Entity was found in second-level cache...

                   return assembleCacheEntry(

                            entry,

                            event.getEntityId(),

                            persister,

                            event

                       );

              }

         }       

         return null;

     }

 

注:在操作二级缓存时,Hibernate并不是直接使用ObjectID或者hashCode来作为Key,而是使用一个自

定义的CacheKey类。而所存储的对象也不仅仅是实体本身,而是一个经过assemble的对象。

 

<!--[if !supportLists]-->2.3.       <!--[endif]-->loadFromDatasource

这是loadFromDataSource的大致流程,主要的操作都是在类UniqueEntityLoader内部完成,前半部分主要是生成JDBCPreparedStatement,并进行数据库查询。当结果返回以后,需要把结果先放到SessionPersistenceContext当中,这通过TwoPhaseLoadaddUninitializedEntity()postHydrate()完成。前一个方法主要是存入一个实例,该实例只设置了id属性。后续的EntityPersister.hydrate(),用于获取其他的属性值,当所有属性值获取以后将调用postHydrate()方法更新属性值。在存入PersistenceContext以后,要操作的就是二级缓存,这通过TwoPhaseLoad.initializeEnttiy()完成。

<!--[if !vml]--><!--[endif]-->

<!--[if !supportLists]-->3.        <!--[endif]-->总结:

在整个Hibernateget操作里面,我们可以通过提供不同的Interceptor,或者直接操作他的二级缓存来改变他的整个查询策略。

了解了这点,可以部分改进我们的数据库测试。当我们的某些操作仅仅依赖于get操作时,我们可以把测试数据直接通过Interceptor或者二级缓存压入Hiberante,而不用真正的写入数据库。

分享到:
评论

相关推荐

    hibernate get load区别

    3. **支持懒加载**:由于`load`方法返回的是代理对象,并且该代理支持按需加载特性,因此非常适合用于实现懒加载(Lazy Loading)策略,即在真正需要数据的时候才进行加载,从而提高系统的性能和响应速度。...

    hibernate中get和load方法的区别

    在Java的持久化框架Hibernate中,`get`和`load`方法都是用于从数据库中获取对象,但它们之间存在一些重要的区别。理解这些差异对于优化应用程序的性能和避免潜在问题至关重要。 首先,`get`方法是直接从数据库中...

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

    - 使用`load`的一个重要原因是延迟加载(Lazy Loading)。如果实体关联了其他实体,而你只想在需要时才加载它们,那么`load`会很有帮助,因为它可以避免不必要的数据库交互,提高性能。 - `load`方法抛出`...

    Hibernate的get和load方法的区别

    `Session.load(Class clazz, Serializable id)`方法是延迟加载(Lazy Loading)的代表。它并不会立即执行SQL查询,而是创建一个代理对象,这个代理对象在真正被访问时(如调用其属性或方法)才会执行查询。这是为了...

    session的get与load比较

    ### Session的Get与Load方法比较 在对象关系映射(ORM)框架中,如Hibernate,开发者经常需要通过Session对象来加载或获取实体对象。本文将深入探讨`get`与`load`两种方法的区别及其应用场景。 #### 一、基本概念 ...

    hibernate-release-5.2.10

    4. 加载和检索:get()和load()加载单个对象,find()和query()用于执行HQL或Criteria查询。 六、级联操作 通过设置属性 cascade,可以控制实体间的操作是否级联,例如级联保存、更新、删除等。 七、缓存机制 ...

    Hibernate框架搭建及数据库相关操作

    1. **查询**:使用 `session.get()` 或 `session.load()` 获取单个对象,`session.createQuery()` 或 `session.createCriteria()` 用于执行 HQL(Hibernate Query Language)查询。 2. **更新**:通过 `session....

    hibernate中get和load的区别共5页.pdf

    在Java的持久化框架Hibernate中,`get`和`load`是两个常用的方法,它们都是用来从数据库中获取对象的。然而,它们在工作原理和使用场景上存在一些关键的区别,这些区别对于理解和优化Hibernate应用至关重要。 首先...

    hibernate--- jar包

    8. **性能优化**: Hibernate提供了一些优化手段,如二级缓存、批处理、延迟加载(lazy loading)、预加载(eager loading)等,以提高应用性能。 9. **一对多、多对一、多对多关系映射**: Hibernate可以轻松处理...

    hibernate-release-4.2.2.Final.zip

    Hibernate提供了一套完整的生命周期管理机制,包括持久化(persist)、加载(load)、检索(get)、更新(update)、删除(delete)等操作。同时,它支持延迟加载(Lazy Loading),避免了内存消耗和性能瓶颈。 五...

    精通hibernate源码ch2

    - get()和load():根据主键获取对象,load()会延迟加载。 - find():通过HQL或Criteria API执行查询。 5. Hibernate缓存机制: - 第一级缓存:SessionFactory级别的,每个Session都有自己的缓存,存储当前...

    hibernate-release-5.0.12.Final.rar

    Hibernate提供了多种性能优化策略,如延迟加载(Lazy Loading)、批处理(Batch Processing)、结果集缓存(Result Set Caching)等,旨在减少数据库交互,提高程序运行效率。 9. **关联映射** Hibernate支持多种...

    hibernate-distribution-3.6.2.Final-dist jar包

    12. **延迟加载(Lazy Loading)**:Hibernate支持懒加载机制,即当需要访问关联对象时才进行数据库查询,提高性能。 以上就是`hibernate-distribution-3.6.2.Final-dist` jar包中涉及的主耍知识点。这个包包含了...

    Hibernate中get和load方法的区别以及close(),clear()、evict()等的区别

    如果不存在且不是懒加载(lazy loading),则直接查询数据库。如果是懒加载,`load`会创建一个代理对象,初始化标志设为`false`,目标对象(target)设为`null`。当访问代理对象的属性时,才会触发数据库查询。如果...

    hibernate.jar包

    - 对象操作:执行增删改查操作,如save()、update()、delete()、load()和get()等。 - 提交事务:事务成功则提交,失败则回滚。 - 关闭资源:关闭Session和SessionFactory,释放资源。 4. Hibernate与SSH框架的...

    Hibernate面试问题大全

    延迟加载(Lazy Loading)是一种优化策略,只有当对象实际被访问时,才会加载其关联的对象。这样可以避免在不需要时加载大量数据,提高系统性能。 10. Hibernate的一对一、多对一和多对多关系如何映射? - 一对一:...

    hibernate-3[1].2.6.ga.zip

    总之,"hibernate-3[1].2.6.ga.zip"压缩包包含的是一个经典的Hibernate版本,虽然较旧,但仍然具有重要的学习价值。通过理解它的核心特性、主要功能和使用方法,开发者可以更好地掌握ORM框架,提升Java应用的数据...

    Hibernate-Task-04-03-2021

    另外,合理使用懒加载(lazy loading)和立即加载(eager loading)也能优化数据读取。 综上所述,"Hibernate-Task-04-03-2021"可能涵盖了一个完整的Hibernate应用开发流程,涉及了从配置到实际操作的多个环节。这...

    hibernate-3.2.rar

    11. **延迟加载(Lazy Loading)**:Hibernate 3.2支持懒加载机制,对于一对多或多对一的关系,关联对象默认不会立即加载,而是在真正需要时才从数据库中获取,减少内存占用。 12. **事件监听器**:Hibernate提供了...

Global site tag (gtag.js) - Google Analytics