<script type="text/javascript"></script><script type="text/javascript"></script>
<!--[if !supportLists]-->1. <!--[endif]-->从方法调用到事件处理
在hibernate当中,大部分操作最终都是转化为事件,然后由对应的事件处理函数来处理。而事件内部主要包含的就是对Session实例的引用
<!--[if !vml]--><!--[endif]-->
<!--[if !supportLists]-->2. <!--[endif]-->数据加载
数据加载主要在LoadEventListener的doLoad()内部完成。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并不是直接使用Object的ID或者hashCode来作为Key,而是使用一个自
定义的CacheKey类。而所存储的对象也不仅仅是实体本身,而是一个经过assemble的对象。
<!--[if !supportLists]-->2.3. <!--[endif]-->loadFromDatasource
这是loadFromDataSource的大致流程,主要的操作都是在类UniqueEntityLoader内部完成,前半部分主要是生成JDBC的PreparedStatement,并进行数据库查询。当结果返回以后,需要把结果先放到Session的PersistenceContext当中,这通过TwoPhaseLoad的addUninitializedEntity()和postHydrate()完成。前一个方法主要是存入一个实例,该实例只设置了id属性。后续的EntityPersister.hydrate(),用于获取其他的属性值,当所有属性值获取以后将调用postHydrate()方法更新属性值。在存入PersistenceContext以后,要操作的就是二级缓存,这通过TwoPhaseLoad.initializeEnttiy()完成。
<!--[if !vml]--><!--[endif]-->
<!--[if !supportLists]-->3. <!--[endif]-->总结:
在整个Hibernate的get操作里面,我们可以通过提供不同的Interceptor,或者直接操作他的二级缓存来改变他的整个查询策略。
了解了这点,可以部分改进我们的数据库测试。当我们的某些操作仅仅依赖于get操作时,我们可以把测试数据直接通过Interceptor或者二级缓存压入Hiberante,而不用真正的写入数据库。
相关推荐
3. **支持懒加载**:由于`load`方法返回的是代理对象,并且该代理支持按需加载特性,因此非常适合用于实现懒加载(Lazy Loading)策略,即在真正需要数据的时候才进行加载,从而提高系统的性能和响应速度。...
在Java的持久化框架Hibernate中,`get`和`load`方法都是用于从数据库中获取对象,但它们之间存在一些重要的区别。理解这些差异对于优化应用程序的性能和避免潜在问题至关重要。 首先,`get`方法是直接从数据库中...
- 使用`load`的一个重要原因是延迟加载(Lazy Loading)。如果实体关联了其他实体,而你只想在需要时才加载它们,那么`load`会很有帮助,因为它可以避免不必要的数据库交互,提高性能。 - `load`方法抛出`...
`Session.load(Class clazz, Serializable id)`方法是延迟加载(Lazy Loading)的代表。它并不会立即执行SQL查询,而是创建一个代理对象,这个代理对象在真正被访问时(如调用其属性或方法)才会执行查询。这是为了...
### Session的Get与Load方法比较 在对象关系映射(ORM)框架中,如Hibernate,开发者经常需要通过Session对象来加载或获取实体对象。本文将深入探讨`get`与`load`两种方法的区别及其应用场景。 #### 一、基本概念 ...
4. 加载和检索:get()和load()加载单个对象,find()和query()用于执行HQL或Criteria查询。 六、级联操作 通过设置属性 cascade,可以控制实体间的操作是否级联,例如级联保存、更新、删除等。 七、缓存机制 ...
1. **查询**:使用 `session.get()` 或 `session.load()` 获取单个对象,`session.createQuery()` 或 `session.createCriteria()` 用于执行 HQL(Hibernate Query Language)查询。 2. **更新**:通过 `session....
在Java的持久化框架Hibernate中,`get`和`load`是两个常用的方法,它们都是用来从数据库中获取对象的。然而,它们在工作原理和使用场景上存在一些关键的区别,这些区别对于理解和优化Hibernate应用至关重要。 首先...
8. **性能优化**: Hibernate提供了一些优化手段,如二级缓存、批处理、延迟加载(lazy loading)、预加载(eager loading)等,以提高应用性能。 9. **一对多、多对一、多对多关系映射**: Hibernate可以轻松处理...
Hibernate提供了一套完整的生命周期管理机制,包括持久化(persist)、加载(load)、检索(get)、更新(update)、删除(delete)等操作。同时,它支持延迟加载(Lazy Loading),避免了内存消耗和性能瓶颈。 五...
- get()和load():根据主键获取对象,load()会延迟加载。 - find():通过HQL或Criteria API执行查询。 5. Hibernate缓存机制: - 第一级缓存:SessionFactory级别的,每个Session都有自己的缓存,存储当前...
Hibernate提供了多种性能优化策略,如延迟加载(Lazy Loading)、批处理(Batch Processing)、结果集缓存(Result Set Caching)等,旨在减少数据库交互,提高程序运行效率。 9. **关联映射** Hibernate支持多种...
12. **延迟加载(Lazy Loading)**:Hibernate支持懒加载机制,即当需要访问关联对象时才进行数据库查询,提高性能。 以上就是`hibernate-distribution-3.6.2.Final-dist` jar包中涉及的主耍知识点。这个包包含了...
如果不存在且不是懒加载(lazy loading),则直接查询数据库。如果是懒加载,`load`会创建一个代理对象,初始化标志设为`false`,目标对象(target)设为`null`。当访问代理对象的属性时,才会触发数据库查询。如果...
- 对象操作:执行增删改查操作,如save()、update()、delete()、load()和get()等。 - 提交事务:事务成功则提交,失败则回滚。 - 关闭资源:关闭Session和SessionFactory,释放资源。 4. Hibernate与SSH框架的...
延迟加载(Lazy Loading)是一种优化策略,只有当对象实际被访问时,才会加载其关联的对象。这样可以避免在不需要时加载大量数据,提高系统性能。 10. Hibernate的一对一、多对一和多对多关系如何映射? - 一对一:...
总之,"hibernate-3[1].2.6.ga.zip"压缩包包含的是一个经典的Hibernate版本,虽然较旧,但仍然具有重要的学习价值。通过理解它的核心特性、主要功能和使用方法,开发者可以更好地掌握ORM框架,提升Java应用的数据...
另外,合理使用懒加载(lazy loading)和立即加载(eager loading)也能优化数据读取。 综上所述,"Hibernate-Task-04-03-2021"可能涵盖了一个完整的Hibernate应用开发流程,涉及了从配置到实际操作的多个环节。这...
11. **延迟加载(Lazy Loading)**:Hibernate 3.2支持懒加载机制,对于一对多或多对一的关系,关联对象默认不会立即加载,而是在真正需要时才从数据库中获取,减少内存占用。 12. **事件监听器**:Hibernate提供了...