首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

hibernate3 源码翻阅 (三) Connection

2012-11-20 
hibernate3 源码阅读 (三)Connection用 jdbc 操作数据库,是围绕 Connection 这个类 进行的,hibernate 也一

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 datatry {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的构造以及调用 大概看了一遍。

?

<bean id="dataSource" 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"name="code">.... 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> 3 楼 gutou9 2010-07-19   www.uupan.net 网盘资源集散,使用网盘也赚钱

热点排行