hibernate涉及到的代码过多,在阅读一中我们虽然是跟踪到最终SQL语句如何在hibernate中拼接出来,但是里面很多的细节我还是很模糊,我这里讲的条理性可能有些差,还请多多见谅。
在阅读一的前面部分我们看到了程序是在类org.hibernate.cfg.Configuration中通过下面两段来解析hibernate.cfg.xml文件:
protected Configuration doConfigure(org.dom4j.Document doc) throws HibernateException {
Element sfNode = doc.getRootElement().element( "session-factory" );
String name = sfNode.attributeValue( "name" );
if ( name != null ) {
properties.setProperty( Environment.SESSION_FACTORY_NAME, name );
}
addProperties( sfNode );
parseSessionFactory( sfNode, name );
Element secNode = doc.getRootElement().element( "security" );
if ( secNode != null ) {
parseSecurity( secNode );
}
log.info( "Configured SessionFactory: " + name );
log.debug( "properties: " + properties );
return this;
}
private void addProperties(Element parent) {
Iterator iter = parent.elementIterator( "property" );
while ( iter.hasNext() ) {
Element node = (Element) iter.next();
String name = node.attributeValue( "name" );
String value = node.getText().trim();
log.debug( name + "=" + value );
properties.setProperty( name, value );
if ( !name.startsWith( "hibernate" ) ) {
properties.setProperty( "hibernate." + name, value );
}
}
Environment.verifyProperties( properties );
}
这里会将hibernate.cfg.xml文件中目录节点为session-factory下的所有属性名称为name的信息全部解析出来,并赋值到properties文件中去,其实是放在map中
这里有一点值得注意,程序在将name取得的值作为key的同时,也将hibernate.前缀与name取的值进行拼接当做key去存储,不知道这里的用意是为何
我们看看这句:Session session = sessionFactory.getCurrentSession();实际它是调用org.hibernate.context.ThreadLocalSessionContext中的currentSession()方法:
public final Session currentSession() throws HibernateException {
Session current = existingSession( factory );
if (current == null) {
current = buildOrObtainSession();
// register a cleanup synch
current.getTransaction().registerSynchronization( buildCleanupSynch() );
// wrap the session in the transaction-protection proxy
if ( needsWrapping( current ) ) {
current = wrap( current );
}
// then bind it
doBind( current, factory );
}
return current;
}
public final Session currentSession() throws HibernateException {
Session current = existingSession( factory );
if (current == null) {
current = buildOrObtainSession();
// register a cleanup synch
current.getTransaction().registerSynchronization( buildCleanupSynch() );
// wrap the session in the transaction-protection proxy
if ( needsWrapping( current ) ) {
current = wrap( current );
}
// then bind it
doBind( current, factory );
}
return current;
}
上面传入的factory其实就是hibernate.cfg.xml中的<property name="current_session_context_class">thread</property>值。
protected static Map sessionMap() {
return ( Map ) context.get();
}
/**
* Returns the value in the current thread's copy of this
* thread-local variable. If the variable has no value for the
* current thread, it is first initialized to the value returned
* by an invocation of the {@link #initialValue} method.
*
* @return the current thread's value of this thread-local
*/
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null)
return (T)e.value;
}
return setInitialValue();
}
通过上面我们不难看出,其实session是放在map中的,而且这个map是和线程有关联的