proxool使用起来怎么这么麻烦?

时间:2021-10-31 01:08:13

【题记】 自己在使用proxool连接池的时候,发现使用proxool官网上介绍的几种配置方案都觉得很麻烦,而且要是改个alias名字还要改程序,很麻烦。

下面是具体的描述:

想要自己封装数据库的连接, 通过proxool的getConnection()方法获得连接。

proxool官网:http://proxool.sourceforge.net/index.html

官网上推荐的两种使用方式:

1、 properties文件方式

Using a properties (flat text) file. For instance

jdbc-0.proxool.alias=property-test
jdbc-0.proxool.driver-url=jdbc:hsqldb:.
jdbc-0.proxool.driver-class=org.hsqldb.jdbcDriver
jdbc-0.user=sa
jdbc-0.password=
jdbc-0.proxool.maximum-connection-count=10
jdbc-0.proxool.house-keeping-test-sql=select CURRENT_DATE

The first word (up to the first dot) must start with "jdbc", but it can be anything you like. Use unique names to identify each pool. Any property not starting with "jdbc" will be ignored. The properties prefixed with "proxool." will be used by Proxool while the properties that are not prefixed will be passed on to the delegate JDBC driver.

And then simply call the property configurator (PropertyConfigurator) in your startup code:


PropertyConfigurator.configure("src/java-test/org/logicalcobwebs/proxool/configuration/test.properties"); 

Again, picking up connections is really easy ("property-test" is the alias we used above)

connection = DriverManager.getConnection("proxool.property-test");


2、xml文件方式


<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- the proxool configuration can be embedded within your own application's.
Anything outside the "proxool" tag is ignored. -->
<something-else-entirely>
  <proxool>
    <alias>xml-test</alias>
    <driver-url>jdbc:hsqldb:.</driver-url>
    <driver-class>org.hsqldb.jdbcDriver</driver-class>
    <driver-properties>
      <property name="user" value="sa"/>
      <property name="password" value=""/>
    </driver-properties>
    <maximum-connection-count>10</maximum-connection-count>
    <house-keeping-test-sql>select CURRENT_DATE</house-keeping-test-sql>
  </proxool>
</something-else-entirely>


And then simply call the XML configurator (JAXPConfigurator) in your startup code:

JAXPConfigurator.configure("src/java-test/org/logicalcobwebs/proxool/configuration/test-no-ns.xml", false);


// The false means non-validating

And then, picking up connections is really easy ("xml-test" is the alias we used above)

connection = DriverManager.getConnection("proxool.xml-test");


NOTE: you need to include a JAXP compliant XML parser to use this configuration method. For instance,Crimson, orXerces


通过官网上的示例可以发现,想要引入proxool时候挺麻烦的,具体地方有两个:

1、使用任何一个configurator时,必须制定具体路径(以工程根目录为起始路径,例如

src/java-test/org/logicalcobwebs/proxool/configuration/test.properties"
)一旦部署到web服务器上就容易出错。所以最好使用能相对路径以lcasses为根路径或当前java文件路径为起始路径。


2、必须使用 DriverManager.getConnection("连接池名字的url");来获取连接。这个url需要手动写,不能根据配置文件生成,

要是改动配置文件时不能自动变化,还必须手动改。所以想要是configuration完了以后能自动获取得到就ok了。


解决方案:

于是针对它的PropertyConfigurator进行了简单的扩展修改:

package org.study.db.dao.base;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.logicalcobwebs.proxool.ProxoolConstants;
import org.logicalcobwebs.proxool.ProxoolException;
import org.logicalcobwebs.proxool.ProxoolFacade;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * Uses a standard Java properties file to configure Proxool. For example:
 *
 * <pre>
 * jdbc-0.proxool.alias=property-test
 * jdbc-0.proxool.driver-url=jdbc:hsqldb:.
 * jdbc-0.proxool.driver-class=org.hsqldb.jdbcDriver
 * jdbc-0.user=foo
 * jdbc-0.password=bar
 * jdbc-0.proxool.house-keeping-sleep-time=40000
 * jdbc-0.proxool.house-keeping-test-sql=select CURRENT_DATE
 * jdbc-0.proxool.maximum-connection-count=10
 * jdbc-0.proxool.minimum-connection-count=3
 * jdbc-0.proxool.maximum-connection-lifetime=18000000
 * jdbc-0.proxool.simultaneous-build-throttle=5
 * jdbc-0.proxool.recently-started-threshold=40000
 * jdbc-0.proxool.overload-without-refusal-lifetime=50000
 * jdbc-0.proxool.maximum-active-time=60000
 * jdbc-0.proxool.verbose=true
 * jdbc-0.proxool.trace=true
 * jdbc-0.proxool.fatal-sql-exception=Fatal error
 * jdbc-0.proxool.prototype-count=2
 *
 * jdbc-1.proxool.alias=property-test-2
 * jdbc-1.proxool.driver-url=jdbc:hsqldb:.
 * jdbc-1.proxool.driver-class=org.hsqldb.jdbcDriver
 * jdbc-1.user=scott
 * jdbc-1.password=tiger
 * jdbc-1.proxool.house-keeping-sleep-time=40000
 * jdbc-1.proxool.house-keeping-test-sql=select CURRENT_DATE
 * jdbc-1.proxool.maximum-connection-count=10
 * jdbc-1.proxool.minimum-connection-count=3
 * jdbc-1.proxool.maximum-connection-lifetime=18000000
 * jdbc-1.proxool.simultaneous-build-throttle=5
 * jdbc-1.proxool.recently-started-threshold=40000
 * jdbc-1.proxool.overload-without-refusal-lifetime=50000
 * jdbc-1.proxool.maximum-active-time=60000
 * jdbc-1.proxool.verbose=true
 * jdbc-1.proxool.trace=true
 * jdbc-1.proxool.fatal-sql-exception=Fatal error
 * jdbc-1.proxool.prototype-count=2
 * </pre>
 *
 * <p>The first word (up to the first dot) must start with "jdbc", but it can
 * be anything you like. Use unique names to identify each pool. Any property
 * not starting with "jdbc" will be ignored.</p>
 * <p>
 * The properties prefixed with "proxool."  will be used by Proxool while
 * the properties that are not prefixed will be passed on to the
 * delegate JDBC driver.
 * </p>
 *
 * @version $Revision: 1.11 $, $Date: 2006/01/18 14:39:58 $
 * @author Bill Horsman (bill@logicalcobwebs.co.uk)
 * @author $Author: billhorsman $ (current maintainer)
 * @since Proxool 0.5
 */
public class PropertyConfigurator {
    private static final Log LOG = LogFactory.getLog(PropertyConfigurator.class);

    protected static final String PREFIX = "jdbc";

    private static final String DOT = ".";

    private static final String EXAMPLE_FORMAT = PREFIX + "*" + DOT + "*";

    /**
     * Configure proxool with the given properties file.
     * @param filename the filename of the properties file.
     * @throws ProxoolException if the configuration fails.
     * @throws FileNotFoundException 
     */
    public static List<String> configure(String fileName) throws ProxoolException{
        Properties properties = new Properties();
     	InputStream inputStream = null;
     	File file = new File(fileName);
     	if(file.exists()){
     		try {
     			inputStream = new FileInputStream(fileName);
				properties.load(inputStream);
			} catch (IOException e) {
				throw new ProxoolException("Couldn't load property file " + fileName);
			}
     	}else{
     		try {
     			inputStream = PropertyConfigurator.class.getResourceAsStream(fileName);
     			properties.load(inputStream);
     		} catch (Exception ioe) {
     			try {
     				// 若配置文件在classes根目录下,加载它
     				inputStream = PropertyConfigurator.class.getClassLoader().getResourceAsStream(fileName);
     				properties.load(inputStream);
     			} catch (Exception e) {
     				 throw new ProxoolException("Couldn't load property file " + fileName);
     			}
     		}
     	}
 		
     	if(inputStream != null){
			try {
				inputStream.close();
			} catch (IOException e) {
				LOG.error(e);
			}
     	}
     		
        return configure(properties);
    }

    /**
     * Configure proxool with the given properties.
     * @param properties the properties instance to use.
     * @throws ProxoolException if the configuration fails.
     */
    public static List<String> configure(Properties properties) throws ProxoolException {
    	List<String> dbUrls = new ArrayList<String>();
        final Map<String, Properties> propertiesMap = new HashMap<String, Properties>();
        @SuppressWarnings("rawtypes")
		final Iterator allPropertyKeysIterator = properties.keySet().iterator();
        Properties proxoolProperties = null;

        while (allPropertyKeysIterator.hasNext()) {
            String key = (String) allPropertyKeysIterator.next();
            String value = properties.getProperty(key);

            if (key.startsWith(PREFIX)) {
                int a = key.indexOf(DOT);
                if (a == -1) {
                    throw new ProxoolException("Property " + key + " must be of the format " + EXAMPLE_FORMAT);
                }
                final String tag = key.substring(0, a);
                final String name = key.substring(a + 1);
                proxoolProperties = (Properties) propertiesMap.get(tag);
                if (proxoolProperties == null) {
                    proxoolProperties = new Properties();
                    propertiesMap.put(tag, proxoolProperties);
                }
                proxoolProperties.put(name, value);
            }
        }

        @SuppressWarnings("rawtypes")
		final Iterator tags = propertiesMap.keySet().iterator();
        while (tags.hasNext()) {
            proxoolProperties = (Properties) propertiesMap.get(tags.next());
            // make sure that required propeties are defined
            // and build the url
            // Check that we have defined the minimum information
            final String driverClass = proxoolProperties.getProperty(ProxoolConstants.DRIVER_CLASS_PROPERTY);
            final String driverUrl = proxoolProperties.getProperty(ProxoolConstants.DRIVER_URL_PROPERTY);
            if (driverClass == null || driverUrl == null) {
                throw new ProxoolException("You must define the " + ProxoolConstants.DRIVER_CLASS_PROPERTY + " and the "
                    + ProxoolConstants.DRIVER_URL_PROPERTY + ".");
            }
            final String alias = proxoolProperties.getProperty(ProxoolConstants.ALIAS_PROPERTY);

            // Build the URL; optionally defining a name
            StringBuffer url = new StringBuffer();
            url.append("proxool");
            if (alias != null) {
                url.append(ProxoolConstants.ALIAS_DELIMITER);
                url.append(alias);
                proxoolProperties.remove(ProxoolConstants.ALIAS_PROPERTY);
            }
            url.append(ProxoolConstants.URL_DELIMITER);
            url.append(driverClass);
            proxoolProperties.remove(ProxoolConstants.DRIVER_CLASS_PROPERTY);
            url.append(ProxoolConstants.URL_DELIMITER);
            url.append(driverUrl);
            proxoolProperties.remove(ProxoolConstants.DRIVER_URL_PROPERTY);
            if (LOG.isDebugEnabled()) {
                LOG.debug("Created url: " + url);
            }

            String urlStr = url.toString();
            ProxoolFacade.registerConnectionPool(urlStr, proxoolProperties);
            dbUrls.add(urlStr);
        }
        return dbUrls;
    }

}

/*
 Revision history:
 $Log: PropertyConfigurator.java,v $
 
 Revision: 1.11 , 2006/01/18 14:39:58 Walker Jong
 revise the file path resolution and return the dbUrls 
 to facilitate referring DriverManager.getConnection(dbUrl);
  
 Revision 1.11  2006/01/18 14:39:58  billhorsman
 Unbundled Jakarta's Commons Logging.

 Revision 1.10  2003/03/05 23:28:56  billhorsman
 deprecated maximum-new-connections property in favour of
 more descriptive simultaneous-build-throttle

 Revision 1.9  2003/03/03 11:12:00  billhorsman
 fixed licence

 Revision 1.8  2003/02/06 17:41:05  billhorsman
 now uses imported logging

 Revision 1.7  2003/02/05 14:46:31  billhorsman
 fixed copyright and made PREFIX protected for
 use by ServletConfigurator

 Revision 1.6  2003/01/27 18:26:43  billhorsman
 refactoring of ProxyConnection and ProxyStatement to
 make it easier to write JDK 1.2 patch

 Revision 1.5  2003/01/23 10:41:05  billhorsman
 changed use of pool-name to alias for consistency

 Revision 1.4  2003/01/22 17:35:01  billhorsman
 checkstyle

 Revision 1.3  2003/01/18 15:13:12  billhorsman
 Signature changes (new ProxoolException
 thrown) on the ProxoolFacade API.

 Revision 1.2  2002/12/26 11:32:59  billhorsman
 Rewrote to support new format.

 Revision 1.1  2002/12/15 18:48:33  chr32
 Movied in from 'ext' source tree.

 Revision 1.4  2002/11/09 15:57:57  billhorsman
 fix doc

 Revision 1.3  2002/11/02 14:22:16  billhorsman
 Documentation

 Revision 1.2  2002/10/27 13:05:01  billhorsman
 checkstyle

 Revision 1.1  2002/10/27 12:00:16  billhorsman
 moved classes from ext sub-package which is now obsolete - let's keep everything together in one place

 Revision 1.1  2002/10/25 10:40:27  billhorsman
 draft

*/

这样就可以解决上面提到的两个使用不便的问题。


然后使用如下:

jdbc.properties

 
 jdbc-0.proxool.alias=property-test
 jdbc-0.proxool.driver-url=jdbc:hsqldb:.
 jdbc-0.proxool.driver-class=org.hsqldb.jdbcDriver
 jdbc-0.user=foo
 jdbc-0.password=bar
 jdbc-0.proxool.house-keeping-sleep-time=40000
 jdbc-0.proxool.house-keeping-test-sql=select CURRENT_DATE
 jdbc-0.proxool.maximum-connection-count=10
 jdbc-0.proxool.minimum-connection-count=3
 jdbc-0.proxool.maximum-connection-lifetime=18000000
 jdbc-0.proxool.simultaneous-build-throttle=5
 jdbc-0.proxool.recently-started-threshold=40000
 jdbc-0.proxool.overload-without-refusal-lifetime=50000
 jdbc-0.proxool.maximum-active-time=60000
 jdbc-0.proxool.verbose=true
 jdbc-0.proxool.trace=true
 jdbc-0.proxool.fatal-sql-exception=Fatal error
 jdbc-0.proxool.prototype-count=2

 jdbc-1.proxool.alias=property-test-2
 jdbc-1.proxool.driver-url=jdbc:hsqldb:.
 jdbc-1.proxool.driver-class=org.hsqldb.jdbcDriver
 jdbc-1.user=scott
 jdbc-1.password=tiger
 jdbc-1.proxool.house-keeping-sleep-time=40000
 jdbc-1.proxool.house-keeping-test-sql=select CURRENT_DATE
 jdbc-1.proxool.maximum-connection-count=10
 jdbc-1.proxool.minimum-connection-count=3
 jdbc-1.proxool.maximum-connection-lifetime=18000000
 jdbc-1.proxool.simultaneous-build-throttle=5
 jdbc-1.proxool.recently-started-threshold=40000
 jdbc-1.proxool.overload-without-refusal-lifetime=50000
 jdbc-1.proxool.maximum-active-time=60000
 jdbc-1.proxool.verbose=true
 jdbc-1.proxool.trace=true
 jdbc-1.proxool.fatal-sql-exception=Fatal error
 jdbc-1.proxool.prototype-count=2


//这里返回的连接池dbURL,可以同时配置多个连接池
List<String> dbUrls = PropertyConfigurator("jdbc.properties");

//注意:在使用getConnection()方法之前,需要静态加载
//Class.forName("org.logicalcobwebs.proxool.ProxoolDriver");

//get(0)返回的是第一个连接池的dbURL
Connection conn = DriverManager.getConnection(dbUrls.get(0))

XML文件方式的配置就不赘述了,解决方案类似。

该文主要针对自己封装获取proxool的方式,若要与其他框架集成如spring可看下篇文章。