Hibernate的ConnectionProvider是怎麼一回事?

此次討論一下Hibernate的ConnectionProvider接口, 由於我看到某些Hibernate項目是這樣配置的ide

  
  
  
  
  1. <property name="c3p0.min_size">5</property> 
  2. <property name="c3p0.max_size">30</property> 
  3. <property name="c3p0.time_out">1800</property> 
  4. <property name="c3p0.max_statement">50</property> 

問題是, 這樣就配置好了嗎? hibernate.connection.provider_class到底需不須要呢? 來看看Hibernate 3.3.2 GA的源碼 ConnectionProviderFactory類的newConnectionProvider方法.性能

  
  
  
  
  1. public static ConnectionProvider newConnectionProvider(Properties properties, Map connectionProviderInjectionData) throws HibernateException {  
  2.     ConnectionProvider connections;  
  3.     String providerClass = properties.getProperty(Environment.CONNECTION_PROVIDER);  
  4.     if ( providerClass!=null ) {  
  5.         try {  
  6.             log.info("Initializing connection provider: " + providerClass);  
  7.             connections = (ConnectionProvider) ReflectHelper.classForName(providerClass).newInstance();  
  8.         }  
  9.         catch ( Exception e ) {  
  10.             log.error( "Could not instantiate connection provider", e );  
  11.             throw new HibernateException("Could not instantiate connection provider: " + providerClass);  
  12.         }  
  13.     }  
  14.     else if ( properties.getProperty(Environment.DATASOURCE)!=null ) {  
  15.         connections = new DatasourceConnectionProvider();  
  16.     }  
  17.     else if ( properties.getProperty(Environment.URL)!=null ) {  
  18.         connections = new DriverManagerConnectionProvider();  
  19.     }  
  20.     else {  
  21.         connections = new UserSuppliedConnectionProvider();  
  22.     }  
  23.  
  24.     if ( connectionProviderInjectionData != null && connectionProviderInjectionData.size() != 0 ) {  
  25.         //inject the data  
  26.         try {  
  27.             BeanInfo info = Introspector.getBeanInfo( connections.getClass() );  
  28.             PropertyDescriptor[] descritors = info.getPropertyDescriptors();  
  29.             int size = descritors.length;  
  30.             for (int index = 0 ; index < size ; index++) {  
  31.                 String propertyName = descritors[index].getName();  
  32.                 if ( connectionProviderInjectionData.containsKey( propertyName ) ) {  
  33.                     Method method = descritors[index].getWriteMethod();  
  34.                     method.invoke( connections, new Object[] { connectionProviderInjectionData.get( propertyName ) } );  
  35.                 }  
  36.             }  
  37.         }  
  38.         catch (IntrospectionException e) {  
  39.             throw new HibernateException("Unable to inject objects into the conenction provider", e);  
  40.         }  
  41.         catch (IllegalAccessException e) {  
  42.             throw new HibernateException("Unable to inject objects into the conenction provider", e);  
  43.         }  
  44.         catch (InvocationTargetException e) {  
  45.             throw new HibernateException("Unable to inject objects into the conenction provider", e);  
  46.         }  
  47.     }  
  48.     connections.configure(properties);  
  49.     return connections;  
  50.     } 

上面的代碼有點長, 精簡出核心部分:url

  
  
  
  
  1. ConnectionProvider connections;  
  2. String providerClass = properties.getProperty(Environment.CONNECTION_PROVIDER);  
  3. if ( providerClass!=null ) {  
  4.     connections = (ConnectionProvider) ReflectHelper.classForName(providerClass).newInstance();  
  5. }else if ( properties.getProperty(Environment.DATASOURCE)!=null ) {  
  6.     connections = new DatasourceConnectionProvider();  
  7. }else if ( properties.getProperty(Environment.URL)!=null ) {  
  8.     connections = new DriverManagerConnectionProvider();  
  9. }else {  
  10.     connections = new UserSuppliedConnectionProvider();  
  11. }  
  12. /**  
  13. Environment.CONNECTION_PROVIDER 的定義:  
  14. public static final String CONNECTION_PROVIDER ="hibernate.connection.provider_class";  
  15. Environment.DATASOURCE 的定義:  
  16. public static final String DATASOURCE ="hibernate.connection.datasource";  
  17. Environment.URL 的定義:  
  18. public static final String URL ="hibernate.connection.url";  
  19. */ 

能夠看到, 若是hibernate.connection.provider_class和hibernate.connection.datasource都沒有定義,就會使用內置的鏈接池,OK,那繼續看默認的鏈接池DriverManagerConnectionProvider,只貼精華部分:spa

  
  
  
  
  1. /*鏈接池就是一個ArrayList !!*/  
  2. private final ArrayList pool = new ArrayList();  
  3. /*獲取鏈接*/  
  4. public Connection getConnection() throws SQLException {  
  5.     synchronized (pool) {  
  6.         if ( !pool.isEmpty() ) {  
  7.             int last = pool.size() - 1;  
  8.             Connection pooled = (Connection) pool.remove(last);  
  9.             if (isolation!=null) pooled.setTransactionIsolation( isolation.intValue() );  
  10.             if ( pooled.getAutoCommit()!=autocommit ) pooled.setAutoCommit(autocommit);  
  11.             return pooled;  
  12.         }  
  13.     }  
  14.  
  15.     log.debug("opening new JDBC connection");  
  16.     Connection conn = DriverManager.getConnection(url, connectionProps);  
  17.     return conn;  
  18. }  
  19. /*釋放鏈接*/  
  20. public void closeConnection(Connection conn) throws SQLException {  
  21.     synchronized (pool) {  
  22.         int currentSize = pool.size();  
  23.         if ( currentSize < poolSize ) {  
  24.             pool.add(conn);  
  25.             return;  
  26.         }  
  27.     }  
  28.     conn.close();  

用一個簡單ArrayList作出來的默認鏈接池,就是這樣簡單!!! sorry,是簡陋!!! 無比簡陋!! 性能能有多好?! 你的Hibernate還在用默認鏈接池? 你尚未配hibernate.connection.provider_class屬性? 快去看看吧!!hibernate

相關文章
相關標籤/搜索