ConnectionProvider 在hibernate 3.2.3中有五种实现 ,分别是DatasourceConnectionProvider、C3P0ConnectionProvider、ProxoolConnectionProvider、DriverManagerConnectionProvider、UserSuppliedConnectionProvider。
DatasourceConnectionProvider:使用JNDI注册的数据源,如果要使用它,需配置hibernate.connection.datasource 属性。
C3P0ConnectionProvider:使用了C3P0连接池,如果要使用它,需配置hibernate.c3p0.*属性,
ProxoolConnectionProvider:使用了Proxool连接池,如果要使用它,需配置hibernate.proxool.*属性
DriverManagerConnectionProvider:使用了java.sql.DriverManager,也实现了一个简单的连接池。
UserSuppliedConnectionProvider:ConnectionProvider接口的实现,当请求连接的时候,抛出异常。
hibernate获取Connection Provider的源代码如下:
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.fatal("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.C3P0_MAX_SIZE)!=null ) { connections = new C3P0ConnectionProvider(); } else if ( properties.getProperty(Environment.PROXOOL_XML)!=null || properties.getProperty(Environment.PROXOOL_PROPERTIES)!=null || properties.getProperty(Environment.PROXOOL_EXISTING_POOL)!=null ) { connections = new ProxoolConnectionProvider(); } 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; }
从源代码不难看出这么多种Connection Provider的优先顺序 :
自定义Connection Provider >DatasourceConnectionProvider>C3P0ConnectionProvider
> ProxoolConnectionProvider>DriverManagerConnectionProvider>UserSuppliedConnectionProvider
首先hibernate检测hibernate.connection.provider_class是否配置了,如果配置了,则根据该配置对应的类(必须要实现ConnectionProvider接口,含无参构造函数)名实例化。
如果hibernate.connection.provider_class没有配置,则检测hibernate.connection.datasource配置,如果配置了,则使用DatasourceConnectionProvider。
如果hibernate.connection.datasource没有配置,则检测hibernate.c3p0.max_size,如果配置了,则使用C3P0ConnectionProvider。
如果hibernate.c3p0.max_size没有配置,则检测hibernate.proxool.xml、hibernate.proxool.properties、hibernate.proxool.existing_pool的配置,只要其中任何一个配置了,则使用ProxoolConnectionProvider。
如果hibernate.proxool.xml、hibernate.proxool.properties、hibernate.proxool.existing_pool都没有配置,则检测hibernate.connection.url的配置,则使用DriverManagerConnectionProvider。
如果以上没有配置的话,则使用UserSuppliedConnectionProvider(抛出异常),提示需要提供连接。