urce...
} finally {
DataSources.destroy(ds_pooled);
}
?
可供选择的,c3p0的PooledDataSource接口包含一个close()方法,当你使用DataSource完成工作以后你可以调用它。所以,你可以转换一个c3p0派生出的DataSource为PooledDataSource然后关闭它。
?
static void cleanup(DataSource ds) throws SQLException {
// Make sure it's a c3p0 PooledDataSource
if (ds instanceof PooledDataSource) {
PooledDataSource pds = (PooledDataSource) ds;
pds.close();
} else
System.err.println("Not a c3p0 PooledDataSource!");
}
?
ComboPooledDataSource是PooledDataSource的实例,可以直接通过close()关闭。PooledDataSource实现了java.lang.AutoCloseable,所以他们可以被Java 7 + try-with-resources块管理。
?
不是PooledDataSource的实例不能用close()方法,如果想要关闭他们优先在它们的finalize()中使用垃圾回收机制(garbage collection)。一如既往,析构(finalization)应该被认为是一个捕手,而不是一个提示或是清理资源的途径。
?
高级:构建自己的PoolBackedDataSource
大部分程序员这么做是有一些原因的,但是你可以一步步的构建PooledDataSource。通过实例化并配置一个无池DriverManagerDataSource,实例化一个WrapperConnectionPoolDataSource并设置一个无池DataSource作为它的nestedDataSource属性,然后PoolBackedDataSource使用这些设置connectionPoolDataSource属性。
?
如果你的驱动提供一个ConnectionPoolDataSource实现,这些事件序列就是首要的关键点,你会更倾向于这样使用c3p0,而不是使用c3p0的WrapperConnectionPoolDataSource,你可以创建一个PoolBackedDataSource设置它的connectionPoolDataSource属性。Statement池,ConnectionCustomizers,和很多c3p0特定的属性不被第三方ConnectionPoolDataSource支持(第三方DataSource实现只能替代c3p0的DriverManagerDataSource没有重大损失的功能)。
?
?
高级:原始连接和语句操作
?
注意:自c3p0-0.9.5起,通过代理c3p0支持标准JDBC4的unwrap()方法。注意如果你使用unwrap()方法,c3p0就不能清理任何你从原始Connections或是Statements生成的Statement或是ResultSet对象。使用者必须小心仔细的直接清理这些对象。此外,使用者应该注意不要以某种方式修改底层的Connections,致使它们不能再与其它的Connections替换,因为必须保持它们是适合于连接池的。
?
JDBC驱动有时候根据特定供应商,非标准API去定义Connection和Statement的实现。C3P0通过代理包装这些对象,所以你不能转换由C3P0返回的Connections或是Statements到特定供应商实现的类。C3P0并不提供任何方式去直接访问原始Connections和Statements,因为C3P0需要保持追踪Statements和ResultSets的创建,防止资源泄露和破坏连接池。
?
C3P0确实提供了一个API,允许你在底层Connection上反射调用非标准方法。为了使用它,第一步,转换Connection为一个C3P0ProxyConnection。然后调用rawConnectionOperation(),应用java.lang.reflect.Method对象,你希望调用的非标准方法作为其参数。你提供的Method对象将会被你提供的第二个参数目标调用(静态方法则为null),并且使用你提供的第三个参数。对于这个目标,任何的方法参数,你都可以应用特定的C3P0ProxyConnection.RAW_CONNECTION,在Method被调用之前,它将被底层特定供应商Connection对象替代。
?
C3P0ProxyStatement提供一个类似的API。
任何原始操作返回的Statements(包括Prepared和CallableStatements)和ResultSets都将被c3p0-managed,被父代理Connection的close()正确的清理。使用者必须仔细清理任何通过特定供应商返回的非标准资源。
?
这里有一个例子,在Oracle-specific API上调用原始Connection的静态方法:
?
C3P0ProxyConnection castCon = (C3P0ProxyConnection) c3p0DataSource.getConnection();
Method m = CLOB.class.getMethod("createTemporary", new Class[] { Connection.class, boolean.class, int.class });
Object[] args = new Object[] { C3P0ProxyConnection.RAW_CONNECTION, Boolean.valueOf(true), new Integer(10) };
CLOB oracleCLOB = (CLOB) castCon.rawConnectionOperation(m, null, args);
?
C3P0包含了对一些Oracle-specific方法特殊的支持,请另行参考官方文档。