数据库程序接口——JDBC——功能第二篇——数据源之C3P0数据源
综述
C3P0由三部分内容组成。实例化对象,各配置项的含义,以及加载配置项的方式。
实例化对象的方式有三种,第一种方式直接new ComboPooledDataSource,第二种方式使用工厂类DataSources.poolDataSource方法。第三种不常见。第一种方式是最方便的方式。
C3P0的配置项主要有:
- 连接数据库的必要属性:例如jdbcUrl,user,password等。
- 连接池的大小配置。例如initialPoolSize
- 连接对象的生命周期。例如maxConnectionAge。
- 测试连接的配置,例如preferredTestQuery指定测试SQL语句。
- 重连策略的配置,例如acquireRetryAttempts指定重连次数。
- statement对象的配置,例如maxStatements指定最大Statement的总数。
- 线程配置,例如numHelperThread指定连接池拥有的线程数量。
- 事务配置,例如autoCommitOnClose指定是否在回收连接对象时自动提交事务。
- 调试模式,例如debugUnreturnedConnectionStackTraces为true时,会打印所有从连接池获取连接对象的记录。
- 监听类的设置,例如connectionCustomizerClassName指定监听类的名称,该类可以实现onAcquire,onDestory等方法。
- 日志的设置,例如com.mchange.v2.log.MLog指定日志的实现方式。常见的有log4J,commonLogging等。
配置项常见的加载方式有三种:
- 代码方式:通过实例对象调用setXX方法。
- properties文件:这种方式需要properties文件的名称必须为c3p0.properties,而且该文件必须在类加载路径下。
- xml文件:这种方式需要文件名称为c3p0-config.xml,路径由com.mchange.v2.c3p0.cfg.xml指定。
实例化
实例化ComboPooledDataSource
// 创建实例,dataSourceName指定数据源的名称
ComboPooledDataSource dataSource = new ComboPooledDataSource(dataSourceName);
// 设置数据库url
dataSource.setJdbcUrl("jdbc:oracle:thin:@localhost:1521:masteroracle");
// 设置数据库驱动类
dataSource.setDriverClass("oracle.jdbc.driver.OracleDriver");
// 设置用户名
dataSource.setUser("system");
// 设置密码
dataSource.setPassword("password");
Connection conn = dataSource.getConnection();
runSQLTest(conn);
工厂DataSources方式
// 创建unpooled的数据源
DataSource ds_unpooled = DataSources.unpooledDataSource(jdbcUrl, user, password);
// pooled数据源的参数
Map<String,String> paramMap = new HashMap<>();
DataSource pooled = DataSources.pooledDataSource(ds_unpooled,paramMap);
Connection conn = pooled.getConnection();
runSQLTest(conn);
conn.close();
DataSources.destroy(pooled);
return pooled;
配置项的含义
C3P0各配置项的前缀为c3p0。如果指定dataSourceName,前缀为c3p0.named-configs.dataSourceName。如果存在多个用户,用户可以覆盖默认的配置项,前缀为c3p0.user-overrides.user。
Java代码方式
/** -----------------------配置数据源----------------------------- **/
/**
* 配置数据源
*
* @param dataSource
* @return
* @throws PropertyVetoException
*/
public static ComboPooledDataSource configDataSource(ComboPooledDataSource dataSource)
throws PropertyVetoException {
// 连接数据库的必要属性
connDatabaseConfig(dataSource,"masterOracle");
// 连接池的相关配置
connPoolConfig(dataSource);
// 连接对象的生命周期配置
connAgeConfig(dataSource);
// 测试连接的配置
connTestConfig(dataSource);
// statement对象的配置
statementConfig(dataSource);
// 重连配置
reconnConfig(dataSource);
// 连接的监听类配置
connListenerConfig(dataSource);
// 事务的配置
tranConfig(dataSource);
// 调试模式
debugMode(dataSource);
// 线程配置
threadConfig(dataSource);
return dataSource;
}
连接必要属性
- driverClassName:驱动类的名称,包名+类名
- jdbcUrl:数据库实例的url地址,格式为jdbc:subprotocol:subname。其中subprotocol表示连接方式。
- user:用户名
- password:密码。
C3P0.properties的方式
##-------------------------------数据库连接属性-----------------------------------##
# 驱动类名称
c3p0.driverClass=oracle.jdbc.driver.OracleDriver
# 数据库实例url地址
c3p0.jdbcUrl=jdbc:oracle:thin:@localhost:1521:masteroracle
# 用户名
c3p0.user=system
# 密码
c3p0.password=password
代码方式
// 设置数据库url
dataSource.setJdbcUrl(jdbcUrl);
// 设置数据库驱动类
dataSource.setDriverClass(driverClassName);
// 设置用户名
dataSource.setUser(user);
// 设置密码
dataSource.setPassword(password);
// 输出dataSourceName,在初始化ComboPooledDataSource时,字符串参数作为数据源名称,
dataSource.getDataSourceName();
连接池大小
- initialPoolSize:连接池的初始需求量大小,实际创建的连接对象小于需求量大小。
- minPoolSize:连接池连接数量的最小值。
- maxPoolSize:连接池连接数量的最大值。
- acquireIncrement:当实际连接不够用时,调整需求量的大小,需求量的递增值。
C3P0.properties的方式
##-------------------------------连接池配置-------------------------------------##
# 连接池拥有连接对象的初始值,这种情形下只是Acquire(需求)的初始值,真正创建对象会根据Acquire来按需创建
c3p0.initialPoolSize=10
# 连接池拥有连接对象的最大值,默认值为3
c3p0.maxPoolSize=20
# 连接池拥有连接对象的最小值,默认值为3
c3p0.minPoolSize=5
# 当无空闲连接时,新创建的连接数,默认值为3
c3p0.acquireIncrement=3
代码方式
/**
* 连接池的配置 initialPoolSize:连接池的初始值 maxPoolSize:连接池的最大值 minPoolSize:连接池的最小值
*
* @param dataSource
*/
private static void connPoolConfig(ComboPooledDataSource dataSource) {
// 连接池的初始值,默认值为3
dataSource.setInitialPoolSize(10);
// 连接池的最大值,默认值为0
dataSource.setMaxPoolSize(20);
// 连接池的最小值,最小值为3
dataSource.setMinPoolSize(1);
// 连接池的递增值,默认值为3
dataSource.setAcquireIncrement(5);
}
连接生命周期
- maxIdleTime:空闲连接对象的超时时间,当连接对象处于空闲状态的时间超过此时间,连接池销毁该连接对象。
- maxConnectionAge:连接对象的最大生命值,从创建连接对象开始计算。当超出此时间,销毁连接对象。与maxIdleTime的区别在于maxIdleTime只适用于空闲连接对象,而且是从空闲状态开始计算时间。
- maxIdleTimeExcessConnections:当连接池负载较低时,空闲连接对象的超时时间,设置此项可以在负载较低时,快速的释放链接。
- unreturnedConnectionTimeout:连接对象的最大使用时间。从连接池中获取连接对象开始计算,如果超出此时间,该连接对象还没有被连接池回收,那么连接池创建新连接对象替换旧连接对象。
C3P0.proerties的方式
##-------------------------------连接池中连接对象的生命周期--------------------------##
# 连接对象的最大生存时间,起始时间从连接池从数据库中创建连接对象开始计算。0表示永远不销毁
c3p0.maxConnectionAge=0
# 空闲连接对象的超时时间,起始时间从连接对象状态变为空闲时起计算。
c3p0.maxIdleTime=1800
# 当连接池不处于满载状态时,空闲连接对象的最大生存时间,设置此值,可以快速的减少连接池的大小
c3p0.maxIdleTimeExcessConnections=60
# 连接对象回收的超时时间,当连接池无法在一定时间内回收连接对象时,销毁旧对象,重新创建新对象
c3p0.unreturnedConnectionTimeout=600
代码方式
/**
* 连接池生命周期配置,连接池首先从数据库中获取连接,用户请求时从连接池中获取连接。默认值为0,表示永不过期。 maxConnectionAge:
* 连接对象生命的最大值,超过此时间,连接池会销毁连接对象,连接池变小。单位为秒,建议设置1800或更多 maxIdleTime:
* 空闲连接在连接池中的超时时间,超过此时间,连接池将会销毁连接对象。单位为秒,建议设置1800或更多
* maxIdleTimeExcessConnections:当连接池不处于过载状态时,空闲连接对象生命的最大值。
* unreturnedConnectionTimeout:当连接对象在一定时间内无法回收,则创建新连接对象,销毁旧连接对象
*
* @param dataSource
*/
private static void connAgeConfig(ComboPooledDataSource dataSource) {
// 连接对象生命的最大值,它指绝对时间。从创建开始时计算,默认值为0
dataSource.setMaxConnectionAge(10 * 60 * 60);
// 空闲连接的超时时间,从连接池变为空闲状态开始计算
dataSource.setMaxIdleTime(1800);
// 空闲连接对象生命的最大值
dataSource.setMaxIdleTimeExcessConnections(60);
// 连接对象的最大使用时间,设置为2小时
dataSource.setUnreturnedConnectionTimeout(2 * 60 * 60);
}
测试连接
- automaticTestTable:测试连接使用的数据库表
- connectionTesterClassName:测试连接使用的类名称
- idleConnectionTestPeriod:测试连接的时间间隔,在此间隔内不执行连接测试
- preferredTestQuery:SELECT 1。如果支持JDBC 4,会使用Connection.isAlive方法不设置此值。
- testConnectionOnCheckin:是否在连接池中回收连接对象时进行连接测试,
- testConnectionOnCheckOut:从连接池中取出连接对象时进行连接测试。
C3P0.properties的方式
##-------------------------------测试连接配置项----------------------------------##
# 从连接池中获取连接对象时进行连接测试
c3p0.testConnectionOnCheckout=true
# 从连接池回收对象时进行连接测试
c3p0.testConnectionOnCheckin=true
# 连接测试的间隔,在这一段时间内不进行连接测试
c3p0.idleConnectionTestPeriod=60
# 连接测试时使用的类,设置此值时忽略preferredTestQuery,automaticTestTable等属性值
#c3p0.connectionTesterClassName=com.rain.Tester.ConnectionTesterSample
# 测试的SQL语句
c3p0.preferredTestQuery=select 1
# 连接测试时使用的数据库表
c3p0.automaticTestTable=test
代码方式
/**
* 连接测试配置。 automaticTestTable:测试连接时使用的数据库表 ,默认值为null。connectionTesterClassName:测试连接时使用的类名称
* idleConnectionTestPeriod:测试连接间隔时间。在此段时间内不进行连接测试。 preferredTestQuery:连接测试使用的SQL语句。默认语句为select
* 1 from dual。 testConnectionOnCheckin:从连接池回收连接对象时测试连接。默认值为false
* testConnectionOnCheckOut:从连接池取出连接对象时测试连接。默认值为false。
* forceSynchronousCheckins:连接池回收连接对象时是同步,还是异步,默认是异步。默认值为false
*
* @param dataSource
* @throws PropertyVetoException
*/
private static void connTestConfig(ComboPooledDataSource dataSource)
throws PropertyVetoException {
// 连接测试使用的数据库表,默认值为Null
dataSource.setAutomaticTestTable("dual");
// 连接测试使用的SQL语句,默认使用Connection对象的isAlive方法,所以一般不设置此值,默认值为null
dataSource.setPreferredTestQuery("select 1");
// 从连接池取出连接时测试连接,默认值为false
dataSource.setTestConnectionOnCheckout(true);
// 从连接池回收连接时测试连接,默认值为false。
dataSource.setTestConnectionOnCheckin(true);
// 测试连接的间隔时间,默认值为0
dataSource.setIdleConnectionTestPeriod(60);
// 测试连接使用的类名称
dataSource.setConnectionTesterClassName("com.rain.Tester.ConnectionTesterSample");
}
重连策略
- acquireRetryAttempts:连接失败后,重连次数
- acquireRetryDelay:第一次重连与第二次重连的时间间隔。单位为毫秒
- checkTimeOut:等待连接的超时时间,超出此时间后不在进行重连。
- breakAfterAcquireFailure:当连接失败后,是否销毁数据源对象,true表示是,false表示否。
C3P0.properties
##-------------------------------重新连接---------------------------------------##
# 重新连接的次数
c3p0.acquireRetryAttempts=5
# 重新连接的时间间隔,单位为毫秒
c3p0.acquireRetryDelay=3000
# 等待连接响应的超时时间
c3p0.checkoutTimeout=120
# 当连接失败时,是否销毁数据源对象,true表示是,false表示否
c3p0.breakAfterAcquireFailure=true
代码方式
/**
* 当连接失败后,重新连接的配置。 acquireRetryAttempts:重连的次数。 acquireRetryDelay:重连的时间间隔。单位为毫秒
* breakAfterAcquireFailure:重连失败后,如果此值设置为false,数据源对象不会销毁,设置为false。数据源被销毁。
* checkoutTimeout:等待连接响应的时间。
*/
private static void reconnConfig(ComboPooledDataSource dataSource) {
// 设置重连次数为3,默认值为30
dataSource.setAcquireRetryAttempts(3);
// 设置重连的时间间隔为2秒,默认值为1000
dataSource.setAcquireRetryDelay(2000);
// 等待连接响应的超时时间。默认值为0表示永远不超时
dataSource.setCheckoutTimeout(4);
// 重连失败后,销毁数据源。默认值为false
dataSource.setBreakAfterAcquireFailure(true);
}
Statement配置
- maxStatements:连接池缓存PreparedStatement对象的总数
- maxStatementsPerConnection:每个连接缓存PreparedStatement的最大值。
- statementCacheNumDeferredCloseThreads:当Connection关闭时,有可能会产生Statement对象没有关闭的情形,此时需要额外线程确保Statement对象在Connection关闭时正在关闭。一般配置为0或1
C3P0.properties的方式
##-------------------------------statement对象相关配置---------------------------##
# c3p0拥有的PreparedStatement对象的总数
c3p0.maxStatements=100
# 每个连接拥有PreparedStament对象的数量
c3p0.maxStatementsPerConnection=10
# 当Connection对象关闭时,启动额外线程确保statement对象关闭
# This parameter should only be set if you observe that attempts by c3p0 to close() cached #statements freeze
statementCacheNumDeferredCloseThreads=1
代码方式
/**
* 连接池中PreparedStatement对象的配置 PreparedStatement对象的配置。 maxStatements:连接池拥有PreparedStatement对象的总数。
* maxStatementsPerConnections:每个连接拥有PreparedStatement对象的数目。
*
* @param dataSource
*/
private static void statementConfig(ComboPooledDataSource dataSource) {
// 设置PreparedStatement对象的总数,默认值为0,表示关闭
dataSource.setMaxStatements(100);
// 设置每个连接拥有Statement对象的数目,默认值为0,表示关闭。
dataSource.setMaxStatementsPerConnection(15);
}
线程配置
- numHelperThreads:连接池拥有的线程数量。
- maxAdministrativeTaskTime:线程执行任务的超时时间,当超出此时间时,会销毁该线程,重新创建新线程。
- forceSynchronousCheckins:连接池回收连接对象时默认是同步方式执行连接测试,此值设置为true时,连接测试与回收连接对象是异步执行的。
C3P0.properties的方式
##-------------------------------线程池----------------------------------------##
# 连接池拥有的线程数量
c3p0.numHelperThreads=5
# 线程执行的最大时间
c3p0.maxAdministrativeTaskTime=600
# 启动独立的线程来在连接被连接池回收阶段进行测试
forceSynchronousCheckins=true
代码方式
/**
* 连接池的线程设置 numHelperThread:连接池拥有的线程数量 maxAdministrativeTaskTime:线程执行的超时时间。
*
* @param dataSource
*/
private static void threadConfig(ComboPooledDataSource dataSource) {
// 设置线程数量为10,默认值为3
dataSource.setNumHelperThreads(10);
// 设置线程的超时时间,默认值为0,设置为5分钟
dataSource.setMaxAdministrativeTaskTime(5 * 60);
}
事务配置
- autoCommitOnClose:回收连接对象时,是否自动提交事务。默认不配置,通过其他方式管理事务,例如Spring事务
- forceIgnoreUnresolvedTransactions:回收连接对象时,是否强制回滚或者提交事务,默认不配置。
C3P0.properties的方式
##-------------------------------事务-----------------------------------------##
# 交给Spring去管理事务,默认不配置这些项
# 连接关闭时,是否自动提交事务
c3p0.autoCommitOnClose=false
# 连接回收时,是否强制提交或者回滚当前连接拥有的事务,默认不配置。
c3p0.forceIgnoreUnresolvedTransactions=false
代码方式
/**
* 连接对象的事务配置 autoCommitOnClose:是否自动提交事务,true为是,false为否,默认为否 forceIgnoreUnresolvedTransactions
* 回收连接时,是否强制回滚或提交事务,默认为false。一般不设置此值, 例如由Spring来管理事务
*
* @param dataSource
*/
private static void tranConfig(ComboPooledDataSource dataSource) {
// 关闭自动提交事务,默认值为false
dataSource.setAutoCommitOnClose(false);
// 回收连接时,是否强制回滚或提交事务,设置为false。
dataSource.setForceIgnoreUnresolvedTransactions(false); }
调试模式
- debugUnreturnedConnectionStackTraces:打印从连接池获取连接对象的所有信息。
C3P0.properties的方式
##-------------------------------调试模式--------------------------------------##
# 当从连接池获取连接对象时,打印所有信息。
c3p0.debugUnreturnedConnectionStackTraces=true
代码方式
/**
* 调试模式的设置 debugUnreturnedConnectionStackTraces:从连接池获取连接对象时,打印所有信息 *
* @param dataSource
*/
private static void debugMode(ComboPooledDataSource dataSource) {
// 从连接池获取连接对象时,打印所有信息
dataSource.setDebugUnreturnedConnectionStackTraces(true);
}
监听类
connectionCustomizerClassName:监听类的名称,监听类继承自AbstractConnectionCustomizer,监听类有四个方法
- onAcquire在数据库中创建连接对象时触发。
- onDestory在连接池中销毁连接对象时触发。
- onCheckOut从连接池获取连接对象时触发
- onCheckIn 从连接池回收连接对象时触发。
C3P0.properties的方式
##-------------------------------监听类---------------------------------------##
c3p0.connectionCustomizerClassName=com.rain.Tester.ConnCustomrizerSample
代码方式
/**
* 设置连接对象的监听类,该类有四个方法 onAcquire:表示当连接池从数据库中获得连接时 onDestory:表示当连接池销毁连接对象时 onCheckOut:从连接池中获取连接对象时
* onCheckIn:连接池回收连接对象时。
*/
private static void connListenerConfig(ComboPooledDataSource dataSource) {
// 设置连接对象的监听类
dataSource.setConnectionCustomizerClassName("com.rain.Tester.ConnCustomrizerSample");
}
日志配置
- com.mchange.v2.log.MLog:日志的实现方式
- com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL:日志的级别。可选值为OFF,SERVER,WARNING,INFO,FINE,FINER,FINEST,ALL
- com.mchange.v2.log.NameTransformer:日志按每个数据源类输出,还是按包。com.mchange.v2.log.PackageNames表示按包,默认的方式按类的方式
- com.mchange.v2.log.jdk14logging.suppressStackWalk:是否显示哪些类,哪些方法产生的日志,true表示不显示,false表示显示,默认值为true。
C3P0.properties的方式
##-------------------------------日志配置--------------------------------------##
# 日志的实现方式
com.mchange.v2.log.MLog=log4j
# 日志的级别,OFF,SERVER,WARNING,INFO,FINE,FINER,FINEST,ALL
com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL=All
# 日志按包输出
com.mchange.v2.log.NameTransformer=com.mchange.v2.log.PackageNames
# determine the class and method from which a log message was generated,当为true时,不打印这些日志信息
com.mchange.v2.log.jdk14logging.suppressStackWalk=true
加载配置项的方式
代码方式:通过new实例化dataSource,调用setXX方法。
package com.rain.core; import java.beans.PropertyVetoException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.mchange.v2.c3p0.DataSources; public class C3P0DataSourceSample {
private static final String masterOraclejdbcUrl =
"jdbc:oracle:thin:@localhost:1521:masteroracle";
private static final String orclJdbcUrl = "jdbc:oracle:thin:@localhost:1521:orcl";
private static final String driverClassName = "oracle.jdbc.driver.OracleDriver";
private static final String user = "system";
private static final String password = "password"; public static void main(String[] args) throws Exception {
// 创建数据源对象
ComboPooledDataSource dataSource = createByInitInstance();
// 配置数据源
// configDataSource(dataSource);
// 打印数据源信息
printDataSourceInfo(dataSource);
// 运行测试用例
runSQLTest(dataSource);
} /** -------------------------创建数据源------------------------- **/
/**
* 通过实例化的方式来获取数据源
*
* @return
* @throws PropertyVetoException
* @throws SQLException
*/
public static ComboPooledDataSource createByInitInstance()
throws PropertyVetoException, SQLException {
// 创建实例
ComboPooledDataSource dataSource = new ComboPooledDataSource("");
// 连接时配置
// dataSource = connDatabaseConfig(dataSource, "masterOracle");
return dataSource;
} /**
* 创建多个数据源,每个数据源通过名字区分
*
* @return
* @throws IOException
* @throws SQLException
* @throws PropertyVetoException
*/
public static ComboPooledDataSource createMultiDataSource()
throws IOException, SQLException, PropertyVetoException {
// 创建数据库实例masterOracle
ComboPooledDataSource masterOracleDataSource = new ComboPooledDataSource("masterOracle");
// 连接时配置masterOracle数据源
masterOracleDataSource = connDatabaseConfig(masterOracleDataSource, "masterOracle");
// 创建数据库实例orcl
ComboPooledDataSource orclDataSource = new ComboPooledDataSource("orcl");
// 连接时配置orcl数据源
orclDataSource = connDatabaseConfig(orclDataSource, "orcl");
// 执行测试语句
runSQLTest(masterOracleDataSource);
// 执行测试语句
runSQLTest(orclDataSource);
return masterOracleDataSource;
} /**
* 通过DataSources工厂方式建立连接
*
* @return
* @throws SQLException
*/
public static DataSource createByFactory() throws SQLException {
// 创建unpooled的数据源
DataSource ds_unpooled =
DataSources.unpooledDataSource(masterOraclejdbcUrl, user, password);
// pooled数据源的参数
Map<String, String> paramMap = new HashMap<>();
ComboPooledDataSource pooled =
(ComboPooledDataSource) DataSources.pooledDataSource(ds_unpooled, paramMap);
runSQLTest(pooled);
pooled.close();
DataSources.destroy(pooled);
return pooled;
} /** -----------------------配置数据源----------------------------- **/
/**
* 配置数据源
*
* @param dataSource
* @return
* @throws PropertyVetoException
*/
public static ComboPooledDataSource configDataSource(ComboPooledDataSource dataSource)
throws PropertyVetoException {
// 连接数据库的必要属性
connDatabaseConfig(dataSource,"masterOracle");
// 连接池的相关配置
connPoolConfig(dataSource);
// 连接对象的生命周期配置
connAgeConfig(dataSource);
// 测试连接的配置
connTestConfig(dataSource);
// statement对象的配置
statementConfig(dataSource);
// 重连配置
reconnConfig(dataSource);
// 连接的监听类配置
connListenerConfig(dataSource);
// 事务的配置
tranConfig(dataSource);
// 调试模式
debugMode(dataSource);
// 线程配置
threadConfig(dataSource);
return dataSource;
} /**
* 连接池的配置 initialPoolSize:连接池的初始值 maxPoolSize:连接池的最大值 minPoolSize:连接池的最小值
*
* @param dataSource
*/
private static void connPoolConfig(ComboPooledDataSource dataSource) {
// 连接池的初始值,默认值为3
dataSource.setInitialPoolSize(10);
// 连接池的最大值,默认值为0
dataSource.setMaxPoolSize(20);
// 连接池的最小值,最小值为3
dataSource.setMinPoolSize(1);
// 连接池的递增值,默认值为3
dataSource.setAcquireIncrement(5);
} /**
* 连接池生命周期配置,连接池首先从数据库中获取连接,用户请求时从连接池中获取连接。默认值为0,表示永不过期。 maxConnectionAge:
* 连接对象生命的最大值,超过此时间,连接池会销毁连接对象,连接池变小。单位为秒,建议设置1800或更多 maxIdleTime:
* 空闲连接在连接池中的超时时间,超过此时间,连接池将会销毁连接对象。单位为秒,建议设置1800或更多
* maxIdleTimeExcessConnections:当连接池不处于过载状态时,空闲连接对象生命的最大值。
* unreturnedConnectionTimeout:当连接对象在一定时间内无法回收,则创建新连接对象,销毁旧连接对象
*
* @param dataSource
*/
private static void connAgeConfig(ComboPooledDataSource dataSource) {
// 连接对象生命的最大值,它指绝对时间。从创建开始时计算,默认值为0
dataSource.setMaxConnectionAge(10 * 60 * 60);
// 空闲连接的超时时间,从连接池变为空闲状态开始计算
dataSource.setMaxIdleTime(1800);
// 空闲连接对象生命的最大值
dataSource.setMaxIdleTimeExcessConnections(60);
// 连接对象的最大使用时间,设置为2小时
dataSource.setUnreturnedConnectionTimeout(2 * 60 * 60);
} /**
* 连接测试配置。 automaticTestTable:测试连接时使用的数据库表 ,默认值为null。connectionTesterClassName:测试连接时使用的类名称
* idleConnectionTestPeriod:测试连接间隔时间。在此段时间内不进行连接测试。 preferredTestQuery:连接测试使用的SQL语句。默认语句为select
* 1 from dual。 testConnectionOnCheckin:从连接池回收连接对象时测试连接。默认值为false
* testConnectionOnCheckOut:从连接池取出连接对象时测试连接。默认值为false。
* forceSynchronousCheckins:连接池回收连接对象时是同步,还是异步,默认是异步。默认值为false
*
* @param dataSource
* @throws PropertyVetoException
*/
private static void connTestConfig(ComboPooledDataSource dataSource)
throws PropertyVetoException {
// 连接测试使用的数据库表,默认值为Null
dataSource.setAutomaticTestTable("dual");
// 连接测试使用的SQL语句,默认使用Connection对象的isAlive方法,所以一般不设置此值,默认值为null
dataSource.setPreferredTestQuery("select 1");
// 从连接池取出连接时测试连接,默认值为false
dataSource.setTestConnectionOnCheckout(true);
// 从连接池回收连接时测试连接,默认值为false。
dataSource.setTestConnectionOnCheckin(true);
// 测试连接的间隔时间,默认值为0
dataSource.setIdleConnectionTestPeriod(60);
// 测试连接使用的类名称
dataSource.setConnectionTesterClassName("com.rain.Tester.ConnectionTesterSample");
} /**
* 连接池中PreparedStatement对象的配置 PreparedStatement对象的配置。 maxStatements:连接池拥有PreparedStatement对象的总数。
* maxStatementsPerConnections:每个连接拥有PreparedStatement对象的数目。
*
* @param dataSource
*/
private static void statementConfig(ComboPooledDataSource dataSource) {
// 设置PreparedStatement对象的总数,默认值为0,表示关闭
dataSource.setMaxStatements(100);
// 设置每个连接拥有Statement对象的数目,默认值为0,表示关闭。
dataSource.setMaxStatementsPerConnection(15);
} /**
* 当连接失败后,重新连接的配置。 acquireRetryAttempts:重连的次数。 acquireRetryDelay:重连的时间间隔。单位为毫秒
* breakAfterAcquireFailure:重连失败后,如果此值设置为false,数据源对象不会销毁,设置为false。数据源被销毁。
* checkoutTimeout:等待连接响应的时间。
*/
private static void reconnConfig(ComboPooledDataSource dataSource) {
// 设置重连次数为3,默认值为30
dataSource.setAcquireRetryAttempts(3);
// 设置重连的时间间隔为2秒,默认值为1000
dataSource.setAcquireRetryDelay(2000);
// 等待连接响应的超时时间。默认值为0表示永远不超时
dataSource.setCheckoutTimeout(4);
// 重连失败后,销毁数据源。默认值为false
dataSource.setBreakAfterAcquireFailure(true);
} /**
* 设置连接对象的监听类,该类有四个方法 onAcquire:表示当连接池从数据库中获得连接时 onDestory:表示当连接池销毁连接对象时 onCheckOut:从连接池中获取连接对象时
* onCheckIn:连接池回收连接对象时。
*/
private static void connListenerConfig(ComboPooledDataSource dataSource) {
// 设置连接对象的监听类
dataSource.setConnectionCustomizerClassName("com.rain.Tester.ConnCustomrizerSample");
} /**
* 连接对象的事务配置 autoCommitOnClose:是否自动提交事务,true为是,false为否,默认为否 forceIgnoreUnresolvedTransactions
* 回收连接时,是否强制回滚或提交事务,默认为false。一般不设置此值, 例如由Spring来管理事务
*
* @param dataSource
*/
private static void tranConfig(ComboPooledDataSource dataSource) {
// 关闭自动提交事务,默认值为false
dataSource.setAutoCommitOnClose(false);
// 回收连接时,是否强制回滚或提交事务,设置为false。
dataSource.setForceIgnoreUnresolvedTransactions(false); } /**
* 调试模式的设置 debugUnreturnedConnectionStackTraces:从连接池获取连接对象时,打印所有信息 *
* @param dataSource
*/
private static void debugMode(ComboPooledDataSource dataSource) {
// 从连接池获取连接对象时,打印所有信息
dataSource.setDebugUnreturnedConnectionStackTraces(true);
} /**
* 类加载器的设置。 contextClassLoaderSource:可选值为caller,none,library。默认值为caller,一般不设置此值。
* privilegeSpawnedThreads:
*
* @param dataSource
*/
private static void classLoaderConfig(ComboPooledDataSource dataSource) {
// dataSource.getContext
} /**
* 连接池的线程设置 numHelperThread:连接池拥有的线程数量 maxAdministrativeTaskTime:线程执行的超时时间。
*
* @param dataSource
*/
private static void threadConfig(ComboPooledDataSource dataSource) {
// 设置线程数量为10,默认值为3
dataSource.setNumHelperThreads(10);
// 设置线程的超时时间,默认值为0,设置为5分钟
dataSource.setMaxAdministrativeTaskTime(5 * 60);
} /**
* 连接池的日志配置,mchange-log.properties提供默认配置
*
* @param dataSource
*/
private static void logConfig(ComboPooledDataSource dataSource) {
// 设置com.mchange.v2.log.MLog
// 设置com.mchange.v2.log.jdk14logging.suppressStackWalk
// 设置com.mchange.v2.log.NameTransformer
// 设置com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL,可选值为
// OFF,SERVER,WARNING,INFO,FINE,FINER,FINEST,ALL
} /**
* 其他配置项
*
* @param dataSource
*/
private static void otherConfig(ComboPooledDataSource dataSource) {
// 设置factoryClassLocation
// 设置forceSynchronousCheckins
// statementCacheNumDeferredCloseThreads
// com.mchange.v2.c3p0.cfg.xml
// com.mchange.v2.c3p0.impl.DefaultConnectionTester.querylessTestRunner
// com.mchange.v2.c3p0.impl.DefaultConnectionTester.isValidTimeout
} /**
* 打印连接池的属性
*
* @param dataSource
*/
private static void printDataSourceInfo(ComboPooledDataSource dataSource) {
// 连接时的必要属性
System.out.println("——————————————————————————————————————————————————————————————————————");
System.out.println("||-------------------连接数据库的必要属性-----------------||");
System.out.println("数据源的驱动类名称:" + dataSource.getDriverClass());
System.out.println("数据源的连接URL:" + dataSource.getJdbcUrl());
System.out.println("数据源的连接用户名:" + dataSource.getUser());
System.out.println("数据源的连接密码:" + dataSource.getPassword());
System.out.println("数据源的Id:" + dataSource.getIdentityToken());
// 连接池的基本配置
System.out.println("——————————————————————————————————————————————————————————————————————");
System.out.println("||-------------------连接池大小配置---------------------||");
System.out.println("连接池的初始需求量大小:" + dataSource.getInitialPoolSize());
System.out.println("连接池的最大值:" + dataSource.getMaxPoolSize());
System.out.println("连接池的最小值:" + dataSource.getMinPoolSize());
System.out.println("当无可用连接时,连接池需求量的递增值:" + dataSource.getAcquireIncrement());
// 连接对象的生命周期配置
System.out.println("——————————————————————————————————————————————————————————————————————");
System.out.println("||-------------------连接对象的生命周期--------------------||");
System.out.println("连接对象的最大生存时间,从创建连接对象时开始计时:" + dataSource.getMaxConnectionAge());
System.out.println("空闲连接对象的超时时间,从连接对象变为空闲状态开始计时:" + dataSource.getMaxIdleTime());
System.out.println("当连接池负载较低时,空闲连接对象的最大生命年龄:" + dataSource.getMaxIdleTimeExcessConnections());
System.out.println("从连接池获取连接对象之后,连接对象的超时时间:"+dataSource.getUnreturnedConnectionTimeout());
// 测试连接的配置
System.out.println("——————————————————————————————————————————————————————————————————————");
System.out.println("||-------------------测试连接的配置----------------------||");
System.out.println("测试连接使用的数据库表:" + dataSource.getAutomaticTestTable());
System.out.println("测试连接使用的SQL语句:" + dataSource.getPreferredTestQuery());
System.out.println("从连接池中获取连接时是否进行连接测试:"
+ convertBooleanToStr(dataSource.isTestConnectionOnCheckout()));
System.out.println("从连接池中回收连接时是否进行连接测试:"
+ convertBooleanToStr(dataSource.isTestConnectionOnCheckin()));
System.out.println("测试连接的时间间隔:" + dataSource.getIdleConnectionTestPeriod() + "秒");
System.out.println("测试连接使用的类名称:" + dataSource.getConnectionTesterClassName());
// 重连配置
System.out.println("——————————————————————————————————————————————————————————————————————");
System.out.println("||-------------------重连配置-----------------||");
System.out.println("连接失败后,尝试重连的次数:" + dataSource.getAcquireRetryAttempts());
System.out.println("重连的时间间隔:" + dataSource.getAcquireRetryDelay()+"毫秒");
System.out.println("用户等待连接的超时时间:" + dataSource.getCheckoutTimeout());
System.out.println(
"重连失败后,是否销毁数据源:" + convertBooleanToStr(dataSource.isBreakAfterAcquireFailure()));
// 缓存preparedStatement对象的配置
System.out.println("——————————————————————————————————————————————————————————————————————");
System.out.println("||-------------------缓存preparedStatement对象的配置-----------------||");
System.out.println("连接池拥有PreparedStatement对象的总数:" + dataSource.getMaxStatements());
System.out.println(
"每个连接拥有PreparedStatement对象的数量:" + dataSource.getMaxStatementsPerConnection());
// 线程设置
System.out.println("——————————————————————————————————————————————————————————————————————");
System.out.println("||-------------------线程设置--------------------------||");
System.out.println("连接池拥有的线程数量:" + dataSource.getNumHelperThreads());
System.out.println(
"线程执行的超时时间:" + dataSource.getMaxAdministrativeTaskTime());
// 设置事务
System.out.println("——————————————————————————————————————————————————————————————————————");
System.out.println("||-------------------事务配置---------------------------||");
System.out
.println("连接对象的事务是否自动提交:" + convertBooleanToStr(dataSource.isAutoCommitOnClose()));
System.out.println("回收连接对象时,是否强制提交和回滚事务:"
+ convertBooleanToStr(dataSource.isForceIgnoreUnresolvedTransactions()));
// 设置调试模式
System.out.println("——————————————————————————————————————————————————————————————————————");
System.out.println("||-------------------调试模式配置-----------------------||");
System.out.println("从连接池获取连接对象时,是否打印所有信息:"
+ convertBooleanToStr(dataSource.isDebugUnreturnedConnectionStackTraces()));
// 监听类
System.out.println("——————————————————————————————————————————————————————————————————————");
System.out.println("||-------------------监听类名称-----------------||");
System.out.println("连接对象的监听类名称:" + dataSource.getConnectionCustomizerClassName()); } /**
* 运行测试用例,执行select 1 from dual 语句。
*
* @param dataSource
* @throws SQLException
*/
private static void runSQLTest(ComboPooledDataSource dataSource) throws SQLException {
// 建立连接
Connection conn = dataSource.getConnection();
// 创建Statement对象
Statement statement = conn.createStatement();
// 处理结果集
ResultSet rs = statement.executeQuery("select 1 from dual");
printResultSet(rs);
} private static void printResultSet(ResultSet rs) throws SQLException {
while (rs.next()) {
System.out.println("返回结果集为:" + rs.getInt(1));
}
} /**
* 连接数据库时的必要配置, driverClass:驱动类 jdbcUrl:数据库实例url,格式为jdbc:subprotocol:subname
* user:用户名,其他数据源有时候使用username表示,拥有相同的含义。 password:密码,用户密码
*
* @param dataSource
* @return
* @throws PropertyVetoException
*/
public static ComboPooledDataSource connDatabaseConfig(ComboPooledDataSource dataSource,
String dsName) throws PropertyVetoException {
String jdbcUrl = null;
switch (dsName) {
case "masterOracle":
jdbcUrl = masterOraclejdbcUrl;
break;
case "orcl":
jdbcUrl = orclJdbcUrl;
break;
default:
break;
}
// 设置数据库url
dataSource.setJdbcUrl(jdbcUrl);
// 设置数据库驱动类
dataSource.setDriverClass(driverClassName);
// 设置用户名
dataSource.setUser(user);
// 设置密码
dataSource.setPassword(password);
// 输出dataSourceName,在初始化ComboPooledDataSource时,字符串参数作为数据源名称,
dataSource.getDataSourceName();
return dataSource;
} /**
* 将布尔值true转换为是,布尔值false转换为否
*
* @param value
* @return
*/
private static String convertBooleanToStr(boolean value) {
if (value) {
return "是";
} else {
return "否";
}
}
}
Properties方式:在类加载路径下,配置项有c3p0前缀
##-------------------------------数据库连接属性-----------------------------------##
# 驱动类名称
c3p0.driverClass=oracle.jdbc.driver.OracleDriver
# 数据库实例url地址
c3p0.jdbcUrl=jdbc:oracle:thin:@localhost:1521:masteroracle
# 用户名
c3p0.user=system
# 密码
c3p0.password=password
##-------------------------------调试模式--------------------------------------##
# 当从连接池获取连接对象时,打印所有信息。
c3p0.debugUnreturnedConnectionStackTraces=true
##-------------------------------日志配置--------------------------------------##
# 日志的实现方式
#com.mchange.v2.log.MLog=log4j
# 日志的级别,OFF,SERVER,WARNING,INFO,FINE,FINER,FINEST,ALL
com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL=All
# 日志按包输出
com.mchange.v2.log.NameTransformer=com.mchange.v2.log.PackageNames
# determine the class and method from which a log message was generated,当为true时,不打印这些日志信息
com.mchange.v2.log.jdk14logging.suppressStackWalk=true
##-------------------------------连接池配置-------------------------------------##
# 连接池拥有连接对象的初始值,这种情形下只是Acquire(需求)的初始值,真正创建对象会根据Acquire来按需创建
c3p0.initialPoolSize=10
# 连接池拥有连接对象的最大值,默认值为3
c3p0.maxPoolSize=20
# 连接池拥有连接对象的最小值,默认值为3
c3p0.minPoolSize=5
# 当无空闲连接时,新创建的连接数,默认值为3
c3p0.acquireIncrement=3
##-------------------------------连接生命周期--------------------------##
# 连接对象的最大生存时间,起始时间从连接池从数据库中创建连接对象开始计算。0表示永远不销毁
c3p0.maxConnectionAge=0
# 空闲连接对象的超时时间,起始时间从连接对象状态变为空闲时起计算。
c3p0.maxIdleTime=1800
# 当连接池不处于满载状态时,空闲连接对象的最大生存时间,设置此值,可以快速的减少连接池的大小
c3p0.maxIdleTimeExcessConnections=60
# 连接对象回收的超时时间,当连接池无法在一定时间内回收连接对象时,销毁旧对象,重新创建新对象
c3p0.unreturnedConnectionTimeout=600
##-------------------------------测试连接配置项----------------------------------##
# 从连接池中获取连接对象时进行连接测试
c3p0.testConnectionOnCheckout=true
# 从连接池回收对象时进行连接测试
c3p0.testConnectionOnCheckin=true
# 连接测试的间隔,在这一段时间内不进行连接测试
c3p0.idleConnectionTestPeriod=60
# 连接测试时使用的类,设置此值时忽略preferredTestQuery,automaticTestTable等属性值
#c3p0.connectionTesterClassName=com.rain.Tester.ConnectionTesterSample
# 测试的SQL语句
c3p0.preferredTestQuery=select 1
# 连接测试时使用的数据库表
c3p0.automaticTestTable=test
##-------------------------------重新连接---------------------------------------##
# 重新连接的次数
c3p0.acquireRetryAttempts=5
# 重新连接的时间间隔,单位为毫秒
c3p0.acquireRetryDelay=3000
# 等待连接响应的超时时间
c3p0.checkoutTimeout=120
# 当连接失败时,是否销毁数据源对象,true表示是,false表示否
c3p0.breakAfterAcquireFailure=true
##-------------------------------statement对象相关配置---------------------------##
# c3p0拥有的PreparedStatement对象的总数
c3p0.maxStatements=100
# 每个连接拥有PreparedStament对象的数量
c3p0.maxStatementsPerConnection=10
# 当Connection对象关闭时,启动额外线程确保statement对象关闭
# This parameter should only be set if you observe that attempts by c3p0 to close() cached statements freeze
statementCacheNumDeferredCloseThreads=1
##-------------------------------线程池----------------------------------------##
# 连接池拥有的线程数量
c3p0.numHelperThreads=5
# 线程执行的最大时间
c3p0.maxAdministrativeTaskTime=600
# 启动独立的线程来在连接被连接池回收阶段进行测试
forceSynchronousCheckins=true
##-------------------------------事务-----------------------------------------##
# 交给Spring去管理事务,默认不配置这些项
# 连接关闭时,是否自动提交事务
c3p0.autoCommitOnClose=false
# 连接回收时,是否强制提交或者回滚当前连接拥有的事务,默认不配置。
c3p0.forceIgnoreUnresolvedTransactions=false
##-------------------------------监听类---------------------------------------##
c3p0.connectionCustomizerClassName=com.rain.Tester.ConnCustomrizerSample
##-------------------------------类加载器配置------------------------------------##
# contextClassLoaderSource should be set to one of caller, library, or none
c3p0.contextClassLoaderSource=caller
# privilegeSpawnedThreads is a boolean, false by default. Set this to true so that c3p0's Threads use the
# c3p0 library's AccessControlContext, rather than an AccessControlContext that may be associated with
# the client application and prevent its garbage collection.
privilegeSpawnedThreads=false
xml方式:com.mchange.v2.c3p0.cfg.xml指定c3p0-config.xml的路径
System属性:System.setProperty(key,value)。
验证
代码方式的执行结果
——————————————————————————————————————————————————————————————————————
||-------------------连接数据库的必要属性-----------------||
数据源的驱动类名称:oracle.jdbc.driver.OracleDriver
数据源的连接URL:jdbc:oracle:thin:@localhost:1521:masteroracle
数据源的连接用户名:system
数据源的连接密码:password
数据源的Id:1hge1639oxiibou10417lr|7506e922
——————————————————————————————————————————————————————————————————————
||-------------------连接池大小配置---------------------||
连接池的初始需求量大小:10
连接池的最大值:20
连接池的最小值:5
当无可用连接时,连接池需求量的递增值:3
——————————————————————————————————————————————————————————————————————
||-------------------连接对象的生命周期--------------------||
连接对象的最大生存时间,从创建连接对象时开始计时:0
空闲连接对象的超时时间,从连接对象变为空闲状态开始计时:1800
当连接池负载较低时,空闲连接对象的最大生命年龄:60
从连接池获取连接对象之后,连接对象的超时时间:600
——————————————————————————————————————————————————————————————————————
||-------------------测试连接的配置----------------------||
测试连接使用的数据库表:test
测试连接使用的SQL语句:select 1
从连接池中获取连接时是否进行连接测试:是
从连接池中回收连接时是否进行连接测试:是
测试连接的时间间隔:60秒
测试连接使用的类名称:com.mchange.v2.c3p0.impl.DefaultConnectionTester
——————————————————————————————————————————————————————————————————————
||-------------------重连配置-----------------||
连接失败后,尝试重连的次数:5
重连的时间间隔:3000毫秒
用户等待连接的超时时间:120
重连失败后,是否销毁数据源:是
——————————————————————————————————————————————————————————————————————
||-------------------缓存preparedStatement对象的配置-----------------||
连接池拥有PreparedStatement对象的总数:100
每个连接拥有PreparedStatement对象的数量:10
——————————————————————————————————————————————————————————————————————
||-------------------线程设置--------------------------||
连接池拥有的线程数量:5
线程执行的超时时间:600
——————————————————————————————————————————————————————————————————————
||-------------------事务配置---------------------------||
连接对象的事务是否自动提交:否
回收连接对象时,是否强制提交和回滚事务:否
——————————————————————————————————————————————————————————————————————
||-------------------调试模式配置-----------------------||
从连接池获取连接对象时,是否打印所有信息:是
——————————————————————————————————————————————————————————————————————
||-------------------监听类名称-----------------||
连接对象的监听类名称:com.rain.Tester.ConnCustomrizerSample
参考资料
C3p0 —— JDBC 3 Connection and Statement Pooling http://www.mchange.com/projects/c3p0
数据库程序接口——JDBC——功能第二篇——数据源之C3P0数据源的更多相关文章
- 数据库程序接口——JDBC——功能第一篇——第一个程序
流程图 综述 从零开始搭建JDBC环境.通过创建Java项目,在项目中,通过java程序执行SQL,并处理返回的结果.本文通过执行 select 1 from dual 语句来测试,并输出相结果集.首 ...
- 数据库程序接口——JDBC——功能第五篇——批量处理
综述 批量处理一般指批量插入,批量更新,删除通过可以指定where条件实现.批量插入的实现方式有三种类型.statement,preparedStatement,callableStatement. ...
- 数据库程序接口——JDBC——功能第四篇——事务之Spring事务
综述 事务的实现方式有三种,JTA,Spring事务,Web Container方式.本篇讲述Spring事务. Spring事务分为两个部分核心对象,Spring事务的实现方式. Spring事务实 ...
- 数据库程序接口——JDBC——初篇——目录
目录 建立连接 核心对象 Driver DriverManager Connection DataSource 常用功能 第一个程序 C3P0数据源 DBCP数据源 事务之Spring事务 执行SQL ...
- 数据库程序接口——JDBC——API解读第二篇——执行SQL的核心对象
结构图 核心对象 Statement Statement主要用来执行SQL语句.它执行SQL语句的步骤为: 第一步:创建statement对象. 第二步:配置statement对象,此步骤可以忽略. ...
- 数据库程序接口——JDBC——API解读第一篇——建立连接的核心对象
结构图 核心对象 Driver Java通过Driver接口表示驱动,每种类型的数据库通过实现Driver接口提供自己的Driver实现类. Driver由属性,操作,事件三部分组成. 属性 公共属性 ...
- 数据库程序接口——JDBC——API解读第三篇——处理结果集的核心对象
核心对象 处理结果集的核心对象有ResultSet和RowSet.其中ResultSet指定关系型数据库的结果集,RowSet更为抽象,凡是由行列组成的数据都可以. ResultSet ResultS ...
- JDBC 学习笔记(三)—— 数据源(数据库连接池):DBCP数据源、C3P0 数据源以及自定义数据源技术
本文目录: 1.应用程序直接获取连接的缺点(图解) 2.使用数据库连接池优化程序性能(图解) 3.可扩展增强某个类方法的功能的三种方式 4.自定 ...
- (转).net程序员转战android第二篇---牛刀小试
上篇说道如何搭建android的开发环境,这一篇我们将牛刀小试一下, 完成我们第一个android APP应用. 我就从新建项目说起吧. 首先打开Eclipse,选择顶部的File(文件)——new( ...
随机推荐
- redis string类型 增删改查
string一.设置 1.设置一个键值对时,如果该键已存在,那么就成了updata (key:value) 例: set name jiang 访问值:get name 2.设置值过期时间:setex ...
- 三、linux环境的搭建1(oracle、ssh、jdk、mysql、samba、tomcat)
linux环境的搭建1(oracle.ssh.jdk.mysql.samba.tomcat) 网络配置 方案一 tip 1 使用ifconfig : ifconfig eth0 新ip 然后编辑/ ...
- bugku 想蹭网先解开密码
首先下载文件 然后 创建密码字典:使用命令 crunch 11 11 -t 1391040%%%% -o password.txt 爆破:使用命令 aircrack-ng -a2 所下载文件的地址 - ...
- 记录 shell学习过程(8)函数
start () { echo "Apache start ...... [OK]" #return 0 可以写一个返回值,比如执行成功返回 0 } stop () { echo ...
- http接口性能测试工具
一. http_load 程序非常小,解压后也不到100K.http_load以并行复用的方式运行,用以测试web服务器的吞吐量与负载. 但是它不同于大多数压力测试工具,它可以以一个单一的进程运行,一 ...
- adb shell 杀进程以及端口占用,adbserver服务重启失败
linux: adb shell ps |grep netease 杀进程: adb shell kill [PID] //杀死进程 C:\Users\chenquan>adb shell ...
- MFC对话框常用操作文章收藏
1.改变控件文本 参考链接:https://blog.csdn.net/active2489595970/article/details/88856235 所有控件的文本都可以用这种方式动态改变. 2 ...
- 题解 Fractal Streets
题目链接 参考博客 #include<cstdio> #include<math.h> #include<utility>//pair using namespac ...
- ET框架之SceneChangeComponent
初始化事件 using ETModel; namespace ETHotfix { [Event(EventIdType.InitSceneStart)] public class InitScene ...
- Python获取最新电影的信息
这次将从电影天堂获取最新的电影的详细信息,这里电影的信息罗列的比较详细. 本来只是想获取电影的迅雷链接,然后用迅雷去下载.但看到这里的电影的信息比较完整和详细,忍不住把所有信息都爬取下来了. 下图是& ...