Hibernate Session是作为 Hibernate的一级缓存使用的,它一般与ThreadLocal结合实现本地线程的Session,然后本地线程作用于其上,不影响其它线程的Session;
为了优化数据库操作,减少数据库的访问,尽量在内存中放有数据的副本,Hibernate通过使用第三方的Cache实现;这个Cache服务于整个应用程序,与HibernateSessionFactory同存亡~ 通过配置cache_provider,Hibernate就可以实现从数据库里get出pojo的同时,放到Cache里一个副本;下一次get这个pojo时,就先查看本地Session,如果没有就去Cache,如果Cache找到了就返回,如果仍没有才会去数据库找~
我在学习Hibernate的过程中,感觉到把Hibernate的源代码也放入项目中是非常方便的,这样可以看到哪些函数是在哪里实现的,实现的方式如何等等,比如Hibernate在查找pojo instance的时候通过看下面的代码就会非常明白:
位置:org.hibernate.event.def.DefaultLoadEventListener.java
/** */ /**
* Coordinates the efforts to load a given entity. First, an attempt is
* made to load the entity from the session-level cache. If not found there,
* an attempt is made to locate it in second-level cache. Lastly, an
* attempt is made to load it directly from the datasource.
*
* @param event The load event
* @param persister The persister for the entity being requested for load
* @param keyToLoad The EntityKey representing the entity to be loaded.
* @param options The load options.
* @return The loaded entity, or null.
* @throws HibernateException
*/
protected Object doLoad(
final LoadEvent event,
final EntityPersister persister,
final EntityKey keyToLoad,
final LoadEventListener.LoadType options) throws HibernateException ... {
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);
}
标记红色的代码有三行,表明了先从Session取,再从Cache取,最后从数据库取这样的先后顺序~
呵呵~ F.Y.I, 继续学习~!