此次討論一下Hibernate的ConnectionProvider接口, 由於我看到某些Hibernate項目是這樣配置的ide
- <property name="c3p0.min_size">5</property>
- <property name="c3p0.max_size">30</property>
- <property name="c3p0.time_out">1800</property>
- <property name="c3p0.max_statement">50</property>
問題是, 這樣就配置好了嗎? hibernate.connection.provider_class到底需不須要呢? 來看看Hibernate 3.3.2 GA的源碼 ConnectionProviderFactory類的newConnectionProvider方法.性能
- 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;
- }
上面的代碼有點長, 精簡出核心部分:url
- ConnectionProvider connections;
- String providerClass = properties.getProperty(Environment.CONNECTION_PROVIDER);
- if ( providerClass!=null ) {
- connections = (ConnectionProvider) ReflectHelper.classForName(providerClass).newInstance();
- }else if ( properties.getProperty(Environment.DATASOURCE)!=null ) {
- connections = new DatasourceConnectionProvider();
- }else if ( properties.getProperty(Environment.URL)!=null ) {
- connections = new DriverManagerConnectionProvider();
- }else {
- connections = new UserSuppliedConnectionProvider();
- }
- /**
- Environment.CONNECTION_PROVIDER 的定義:
- public static final String CONNECTION_PROVIDER ="hibernate.connection.provider_class";
- Environment.DATASOURCE 的定義:
- public static final String DATASOURCE ="hibernate.connection.datasource";
- Environment.URL 的定義:
- public static final String URL ="hibernate.connection.url";
- */
能夠看到, 若是hibernate.connection.provider_class和hibernate.connection.datasource都沒有定義,就會使用內置的鏈接池,OK,那繼續看默認的鏈接池DriverManagerConnectionProvider,只貼精華部分:spa
- /*鏈接池就是一個ArrayList !!*/
- private final ArrayList pool = new ArrayList();
- /*獲取鏈接*/
- public Connection getConnection() throws SQLException {
- synchronized (pool) {
- if ( !pool.isEmpty() ) {
- int last = pool.size() - 1;
- 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);
- return conn;
- }
- /*釋放鏈接*/
- public void closeConnection(Connection conn) throws SQLException {
- synchronized (pool) {
- int currentSize = pool.size();
- if ( currentSize < poolSize ) {
- pool.add(conn);
- return;
- }
- }
- conn.close();
- }
用一個簡單ArrayList作出來的默認鏈接池,就是這樣簡單!!! sorry,是簡陋!!! 無比簡陋!! 性能能有多好?! 你的Hibernate還在用默認鏈接池? 你尚未配hibernate.connection.provider_class屬性? 快去看看吧!!hibernate