Hibernate源码解读——查询
本文主要通过源码,概述一下session的查询过程。
主要api有get、load。他们基本过程是类似的;
以get为例:
Session
public Object get(String entityName, Serializable id) throws HibernateException;
调用SessionImpl:
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); } }
fireLoad 主要是出发监听器;
主要获取过程就是 event.getResult();
event为LoadEvent,其实是一个很简单的类,其getResult也是非常简单,
public Object getResult() { return result; } public void setResult(Object result) { this.result = result; }
其中result其实是由 fireLoad(event, LoadEventListener.GET) 执行过程中赋值的
private void fireLoad(LoadEvent event, LoadType loadType) { errorIfClosed(); checkTransactionSynchStatus(); LoadEventListener[] loadEventListener = listeners.getLoadEventListeners(); for ( int i = 0; i < loadEventListener.length; i++ ) { loadEventListener[i].onLoad(event, loadType); } }
当然,从这段代码中我们仍然看不出什么头绪,我们继续研究
loadEventListener[i].onLoad(event, loadType);
经查找发现loadEvent有一个listener :DefaultLoadEventListener
其onLoad方法主要调用
event.setResult( load(。。。。 ) ); 也就是 DefaultLoadEventListener 的load方法,而其中主要又调用
Object entity = doLoad(event, persister, keyToLoad, options); 来进行“查询”:
protected Object doLoad( final LoadEvent event, final EntityPersister persister, final EntityKey keyToLoad, final LoadEventListener.LoadType options) throws HibernateException { //1 Object entity = loadFromSessionCache(event, keyToLoad, options); if ( entity == REMOVED_ENTITY_MARKER ) { return null; } if ( entity != null ) { return entity; } //2 entity = loadFromSecondLevelCache(event, persister, options); if ( entity != null ) { return entity; } //3 return loadFromDatasource(event, persister, keyToLoad, options); }
去掉其中的注释和logging部分,我们终于可以看到一个比较明显的语义了!!:::
1、loadFromSessionCache————从session缓存中查找, 如果找不到,则2
2、loadFromSecondLevelCache————从二级缓存中查找(如果支持),如果找不到,则3(即从sessionFactory查询)
3、loadFromDatasource————仍然查找不到,则从数据库中查询——这回是真正的查询
loadFromSessionCache 关键:
Object old = session.getEntityUsingInterceptor( keyToLoad );
loadFromSecondLevelCache关键:
Object ce = persister.getCache().get( ck, source.getTimestamp() );
loadFromDatasource关键:
Object entity = persister.load(
event.getEntityId(),
event.getInstanceToLoad(),
event.getLockMode(),
source
);
先写到这里,有时间再仔细看看。
上一篇: PHP网站后门的隐藏技巧测试报告
下一篇: PHP获取url的函数代码_PHP
推荐阅读