综述

C3P0由三部分内容组成。实例化对象,各配置项的含义,以及加载配置项的方式。

实例化对象的方式有三种,第一种方式直接new ComboPooledDataSource,第二种方式使用工厂类DataSources.poolDataSource方法。第三种不常见。第一种方式是最方便的方式。

C3P0的配置项主要有:

  1. 连接数据库的必要属性:例如jdbcUrl,user,password等。
  2. 连接池的大小配置。例如initialPoolSize
  3. 连接对象的生命周期。例如maxConnectionAge。
  4. 测试连接的配置,例如preferredTestQuery指定测试SQL语句。
  5. 重连策略的配置,例如acquireRetryAttempts指定重连次数。
  6. statement对象的配置,例如maxStatements指定最大Statement的总数。
  7. 线程配置,例如numHelperThread指定连接池拥有的线程数量。
  8. 事务配置,例如autoCommitOnClose指定是否在回收连接对象时自动提交事务。
  9. 调试模式,例如debugUnreturnedConnectionStackTraces为true时,会打印所有从连接池获取连接对象的记录。
  10. 监听类的设置,例如connectionCustomizerClassName指定监听类的名称,该类可以实现onAcquire,onDestory等方法。
  11. 日志的设置,例如com.mchange.v2.log.MLog指定日志的实现方式。常见的有log4J,commonLogging等。

配置项常见的加载方式有三种:

  1. 代码方式:通过实例对象调用setXX方法。
  2. properties文件:这种方式需要properties文件的名称必须为c3p0.properties,而且该文件必须在类加载路径下。
  3. 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;

连接必要属性

  1. driverClassName:驱动类的名称,包名+类名
  2. jdbcUrl:数据库实例的url地址,格式为jdbc:subprotocol:subname。其中subprotocol表示连接方式。
  3. user:用户名
  4. 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();

连接池大小

  1. initialPoolSize:连接池的初始需求量大小,实际创建的连接对象小于需求量大小。
  2. minPoolSize:连接池连接数量的最小值。
  3. maxPoolSize:连接池连接数量的最大值。
  4. 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);
}

连接生命周期

  1. maxIdleTime:空闲连接对象的超时时间,当连接对象处于空闲状态的时间超过此时间,连接池销毁该连接对象。
  2. maxConnectionAge:连接对象的最大生命值,从创建连接对象开始计算。当超出此时间,销毁连接对象。与maxIdleTime的区别在于maxIdleTime只适用于空闲连接对象,而且是从空闲状态开始计算时间。
  3. maxIdleTimeExcessConnections:当连接池负载较低时,空闲连接对象的超时时间,设置此项可以在负载较低时,快速的释放链接。
  4. 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);
}

测试连接

  1. automaticTestTable:测试连接使用的数据库表
  2. connectionTesterClassName:测试连接使用的类名称
  3. idleConnectionTestPeriod:测试连接的时间间隔,在此间隔内不执行连接测试
  4. preferredTestQuery:SELECT 1。如果支持JDBC 4,会使用Connection.isAlive方法不设置此值。
  5. testConnectionOnCheckin:是否在连接池中回收连接对象时进行连接测试,
  6. 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");
}

重连策略

  1. acquireRetryAttempts:连接失败后,重连次数
  2. acquireRetryDelay:第一次重连与第二次重连的时间间隔。单位为毫秒
  3. checkTimeOut:等待连接的超时时间,超出此时间后不在进行重连。
  4. 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配置

  1. maxStatements:连接池缓存PreparedStatement对象的总数
  2. maxStatementsPerConnection:每个连接缓存PreparedStatement的最大值。
  3. 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);
}

线程配置

  1. numHelperThreads:连接池拥有的线程数量。
  2. maxAdministrativeTaskTime:线程执行任务的超时时间,当超出此时间时,会销毁该线程,重新创建新线程。
  3. 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);
}

事务配置

  1. autoCommitOnClose:回收连接对象时,是否自动提交事务。默认不配置,通过其他方式管理事务,例如Spring事务
  2. 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); }

调试模式

  1. debugUnreturnedConnectionStackTraces:打印从连接池获取连接对象的所有信息。

C3P0.properties的方式

##-------------------------------调试模式--------------------------------------##
# 当从连接池获取连接对象时,打印所有信息。
c3p0.debugUnreturnedConnectionStackTraces=true

代码方式

     /**
* 调试模式的设置 debugUnreturnedConnectionStackTraces:从连接池获取连接对象时,打印所有信息 *
* @param dataSource
*/
private static void debugMode(ComboPooledDataSource dataSource) {
// 从连接池获取连接对象时,打印所有信息
dataSource.setDebugUnreturnedConnectionStackTraces(true);
}

监听类

connectionCustomizerClassName:监听类的名称,监听类继承自AbstractConnectionCustomizer,监听类有四个方法

  1. onAcquire在数据库中创建连接对象时触发。
  2. onDestory在连接池中销毁连接对象时触发。
  3. onCheckOut从连接池获取连接对象时触发
  4. 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");
}

日志配置

  1. com.mchange.v2.log.MLog:日志的实现方式
  2. com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL:日志的级别。可选值为OFF,SERVER,WARNING,INFO,FINE,FINER,FINEST,ALL
  3. com.mchange.v2.log.NameTransformer:日志按每个数据源类输出,还是按包。com.mchange.v2.log.PackageNames表示按包,默认的方式按类的方式
  4. 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数据源的更多相关文章

  1. 数据库程序接口——JDBC——功能第一篇——第一个程序

    流程图 综述 从零开始搭建JDBC环境.通过创建Java项目,在项目中,通过java程序执行SQL,并处理返回的结果.本文通过执行 select 1 from dual 语句来测试,并输出相结果集.首 ...

  2. 数据库程序接口——JDBC——功能第五篇——批量处理

    综述 批量处理一般指批量插入,批量更新,删除通过可以指定where条件实现.批量插入的实现方式有三种类型.statement,preparedStatement,callableStatement. ...

  3. 数据库程序接口——JDBC——功能第四篇——事务之Spring事务

    综述 事务的实现方式有三种,JTA,Spring事务,Web Container方式.本篇讲述Spring事务. Spring事务分为两个部分核心对象,Spring事务的实现方式. Spring事务实 ...

  4. 数据库程序接口——JDBC——初篇——目录

    目录 建立连接 核心对象 Driver DriverManager Connection DataSource 常用功能 第一个程序 C3P0数据源 DBCP数据源 事务之Spring事务 执行SQL ...

  5. 数据库程序接口——JDBC——API解读第二篇——执行SQL的核心对象

    结构图 核心对象 Statement Statement主要用来执行SQL语句.它执行SQL语句的步骤为: 第一步:创建statement对象. 第二步:配置statement对象,此步骤可以忽略. ...

  6. 数据库程序接口——JDBC——API解读第一篇——建立连接的核心对象

    结构图 核心对象 Driver Java通过Driver接口表示驱动,每种类型的数据库通过实现Driver接口提供自己的Driver实现类. Driver由属性,操作,事件三部分组成. 属性 公共属性 ...

  7. 数据库程序接口——JDBC——API解读第三篇——处理结果集的核心对象

    核心对象 处理结果集的核心对象有ResultSet和RowSet.其中ResultSet指定关系型数据库的结果集,RowSet更为抽象,凡是由行列组成的数据都可以. ResultSet ResultS ...

  8. JDBC 学习笔记(三)—— 数据源(数据库连接池):DBCP数据源、C3P0 数据源以及自定义数据源技术

    本文目录:        1.应用程序直接获取连接的缺点(图解)        2.使用数据库连接池优化程序性能(图解)        3.可扩展增强某个类方法的功能的三种方式        4.自定 ...

  9. (转).net程序员转战android第二篇---牛刀小试

    上篇说道如何搭建android的开发环境,这一篇我们将牛刀小试一下, 完成我们第一个android APP应用. 我就从新建项目说起吧. 首先打开Eclipse,选择顶部的File(文件)——new( ...

随机推荐

  1. [CF91B] Queue - 权值线段树

    有n个人在队列中等待.假如某个人前面有一个人年龄比他小,那他就会不高兴:定义他的"不高兴度"为他前面留他最远的年龄比他小的人与他的距离,求每个人的不高兴度. n<=10^5 ...

  2. PP: Think globally, act locally: A deep neural network approach to high-dimensional time series forecasting

    Problem: high-dimensional time series forecasting ?? what is "high-dimensional" time serie ...

  3. SpringMVC流程图示

  4. VTK坐标系统及视图分割

    计算机图像学里广泛应用的坐标系统有四种,分别是:模型坐标系统(model),世界坐标系统(world),视图坐标系统(view)和显示坐标系统(display). 模型坐标系统就是定义模型时所用的坐标 ...

  5. 编码 - 坑 - win10 下采用 utf-8, 导致 gitbash 中文字体异常, 待解决

    blog01 概述 使用 git 中, 遇到一个坑 背景 最近遇到一个 编码转换 问题 本来也 一知半解 要是有人能给我讲讲就好了 环境 win10 1903 git 2.20.1 1. 问题 概述 ...

  6. java课后作业3

    1.动手动脑 由于类中定义了需要参数的构造方法,导致系统不再提供默认的构造方法. 2.java字段初始化 运行结果 100 300 java字段在初始化时先按照对应的构造方法执行.若构造方法中没有对变 ...

  7. sql查询 —— 模糊查询

    --模糊查询 --like --%至少替换一个 -- _只替换一个 -- 查姓李的人 select *from student name like "李%"; -- 查名为杰伦的人 ...

  8. linux 创建svn版本库,并在svn上配置checkstyle做代码风格检查

    一.创建SVN版本库 1.安装svn服务器 yum install subversion 2.查看版本 svnserve --version 3.建立SVN版本库目录(即你的SVN服务器里面的文件存放 ...

  9. Python - isinstance()更深刻的理解

    起因经过 今天翻collections.abc的文档时,我知道list的实例在逻辑上(因为duck typing 鸭子类型)是Container和不能hash的(因为list可变),就试下面的代码是否 ...

  10. STL初探

    关于STL的一些东西 感言: 学C++不学STL函数库的人可能都是... 有点问题 头文件<algorithm>的一些东西 sort,快排: 这是个初学者必需掌握的东西,及其好用,因为方( ...