此次讨论一下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