现在的位置: 首页 > 综合 > 正文

Hibernate的二级缓存

2013年06月09日 ⁄ 综合 ⁄ 共 3306字 ⁄ 字号 评论关闭

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, 继续学习~!

抱歉!评论已关闭.