Hibernate连接池之ConnectionProvider

Hibernate是如何初始化连接池的呢?先看下图:

1.configuration实例化的时候,hibernate会去读取配置信息,并且将基本的配置信息(不包括实体映射信息)保存到configuration的字段properties中。

2.调用configuration的buildSessionFactory()方法,buildSessionFactory()方法又会调用SettingFactory的buildSettings(Properties props)方法。

3.buildSettings方法调用ConnectionProviderFactory的newConnectionProvider(Properties props)方法产生一个ConnectionProvider对象。

4.buildSettings方法实例化一个Setting对象,并将ConnectionProvider传递给Setting。

5.buildSettings返回一个Setting对象,然后buildSessionFactory()方法会实例化一个SessionFactoryImpl,并且将Setting对象传给SessionFactoryImpl,最后返回SessionFactoryImpl。

configuration的buildSessionFactory()方法实际上是实例化了一个连接池,并且把这个连接池交给SessionFactory管理。

ConnctionProvider是连接提供者,hibernate的数据库连接都来自它。当我们调用SessionFactoryImpl的openSession()方法时,就很容易获得数据库连接了。

Hibernate为ConnctionProvider提供了以下几个实现类:

1.C3P0ConnectionProvider。从C3P0连接池中获取数据库连接。

2.ProxoolConnectionProvider。从Proxool连接池中获取数据库连接。

3.DatasourceConnectionProvider。一般是通过JNDI从应用服务器(如JBoss)中获取数据源。

4.DriverManagerConnectionProvider。Hibernate自带的连接池。

5.UserSuppliedConnectionProvider。没有任何实现,只是抛出了异常。

到底使用哪一个呢?看看ConnectionProviderFactory.newConnectionProvider(Properties props)方法就知道了:

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. public static ConnectionProvider newConnectionProvider(Properties properties, Map connectionProviderInjectionData)  
  2.             throws HibernateException {  
  3.         ConnectionProvider connections;  
  4.         String providerClass = properties.getProperty( Environment.CONNECTION_PROVIDER );//hibernate.connection.provider_class  
  5.         if ( providerClass != null ) {  
  6.             connections = initializeConnectionProviderFromConfig( providerClass );  
  7.         }  
  8.         else if ( c3p0ConfigDefined( properties ) && c3p0ProviderPresent() ) {  
  9.             connections = initializeConnectionProviderFromConfig("org.hibernate.connection.C3P0ConnectionProvider");  
  10.         }  
  11.         else if ( properties.getProperty( Environment.DATASOURCE ) != null ) {//hibernate.connection.datasource  
  12.             connections = new DatasourceConnectionProvider();  
  13.         }  
  14.         else if ( properties.getProperty( Environment.URL ) != null ) {//hibernate.connection.url  
  15.             connections = new DriverManagerConnectionProvider();  
  16.         }  
  17.         else {  
  18.             connections = new UserSuppliedConnectionProvider();  
  19.         }  
  20.   
  21.         ......  
  22.         connections.configure( properties );  
  23.         return connections;  
  24. }  
上面是核心代码。

 

1.如果配置了hibernate.connection.provider_class属性,就会根据指定的类去实例化。属性值为C3P0ConnectionProvider或者ProxoolConnectionProvider的全限定名。

2.如果配置了hibernate.connection.datasource属性,则会实例化一个DatasourceConnectionProvider。属性值为JNDI名称。

3.如果上面两个都没配置,则会去判断是否配置hibernate.connection.url属性。如果配置了,会实例化一个DriverManagerConnectionProvider。

4.如果没有配置hibernate.connection.url属性,则实例化一个UserSuppliedConnectionProvider,实际上是抛出了异常。

我们也可以自己写一个ConnctionProvider的实现,然后配置hibernate.connection.provider_class属性,属性值为我们自己的实现类的全限定名。