`
gutou9
  • 浏览: 145420 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

hibernate3 源码阅读 (三) Connection

阅读更多

用 jdbc 操作数据库,是围绕 Connection 这个类 进行的,

hibernate 也一样,

这篇我们围绕 Connection, 看看hibernate是如何做的。

 

SessionImpl 里有一个方法 connection()

 

public Connection connection() throws HibernateException {
	errorIfClosed();
	return jdbcContext.borrowConnection();
}

 

 Session 取得 Connection, 是委托 jdbcContext 。

 看下 jdbcContext.borrowConnection();

public Connection borrowConnection() {
	return connectionManager.borrowConnection();
}

 

 jdbcContext 取得 Connection, 则又要委托 connectionManager,

那我们在看下ConnectionManager,

	public Connection borrowConnection() {
		if ( isClosed ) {
			throw new HibernateException( "connection manager has been closed" );
		}
		if ( isSuppliedConnection() ) {
			return connection;
		}
		else {
			if ( borrowedConnection == null ) {
				borrowedConnection = BorrowedConnectionProxy.generateProxy( this );
			}
			return borrowedConnection;
		}
	}

 

ConnectionManager

 

	private void openConnection() throws HibernateException {
		if ( connection != null ) {
			return;
		}

		log.debug("opening JDBC connection");
		try {
			connection = factory.getConnectionProvider().getConnection();
		}
		catch (SQLException sqle) {
			throw JDBCExceptionHelper.convert(
					factory.getSQLExceptionConverter(),
					sqle,
					"Cannot open connection"
				);
		}

		callback.connectionOpened(); // register synch; stats.connect()
	}

 

 关键一句

connection = factory.getConnectionProvider().getConnection();

 

这个factory是从哪来的呢?

 

new ConnectionManager(
          owner.getFactory(),
          this,
          owner.getConnectionReleaseMode(),
          connection,
          interceptor
   );

  

是在JdbcContext 初始化时, ConnectionManager 构造函数中作为参数传进来的,

我们已经知道了这个 owner,就是SessionImpl,

那么看看SessionImpl 的 factory ,

 

SessionImpl(
   final Connection connection,
   final SessionFactoryImpl factory,
   final boolean autoclose,
   final long timestamp,
   final Interceptor interceptor,
   final EntityMode entityMode,
   final boolean flushBeforeCompletionEnabled,
   final boolean autoCloseSessionEnabled,
   final ConnectionReleaseMode connectionReleaseMode) {
  super( factory );

 

 

SessionImpl 中的 factory,又是在SessionImpl 构造函数中作为参数传进来的,

那我们再往上一层看,谁初始化的SessionImpl 呢,前边说了,SessionFactory

 

	private SessionImpl openSession(
		Connection connection,
	    boolean autoClose,
	    long timestamp,
	    Interceptor sessionLocalInterceptor
	) {
		return new SessionImpl(
		        connection,
		        this,
		        autoClose,
		        timestamp,
		        sessionLocalInterceptor == null ? interceptor : sessionLocalInterceptor,
		        settings.getDefaultEntityMode(),
		        settings.isFlushBeforeCompletionEnabled(),
		        settings.isAutoCloseSessionEnabled(),
		        settings.getConnectionReleaseMode()
			);
	}

 

看到这个this了吗,就是他,从SessionImpl 传给 JdbcContext 又传个 ConnectionManager ,

ConnectionManager 里的  factory 就是 SessionFactoryImpl,

factory 找到了,再看看取 ConnectionProvider,

 

ConnectionManager

 

  factory.getConnectionProvider().getConnection();

 

要从 factory 中取一个 ConnectionProvider,

 

SessionFactory

 

	public ConnectionProvider getConnectionProvider() {
		return settings.getConnectionProvider();
	}

 

Settings

	public ConnectionProvider getConnectionProvider() {
		return connectionProvider;
	}

 

  原来这个ConnectionProvider 最终是放在 Settings 里边的,

 那么我们看一下 settings 的初始化 看看 settings 是怎么构造出 ConnectionProvider 的,

 

Configuration

 Settings settings = buildSettings( copy );
 

 

	public Settings buildSettings(Properties props) throws HibernateException {
		return settingsFactory.buildSettings( props );
	}

 

SettingsFactory

 

	
	public Settings buildSettings(Properties props) {
		Settings settings = new Settings();
		
		//SessionFactory name:
		
		String sessionFactoryName = props.getProperty(Environment.SESSION_FACTORY_NAME);
		settings.setSessionFactoryName(sessionFactoryName);

		//JDBC and connection settings:

		ConnectionProvider connections = createConnectionProvider(props);
		settings.setConnectionProvider(connections);

 

	protected ConnectionProvider createConnectionProvider(Properties properties) {
		return ConnectionProviderFactory.newConnectionProvider(properties);
	}

 

可以看到,hibernate 通过 ConnectionProviderFactory 类,以hibernate配置文件 (properties) 做参数,

构造了 Settings 里边的 ConnectionProvider,

 

我们看一下具体实现,

	public static ConnectionProvider newConnectionProvider(Properties properties, Map connectionProviderInjectionData) throws HibernateException {
		ConnectionProvider connections;
		String providerClass = properties.getProperty(Environment.CONNECTION_PROVIDER);
		if ( providerClass!=null ) {
			try {
				log.info("Initializing connection provider: " + providerClass);
				connections = (ConnectionProvider) ReflectHelper.classForName(providerClass).newInstance();
			}
			catch ( Exception e ) {
				log.error( "Could not instantiate connection provider", e );
				throw new HibernateException("Could not instantiate connection provider: " + providerClass);
			}
		}
		else if ( properties.getProperty(Environment.DATASOURCE)!=null ) {
			connections = new DatasourceConnectionProvider();
		}
		else if ( properties.getProperty(Environment.URL)!=null ) {
			connections = new DriverManagerConnectionProvider();
		}
		else {
			connections = new UserSuppliedConnectionProvider();
		}

		if ( connectionProviderInjectionData != null && connectionProviderInjectionData.size() != 0 ) {
			//inject the data
			try {
				BeanInfo info = Introspector.getBeanInfo( connections.getClass() );
				PropertyDescriptor[] descritors = info.getPropertyDescriptors();
				int size = descritors.length;
				for (int index = 0 ; index < size ; index++) {
					String propertyName = descritors[index].getName();
					if ( connectionProviderInjectionData.containsKey( propertyName ) ) {
						Method method = descritors[index].getWriteMethod();
						method.invoke( connections, new Object[] { connectionProviderInjectionData.get( propertyName ) } );
					}
				}
			}
			catch (IntrospectionException e) {
				throw new HibernateException("Unable to inject objects into the conenction provider", e);
			}
			catch (IllegalAccessException e) {
				throw new HibernateException("Unable to inject objects into the conenction provider", e);
			}
			catch (InvocationTargetException e) {
				throw new HibernateException("Unable to inject objects into the conenction provider", e);
			}
		}
		connections.configure(properties);
		return connections;
	}

 

好了,我们终于找到了 ConnectionProvider构造的具体实现细节,

根据配置文件,

先判断具体类型,是DatasourceConnectionProvider,DriverManagerConnectionProvider 或是其他,

然后调用 ConnectionProvider 的 Configuration 方法

connections.configure(properties);

一个 ConnectionProvider 就构造完了,

有了ConnectionProvider,就可以通过他的 getConnection 方法,得到我们要的Connection,

 

	public Connection getConnection() throws SQLException {

		if ( log.isTraceEnabled() ) log.trace( "total checked-out connections: " + checkedOut );

		synchronized (pool) {
			if ( !pool.isEmpty() ) {
				int last = pool.size() - 1;
				if ( log.isTraceEnabled() ) {
					log.trace("using pooled JDBC connection, pool size: " + last);
					checkedOut++;
				}
				Connection pooled = (Connection) pool.remove(last);
				if (isolation!=null) pooled.setTransactionIsolation( isolation.intValue() );
				if ( pooled.getAutoCommit()!=autocommit ) pooled.setAutoCommit(autocommit);
				return pooled;
			}
		}

		log.debug("opening new JDBC connection");
		Connection conn = DriverManager.getConnection(url, connectionProps);
		if (isolation!=null) conn.setTransactionIsolation( isolation.intValue() );
		if ( conn.getAutoCommit()!=autocommit ) conn.setAutoCommit(autocommit);

		if ( log.isDebugEnabled() ) {
			log.debug( "created connection to: " + url + ", Isolation Level: " + conn.getTransactionIsolation() );
		}
		if ( log.isTraceEnabled() ) checkedOut++;

		return conn;
	}

 

 Connection conn = DriverManager.getConnection(url, connectionProps);

至此,我们就把 hibernate 中 关于Connection的构造以及调用 大概看了一遍。

 

4
0
分享到:
评论
2 楼 jiahch 2010-06-24  
.... 
else if ( properties.getProperty(Environment.DATASOURCE)!=null ) {   
        <SPAN style="COLOR: #ff0000">connections = new DatasourceConnectionProvider();</SPAN>   
    }   
    else if ( properties.getProperty(Environment.URL)!=null ) {   
        <SPAN style="COLOR: #ff0000">connections = new DriverManagerConnectionProvider();</SPAN>   
    }   
....

上面的代码中  的
Environment.DATASOURCE  如果和 spring 联合起来使用的话 就应该是 其中的 属性dataSource

<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref local="dataSource"/>
</property>
<property name="annotatedClasses">
<list>
<value>com.dne.framework.security.Role</value>
<value>com.dne.framework.security.User</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.connection.autocommit">false</prop>
<prop key="hibernate.connection.release_mode">auto</prop>
<!-- <prop key="hibernate.hbm2ddl.auto">update</prop> -->
</props>
</property>
1 楼 jiahch 2010-06-24  
很好的文章,在结合 配置文件讲解一下就更好了! 多些楼主

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />

		<!--<property name="url" value="jdbc:mysql://localhost:3306/testmysql"/>-->
<!--		<property name="url" value="jdbc:oracle:thin:@localhost:1521:HELL" /> 
		    <property name="url" value="jdbc:oracle:thin:@localhost:1521:ORCL" />
 -->		  
		 
 		<property name="url" value="jdbc:oracle:thin:@111.111.2.3:1521:FEEL" />  
		<property name="username" value="grgbanking" />
		<property name="password" value="passw0rd" />
		<property name="initialSize" value="3"/>
		<property name="maxIdle" value="2"/>
		<property name="minIdle" value="1"/>
		<property name="maxActive" value="50"/>
		<property name="removeAbandoned" value="true"/>
		<property name="removeAbandonedTimeout" value="180"/>
		<property name="maxWait" value="1000"/>
	</bean>
	
	
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource">
			<ref local="dataSource"/>
		</property>
		<property name="annotatedClasses">
		    <list>
		        <value>com.dne.framework.security.Role</value>
		        <value>com.dne.framework.security.User</value>
		        <value>com.dne.framework.security.Resource</value>

相关推荐

    Hibernate源码解析(一)

    《Hibernate源码解析(一)》 在Java开发领域,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。深入理解Hibernate的源码,不仅可以帮助开发者更好地运用该工具,还能提升对Java编程和...

    hibernate c3p0实例源码

    &lt;property name="connection.provider_class"&gt;org.hibernate.connection.C3P0ConnectionProvider &lt;property name="hibernate.c3p0.min_size"&gt;5 &lt;property name="hibernate.c3p0.max_size"&gt;20 &lt;property name="...

    java hibernate连接池源码

    &lt;property name="hibernate.connection.datasource"&gt;org.hibernate.connection.C3P0DataSource &lt;property name="hibernate.connection.url"&gt;jdbc:mysql://localhost:3306/testdb &lt;property name="hibernate....

    hibernate小程序源码

    "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"&gt; &lt;!-- Generated by MyEclipse Hibernate Tools. --&gt; &lt;hibernate-configuration&gt; ...

    hibernate3.2_src官方源码

    源码中涉及的`org.hibernate.connection`包揭示了这一过程。 通过深入学习这些关键概念和组件,开发者可以更好地掌握Hibernate的工作原理,提升数据库操作的效率和灵活性,同时也能为解决实际项目中的问题提供理论...

    Struts2+spring2+hibernate3实例源码-java源码

    ### Struts2 + Spring2 + Hibernate3 整合实例源码分析 #### 一、概述 随着企业级应用的发展,为了提高开发效率和系统维护性,越来越多的项目开始采用MVC设计模式。其中,Struts2作为MVC框架中的佼佼者,在前端...

    hibernate 连接数据库基础源码

    【hibernate 连接数据库基础源码】的解析与详解 Hibernate 是一款强大的对象关系映射(ORM)框架,它极大地简化了Java应用程序与数据库之间的交互。在本教程中,我们将深入探讨Hibernate如何连接到MySQL、Oracle等...

    hibernate3+ proxool-0.9.1配置 和proxool-0.9.1.jar

    Hibernate3是Hibernate项目的第三个主要版本,它提供了强大的对象关系映射功能,能够将Java对象与数据库表进行映射,从而简化数据库操作。它支持多种数据库,包括MySQL、Oracle、SQL Server等,并且具备事务管理、...

    Hibernate5.2.4环境搭建源码

    **Hibernate 5.2.4 环境搭建与源码解析** Hibernate 是一个流行的 Java 对象关系映射(ORM)框架,它极大地简化了数据库操作。在本教程中,我们将详细探讨如何搭建 Hibernate 5.2.4 的开发环境,并理解其源码。 ...

    hibernate源代码

    在这个“hibernate源代码”压缩包中,包含的是Hibernate框架的核心源码,这为我们深入理解其工作原理、自定义功能或者优化性能提供了可能。 在Hibernate源代码中,有几个关键的模块和类值得我们关注: 1. **...

    hibernate核心代码

    Hibernate是一个开源的对象关系映射(ORM)框架,它允许Java开发者在Java对象和数据库之间建立映射,从而简化数据操作。下面将详细讲解Hibernate的核心代码及其相关知识点。 1. **配置文件**: Hibernate的核心...

    Hibernate lazy加载FOR Connection

    标题中的“Hibernate lazy加载FOR Connection”指的是Hibernate框架中的一种特性,即懒加载(Lazy Loading)。在Hibernate中,懒加载是一种优化策略,它推迟对关联对象的加载,直到真正需要使用这些对象时才进行加载...

    hibernate 连接数据库基础源码3

    **hibernate 连接数据库基础源码3** 在初学者的编程旅程中,学习如何使用Hibernate连接到数据库是至关重要的一步。Hibernate是一款强大的对象关系映射(ORM)框架,它简化了Java应用程序与数据库之间的交互。在这个...

    hibernate数据库通用SQL代码

    Connection con = session.connection(); PreparedStatement pstmt = con.prepareStatement(sql); ResultSet rs = pstmt.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); Hashtable ht = null; ...

    hibernate源码

    通过深入研究Hibernate源码,我们可以了解到其内部的工作机制,包括对象关系映射(ORM)、查询语言(HQL)处理、缓存策略等核心概念。这篇内容将详细解析Hibernate的关键组件和工作流程,帮助你深化对数据持久化框架...

    配置Hibernate使用C3P0连接池

    &lt;property name="hibernate.connection.provider_class"&gt;org.hibernate.connection.C3P0ConnectionProvider &lt;property name="hibernate.c3p0.min_size"&gt;5 &lt;property name="hibernate.c3p0.max_size"&gt;20 ...

    hibernate学习笔记第四天的源码

    **hibernate学习笔记第四天源码解析** 在hibernate学习的过程中,第四天通常会深入探讨实体类、映射文件、配置文件以及查询语言等方面的内容。...建议结合源码仔细阅读并实践,以便更好地掌握hibernate的使用。

    hibernate_first项目源码

    《深入理解Hibernate_first项目源码》 Hibernate,作为一款强大的对象关系映射(ORM)框架,使得Java开发者在处理数据库操作时,可以更加专注于业务逻辑,而非底层的SQL语句。"hibernate_first"项目源码为我们提供...

    Hibernate5 + Mysql实现Demo源码

    **Hibernate5 + MySQL实现Demo源码详解** 在Java开发中,ORM(对象关系映射)框架使得数据库操作变得更加便捷,而Hibernate作为其中的佼佼者,深受开发者喜爱。本Demo基于Hibernate5,结合MySQL数据库,提供了完整...

Global site tag (gtag.js) - Google Analytics