Spring boot (12) tomcat jdbc连接池

默认连接池

  tomcat jdbc是从tomcat7开始推出的一个连接池,相比老的dbcp连接池要优秀很多,spring boot将tomcat jdbc作为默认的连接池,只要在pom.xml中引入了spring boot的jdbc组件,就会自动引入tomcat jdbc连接池。

 

默认参数

  以下是org.apache.tomcat.jdbc.pool.PoolProperties源码,这是tomcat jdbc连接池的默认初始参数。这个类实现了一个接口PoolConfiguration,查看这个接口的源码,里面有每一个参数的详细说明。

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.apache.tomcat.jdbc.pool;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;

public class PoolProperties implements PoolConfiguration, Cloneable, Serializable {
    private static final long serialVersionUID = -8519283440854213745L;
    private static final Log log = LogFactory.getLog(PoolProperties.class);
    public static final int DEFAULT_MAX_ACTIVE = 100;
    protected static final AtomicInteger poolCounter = new AtomicInteger(0);
    private volatile Properties dbProperties = new Properties();
    private volatile String url = null;
    private volatile String driverClassName = null;
    private volatile Boolean defaultAutoCommit = null;
    private volatile Boolean defaultReadOnly = null;
    private volatile int defaultTransactionIsolation = -1;
    private volatile String defaultCatalog = null;
    private volatile String connectionProperties;
    private volatile int initialSize = 10;
    private volatile int maxActive = 100;
    private volatile int maxIdle;
    private volatile int minIdle;
    private volatile int maxWait;
    private volatile String validationQuery;
    private volatile int validationQueryTimeout;
    private volatile String validatorClassName;
    private volatile Validator validator;
    private volatile boolean testOnBorrow;
    private volatile boolean testOnReturn;
    private volatile boolean testWhileIdle;
    private volatile int timeBetweenEvictionRunsMillis;
    private volatile int numTestsPerEvictionRun;
    private volatile int minEvictableIdleTimeMillis;
    private volatile boolean accessToUnderlyingConnectionAllowed;
    private volatile boolean removeAbandoned;
    private volatile int removeAbandonedTimeout;
    private volatile boolean logAbandoned;
    private volatile String name;
    private volatile String password;
    private volatile String username;
    private volatile long validationInterval;
    private volatile boolean jmxEnabled;
    private volatile String initSQL;
    private volatile boolean testOnConnect;
    private volatile String jdbcInterceptors;
    private volatile boolean fairQueue;
    private volatile boolean useEquals;
    private volatile int abandonWhenPercentageFull;
    private volatile long maxAge;
    private volatile boolean useLock;
    private volatile PoolProperties.InterceptorDefinition[] interceptors;
    private volatile int suspectTimeout;
    private volatile Object dataSource;
    private volatile String dataSourceJNDI;
    private volatile boolean alternateUsernameAllowed;
    private volatile boolean commitOnReturn;
    private volatile boolean rollbackOnReturn;
    private volatile boolean useDisposableConnectionFacade;
    private volatile boolean logValidationErrors;
    private volatile boolean propagateInterruptState;
    private volatile boolean ignoreExceptionOnPreLoad;

    public PoolProperties() {
        this.maxIdle = this.maxActive;
        this.minIdle = this.initialSize;
        this.maxWait = 30000;
        this.validationQueryTimeout = -1;
        this.testOnBorrow = false;
        this.testOnReturn = false;
        this.testWhileIdle = false;
        this.timeBetweenEvictionRunsMillis = 5000;
        this.minEvictableIdleTimeMillis = 60000;
        this.accessToUnderlyingConnectionAllowed = true;
        this.removeAbandoned = false;
        this.removeAbandonedTimeout = 60;
        this.logAbandoned = false;
        this.name = "Tomcat Connection Pool[" + poolCounter.addAndGet(1) + "-" + System.identityHashCode(PoolProperties.class) + "]";
        this.validationInterval = 3000L;
        this.jmxEnabled = true;
        this.testOnConnect = false;
        this.jdbcInterceptors = null;
        this.fairQueue = true;
        this.useEquals = true;
        this.abandonWhenPercentageFull = 0;
        this.maxAge = 0L;
        this.useLock = false;
        this.interceptors = null;
        this.suspectTimeout = 0;
        this.dataSource = null;
        this.dataSourceJNDI = null;
        this.alternateUsernameAllowed = false;
        this.commitOnReturn = false;
        this.rollbackOnReturn = false;
        this.useDisposableConnectionFacade = true;
        this.logValidationErrors = false;
        this.propagateInterruptState = false;
        this.ignoreExceptionOnPreLoad = false;
    }

    public void setAbandonWhenPercentageFull(int percentage) {
        if (percentage < 0) {
            this.abandonWhenPercentageFull = 0;
        } else if (percentage > 100) {
            this.abandonWhenPercentageFull = 100;
        } else {
            this.abandonWhenPercentageFull = percentage;
        }

    }

    public int getAbandonWhenPercentageFull() {
        return this.abandonWhenPercentageFull;
    }

    public boolean isFairQueue() {
        return this.fairQueue;
    }

    public void setFairQueue(boolean fairQueue) {
        this.fairQueue = fairQueue;
    }

    public boolean isAccessToUnderlyingConnectionAllowed() {
        return this.accessToUnderlyingConnectionAllowed;
    }

    public String getConnectionProperties() {
        return this.connectionProperties;
    }

    public Properties getDbProperties() {
        return this.dbProperties;
    }

    public Boolean isDefaultAutoCommit() {
        return this.defaultAutoCommit;
    }

    public String getDefaultCatalog() {
        return this.defaultCatalog;
    }

    public Boolean isDefaultReadOnly() {
        return this.defaultReadOnly;
    }

    public int getDefaultTransactionIsolation() {
        return this.defaultTransactionIsolation;
    }

    public String getDriverClassName() {
        return this.driverClassName;
    }

    public int getInitialSize() {
        return this.initialSize;
    }

    public boolean isLogAbandoned() {
        return this.logAbandoned;
    }

    public int getMaxActive() {
        return this.maxActive;
    }

    public int getMaxIdle() {
        return this.maxIdle;
    }

    public int getMaxWait() {
        return this.maxWait;
    }

    public int getMinEvictableIdleTimeMillis() {
        return this.minEvictableIdleTimeMillis;
    }

    public int getMinIdle() {
        return this.minIdle;
    }

    public String getName() {
        return this.name;
    }

    public int getNumTestsPerEvictionRun() {
        return this.numTestsPerEvictionRun;
    }

    public String getPassword() {
        return this.password;
    }

    public String getPoolName() {
        return this.getName();
    }

    public boolean isRemoveAbandoned() {
        return this.removeAbandoned;
    }

    public int getRemoveAbandonedTimeout() {
        return this.removeAbandonedTimeout;
    }

    public boolean isTestOnBorrow() {
        return this.testOnBorrow;
    }

    public boolean isTestOnReturn() {
        return this.testOnReturn;
    }

    public boolean isTestWhileIdle() {
        return this.testWhileIdle;
    }

    public int getTimeBetweenEvictionRunsMillis() {
        return this.timeBetweenEvictionRunsMillis;
    }

    public String getUrl() {
        return this.url;
    }

    public String getUsername() {
        return this.username;
    }

    public String getValidationQuery() {
        return this.validationQuery;
    }

    public int getValidationQueryTimeout() {
        return this.validationQueryTimeout;
    }

    public void setValidationQueryTimeout(int validationQueryTimeout) {
        this.validationQueryTimeout = validationQueryTimeout;
    }

    public String getValidatorClassName() {
        return this.validatorClassName;
    }

    public Validator getValidator() {
        return this.validator;
    }

    public void setValidator(Validator validator) {
        this.validator = validator;
        if (validator != null) {
            this.validatorClassName = validator.getClass().getName();
        } else {
            this.validatorClassName = null;
        }

    }

    public long getValidationInterval() {
        return this.validationInterval;
    }

    public String getInitSQL() {
        return this.initSQL;
    }

    public boolean isTestOnConnect() {
        return this.testOnConnect;
    }

    public String getJdbcInterceptors() {
        return this.jdbcInterceptors;
    }

    public PoolProperties.InterceptorDefinition[] getJdbcInterceptorsAsArray() {
        if (this.interceptors == null) {
            if (this.jdbcInterceptors == null) {
                this.interceptors = new PoolProperties.InterceptorDefinition[0];
            } else {
                String[] interceptorValues = this.jdbcInterceptors.split(";");
                PoolProperties.InterceptorDefinition[] definitions = new PoolProperties.InterceptorDefinition[interceptorValues.length + 1];
                definitions[0] = new PoolProperties.InterceptorDefinition(TrapException.class);

                for(int i = 0; i < interceptorValues.length; ++i) {
                    int propIndex = interceptorValues[i].indexOf(40);
                    int endIndex = interceptorValues[i].indexOf(41);
                    if (propIndex >= 0 && endIndex >= 0 && endIndex > propIndex) {
                        String name = interceptorValues[i].substring(0, propIndex).trim();
                        definitions[i + 1] = new PoolProperties.InterceptorDefinition(name);
                        String propsAsString = interceptorValues[i].substring(propIndex + 1, endIndex);
                        String[] props = propsAsString.split(",");

                        for(int j = 0; j < props.length; ++j) {
                            int pidx = props[j].indexOf(61);
                            String propName = props[j].substring(0, pidx).trim();
                            String propValue = props[j].substring(pidx + 1).trim();
                            definitions[i + 1].addProperty(new PoolProperties.InterceptorProperty(propName, propValue));
                        }
                    } else {
                        definitions[i + 1] = new PoolProperties.InterceptorDefinition(interceptorValues[i].trim());
                    }
                }

                this.interceptors = definitions;
            }
        }

        return this.interceptors;
    }

    public void setAccessToUnderlyingConnectionAllowed(boolean accessToUnderlyingConnectionAllowed) {
    }

    public void setConnectionProperties(String connectionProperties) {
        this.connectionProperties = connectionProperties;
        getProperties(connectionProperties, this.getDbProperties());
    }

    public void setDbProperties(Properties dbProperties) {
        this.dbProperties = dbProperties;
    }

    public void setDefaultAutoCommit(Boolean defaultAutoCommit) {
        this.defaultAutoCommit = defaultAutoCommit;
    }

    public void setDefaultCatalog(String defaultCatalog) {
        this.defaultCatalog = defaultCatalog;
    }

    public void setDefaultReadOnly(Boolean defaultReadOnly) {
        this.defaultReadOnly = defaultReadOnly;
    }

    public void setDefaultTransactionIsolation(int defaultTransactionIsolation) {
        this.defaultTransactionIsolation = defaultTransactionIsolation;
    }

    public void setDriverClassName(String driverClassName) {
        this.driverClassName = driverClassName;
    }

    public void setInitialSize(int initialSize) {
        this.initialSize = initialSize;
    }

    public void setLogAbandoned(boolean logAbandoned) {
        this.logAbandoned = logAbandoned;
    }

    public void setMaxActive(int maxActive) {
        this.maxActive = maxActive;
    }

    public void setMaxIdle(int maxIdle) {
        this.maxIdle = maxIdle;
    }

    public void setMaxWait(int maxWait) {
        this.maxWait = maxWait;
    }

    public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
    }

    public void setMinIdle(int minIdle) {
        this.minIdle = minIdle;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
        this.numTestsPerEvictionRun = numTestsPerEvictionRun;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setRemoveAbandoned(boolean removeAbandoned) {
        this.removeAbandoned = removeAbandoned;
    }

    public void setRemoveAbandonedTimeout(int removeAbandonedTimeout) {
        this.removeAbandonedTimeout = removeAbandonedTimeout;
    }

    public void setTestOnBorrow(boolean testOnBorrow) {
        this.testOnBorrow = testOnBorrow;
    }

    public void setTestWhileIdle(boolean testWhileIdle) {
        this.testWhileIdle = testWhileIdle;
    }

    public void setTestOnReturn(boolean testOnReturn) {
        this.testOnReturn = testOnReturn;
    }

    public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setValidationInterval(long validationInterval) {
        this.validationInterval = validationInterval;
    }

    public void setValidationQuery(String validationQuery) {
        this.validationQuery = validationQuery;
    }

    public void setValidatorClassName(String className) {
        this.validatorClassName = className;
        this.validator = null;
        if (className != null) {
            try {
                Class<Validator> validatorClass = ClassLoaderUtil.loadClass(className, new ClassLoader[]{PoolProperties.class.getClassLoader(), Thread.currentThread().getContextClassLoader()});
                this.validator = (Validator)validatorClass.newInstance();
            } catch (ClassNotFoundException var3) {
                log.warn("The class " + className + " cannot be found.", var3);
            } catch (ClassCastException var4) {
                log.warn("The class " + className + " does not implement the Validator interface.", var4);
            } catch (InstantiationException var5) {
                log.warn("An object of class " + className + " cannot be instantiated. Make sure that " + "it includes an implicit or explicit no-arg constructor.", var5);
            } catch (IllegalAccessException var6) {
                log.warn("The class " + className + " or its no-arg constructor are inaccessible.", var6);
            }

        }
    }

    public void setInitSQL(String initSQL) {
        this.initSQL = initSQL != null && initSQL.trim().length() > 0 ? initSQL : null;
    }

    public void setTestOnConnect(boolean testOnConnect) {
        this.testOnConnect = testOnConnect;
    }

    public void setJdbcInterceptors(String jdbcInterceptors) {
        this.jdbcInterceptors = jdbcInterceptors;
        this.interceptors = null;
    }

    public String toString() {
        StringBuilder buf = new StringBuilder("ConnectionPool[");

        try {
            String[] fields = DataSourceFactory.ALL_PROPERTIES;
            String[] arr$ = fields;
            int len$ = fields.length;

            label40:
            for(int i$ = 0; i$ < len$; ++i$) {
                String field = arr$[i$];
                String[] prefix = new String[]{"get", "is"};
                int j = 0;

                Method m;
                while(true) {
                    if (j >= prefix.length) {
                        continue label40;
                    }

                    String name = prefix[j] + field.substring(0, 1).toUpperCase(Locale.ENGLISH) + field.substring(1);
                    m = null;

                    try {
                        m = this.getClass().getMethod(name);
                        break;
                    } catch (NoSuchMethodException var12) {
                        ++j;
                    }
                }

                buf.append(field);
                buf.append("=");
                if ("password".equals(field)) {
                    buf.append("********");
                } else {
                    buf.append(m.invoke(this));
                }

                buf.append("; ");
            }
        } catch (Exception var13) {
            log.debug("toString() call failed", var13);
        }

        return buf.toString();
    }

    public static int getPoolCounter() {
        return poolCounter.get();
    }

    public boolean isJmxEnabled() {
        return this.jmxEnabled;
    }

    public void setJmxEnabled(boolean jmxEnabled) {
        this.jmxEnabled = jmxEnabled;
    }

    public Boolean getDefaultAutoCommit() {
        return this.defaultAutoCommit;
    }

    public Boolean getDefaultReadOnly() {
        return this.defaultReadOnly;
    }

    public int getSuspectTimeout() {
        return this.suspectTimeout;
    }

    public void setSuspectTimeout(int seconds) {
        this.suspectTimeout = seconds;
    }

    public boolean isPoolSweeperEnabled() {
        boolean timer = this.getTimeBetweenEvictionRunsMillis() > 0;
        boolean result = timer && this.isRemoveAbandoned() && this.getRemoveAbandonedTimeout() > 0;
        result = result || timer && this.getSuspectTimeout() > 0;
        result = result || timer && this.isTestWhileIdle() && this.getValidationQuery() != null;
        result = result || timer && this.getMinEvictableIdleTimeMillis() > 0;
        return result;
    }

    public boolean isUseEquals() {
        return this.useEquals;
    }

    public void setUseEquals(boolean useEquals) {
        this.useEquals = useEquals;
    }

    public long getMaxAge() {
        return this.maxAge;
    }

    public void setMaxAge(long maxAge) {
        this.maxAge = maxAge;
    }

    public boolean getUseLock() {
        return this.useLock;
    }

    public void setUseLock(boolean useLock) {
        this.useLock = useLock;
    }

    public void setDataSource(Object ds) {
        if (ds instanceof DataSourceProxy) {
            throw new IllegalArgumentException("Layered pools are not allowed.");
        } else {
            this.dataSource = ds;
        }
    }

    public Object getDataSource() {
        return this.dataSource;
    }

    public void setDataSourceJNDI(String jndiDS) {
        this.dataSourceJNDI = jndiDS;
    }

    public String getDataSourceJNDI() {
        return this.dataSourceJNDI;
    }

    public static Properties getProperties(String propText, Properties props) {
        if (props == null) {
            props = new Properties();
        }

        if (propText != null) {
            try {
                props.load(new ByteArrayInputStream(propText.replace(';', '\n').getBytes()));
            } catch (IOException var3) {
                throw new RuntimeException(var3);
            }
        }

        return props;
    }

    public boolean isAlternateUsernameAllowed() {
        return this.alternateUsernameAllowed;
    }

    public void setAlternateUsernameAllowed(boolean alternateUsernameAllowed) {
        this.alternateUsernameAllowed = alternateUsernameAllowed;
    }

    public void setCommitOnReturn(boolean commitOnReturn) {
        this.commitOnReturn = commitOnReturn;
    }

    public boolean getCommitOnReturn() {
        return this.commitOnReturn;
    }

    public void setRollbackOnReturn(boolean rollbackOnReturn) {
        this.rollbackOnReturn = rollbackOnReturn;
    }

    public boolean getRollbackOnReturn() {
        return this.rollbackOnReturn;
    }

    public void setUseDisposableConnectionFacade(boolean useDisposableConnectionFacade) {
        this.useDisposableConnectionFacade = useDisposableConnectionFacade;
    }

    public boolean getUseDisposableConnectionFacade() {
        return this.useDisposableConnectionFacade;
    }

    public void setLogValidationErrors(boolean logValidationErrors) {
        this.logValidationErrors = logValidationErrors;
    }

    public boolean getLogValidationErrors() {
        return this.logValidationErrors;
    }

    public boolean getPropagateInterruptState() {
        return this.propagateInterruptState;
    }

    public void setPropagateInterruptState(boolean propagateInterruptState) {
        this.propagateInterruptState = propagateInterruptState;
    }

    public boolean isIgnoreExceptionOnPreLoad() {
        return this.ignoreExceptionOnPreLoad;
    }

    public void setIgnoreExceptionOnPreLoad(boolean ignoreExceptionOnPreLoad) {
        this.ignoreExceptionOnPreLoad = ignoreExceptionOnPreLoad;
    }

    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public static class InterceptorProperty implements Serializable {
        private static final long serialVersionUID = 1L;
        String name;
        String value;

        public InterceptorProperty(String name, String value) {
            assert name != null;

            this.name = name;
            this.value = value;
        }

        public String getName() {
            return this.name;
        }

        public String getValue() {
            return this.value;
        }

        public boolean getValueAsBoolean(boolean def) {
            if (this.value == null) {
                return def;
            } else if ("true".equals(this.value)) {
                return true;
            } else {
                return "false".equals(this.value) ? false : def;
            }
        }

        public int getValueAsInt(int def) {
            if (this.value == null) {
                return def;
            } else {
                try {
                    int v = Integer.parseInt(this.value);
                    return v;
                } catch (NumberFormatException var3) {
                    return def;
                }
            }
        }

        public long getValueAsLong(long def) {
            if (this.value == null) {
                return def;
            } else {
                try {
                    return Long.parseLong(this.value);
                } catch (NumberFormatException var4) {
                    return def;
                }
            }
        }

        public byte getValueAsByte(byte def) {
            if (this.value == null) {
                return def;
            } else {
                try {
                    return Byte.parseByte(this.value);
                } catch (NumberFormatException var3) {
                    return def;
                }
            }
        }

        public short getValueAsShort(short def) {
            if (this.value == null) {
                return def;
            } else {
                try {
                    return Short.parseShort(this.value);
                } catch (NumberFormatException var3) {
                    return def;
                }
            }
        }

        public float getValueAsFloat(float def) {
            if (this.value == null) {
                return def;
            } else {
                try {
                    return Float.parseFloat(this.value);
                } catch (NumberFormatException var3) {
                    return def;
                }
            }
        }

        public double getValueAsDouble(double def) {
            if (this.value == null) {
                return def;
            } else {
                try {
                    return Double.parseDouble(this.value);
                } catch (NumberFormatException var4) {
                    return def;
                }
            }
        }

        public char getValueAschar(char def) {
            if (this.value == null) {
                return def;
            } else {
                try {
                    return this.value.charAt(0);
                } catch (StringIndexOutOfBoundsException var3) {
                    return def;
                }
            }
        }

        public int hashCode() {
            return this.name.hashCode();
        }

        public boolean equals(Object o) {
            if (o == this) {
                return true;
            } else if (o instanceof PoolProperties.InterceptorProperty) {
                PoolProperties.InterceptorProperty other = (PoolProperties.InterceptorProperty)o;
                return other.name.equals(this.name);
            } else {
                return false;
            }
        }
    }

    public static class InterceptorDefinition implements Serializable {
        private static final long serialVersionUID = 1L;
        protected String className;
        protected Map<String, PoolProperties.InterceptorProperty> properties;
        protected volatile Class<?> clazz;

        public InterceptorDefinition(String className) {
            this.properties = new HashMap();
            this.clazz = null;
            this.className = className;
        }

        public InterceptorDefinition(Class<?> cl) {
            this(cl.getName());
            this.clazz = cl;
        }

        public String getClassName() {
            return this.className;
        }

        public void addProperty(String name, String value) {
            PoolProperties.InterceptorProperty p = new PoolProperties.InterceptorProperty(name, value);
            this.addProperty(p);
        }

        public void addProperty(PoolProperties.InterceptorProperty p) {
            this.properties.put(p.getName(), p);
        }

        public Map<String, PoolProperties.InterceptorProperty> getProperties() {
            return this.properties;
        }

        public Class<? extends JdbcInterceptor> getInterceptorClass() throws ClassNotFoundException {
            if (this.clazz == null) {
                if (this.getClassName().indexOf(46) < 0) {
                    if (PoolProperties.log.isDebugEnabled()) {
                        PoolProperties.log.debug("Loading interceptor class:org.apache.tomcat.jdbc.pool.interceptor." + this.getClassName());
                    }

                    this.clazz = ClassLoaderUtil.loadClass("org.apache.tomcat.jdbc.pool.interceptor." + this.getClassName(), new ClassLoader[]{PoolProperties.class.getClassLoader(), Thread.currentThread().getContextClassLoader()});
                } else {
                    if (PoolProperties.log.isDebugEnabled()) {
                        PoolProperties.log.debug("Loading interceptor class:" + this.getClassName());
                    }

                    this.clazz = ClassLoaderUtil.loadClass(this.getClassName(), new ClassLoader[]{PoolProperties.class.getClassLoader(), Thread.currentThread().getContextClassLoader()});
                }
            }

            return this.clazz;
        }
    }
}

 

自定义参数

  如果要修改某个默认参数值,可以在application.yml中配置,如下

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/david2018_db?characterEncoding=utf8&useSSL=false
    username: root
    password: 1234
    tomcat:
      max-active: 105

spring.datasource.tomcat是前缀 max-active是参数 105是参数值,其他属性也是一样的。

 

在java中自定义参数

  在yml或properties中自定义参数有一个问题,如果参数名写错了,是不会有任何错误提示的,会继续使用吗哦任职,在java中配置可以避免这个问题,以下是java中设置maxActive参数,set其他参数也是一样。

@Bean
    public DataSource dataSource() {
        PoolProperties poolProperties = new PoolProperties();
        poolProperties.setMaxActive(105);
        return new DataSource(poolProperties);
    }

 

转载于:https://www.cnblogs.com/baidawei/p/9110232.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值