1,在com.ibatis.sqlmap.engine.datasource包新增类C3P0DataSourceFactory:
package com.ibatis.sqlmap.engine.datasource;
import com.ibatis.common.jdbc.C3P0Configuration;
import java.util.Map;
import javax.sql.DataSource;
public class C3P0DataSourceFactory
implements DataSourceFactory
{
private DataSource dataSource;
public void initialize(Map map)
{
C3P0Configuration c3p0 = new C3P0Configuration(map);
this.dataSource = c3p0.getDataSource();
}
public DataSource getDataSource() {
return this.dataSource;
}
}
2,在com.ibatis.common.jdbc包新增类C3P0Configuration ,主要作用是加载c3p0的配置文件信息:
package com.ibatis.common.jdbc;
import com.ibatis.common.beans.Probe;
import com.ibatis.common.beans.ProbeFactory;
import com.ibatis.common.exception.NestedRuntimeException;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
public class C3P0Configuration
{
private static final Probe PROBE = ProbeFactory.getProbe();
private static final String ADD_DRIVER_PROPS_PREFIX = "Driver.";
private static final int ADD_DRIVER_PROPS_PREFIX_LENGTH = "Driver.".length();
private DataSource dataSource;
public C3P0Configuration(Map properties)
{
try
{
this.dataSource = legacyC3P0Configuration(properties);
if (this.dataSource == null)
this.dataSource = newDbcpConfiguration(properties);
} catch (Exception e) {
throw new NestedRuntimeException("Error initializing C3P0DataSourceFactory. Cause: " + e, e);
}
}
public DataSource getDataSource() {
return this.dataSource;
}
private BasicDataSource newDbcpConfiguration(Map map) {
BasicDataSource basicDataSource = new BasicDataSource();
Iterator props = map.keySet().iterator();
while (props.hasNext()) {
String propertyName = (String)props.next();
if (propertyName.startsWith("Driver.")) {
String value = (String)map.get(propertyName);
basicDataSource.addConnectionProperty(propertyName.substring(ADD_DRIVER_PROPS_PREFIX_LENGTH), value);
} else if (PROBE.hasWritableProperty(basicDataSource, propertyName)) {
String value = (String)map.get(propertyName);
Object convertedValue = convertValue(basicDataSource, propertyName, value);
PROBE.setObject(basicDataSource, propertyName, convertedValue);
}
}
return basicDataSource;
}
private Object convertValue(Object object, String propertyName, String value) {
Object convertedValue = value;
Class targetType = PROBE.getPropertyTypeForSetter(object, propertyName);
if ((targetType == Integer.class) || (targetType == Integer.TYPE))
convertedValue = Integer.valueOf(value);
else if ((targetType == Long.class) || (targetType == Long.TYPE))
convertedValue = Long.valueOf(value);
else if ((targetType == Boolean.class) || (targetType == Boolean.TYPE)) {
convertedValue = Boolean.valueOf(value);
}
return convertedValue;
}
private ComboPooledDataSource legacyC3P0Configuration(Map map) throws Exception {
ComboPooledDataSource basicDataSource = null;
if (map.containsKey("driver")) {
basicDataSource = new ComboPooledDataSource();
String driver = (String)map.get("driver");
String url = (String)map.get("url");
String username = (String)map.get("username");
String password = (String)map.get("password");
String initialPoolSize = (String)map.get("initialPoolSize");
String maxPoolSize = (String)map.get("maxPoolSize");
String minPoolSize = (String)map.get("minPoolSize");
String acquireIncrement = (String)map.get("acquireIncrement");
String maxIdleTime = (String)map.get("maxIdleTime");
String maxIdleTimeExcessConnections = (String)map.get("maxIdleTimeExcessConnections");
String maxConnectionAge = (String)map.get("maxConnectionAge");
String maxStatements = (String)map.get("maxStatements");
String maxStatementsPerConnection = (String)map.get("maxStatementsPerConnection");
String numHelperThreads = (String)map.get("numHelperThreads");
String automaticTestTable = (String)map.get("automaticTestTable");
String preferredTestQuery = (String)map.get("preferredTestQuery");
String checkoutTimeout = (String)map.get("checkoutTimeout");
String idleConnectionTestPeriod = (String)map.get("idleConnectionTestPeriod");
String acquireRetryDelay = (String)map.get("acquireRetryDelay");
String acquireRetryAttempts = (String)map.get("acquireRetryAttempts");
String testConnectionOnCheckin = (String)map.get("testConnectionOnCheckin");
basicDataSource.setDriverClass(driver);
basicDataSource.setJdbcUrl(url);
basicDataSource.setUser(username);
basicDataSource.setPassword(password);
if (notEmpty(automaticTestTable)) {
basicDataSource.setAutomaticTestTable(automaticTestTable);
}
if (notEmpty(acquireRetryDelay)) {
basicDataSource.setAcquireRetryDelay(Integer.valueOf(acquireRetryDelay).intValue());
}
if (notEmpty(testConnectionOnCheckin)) {
basicDataSource.setTestConnectionOnCheckin(Boolean.valueOf(testConnectionOnCheckin).booleanValue());
}
if (notEmpty(acquireRetryAttempts)) {
basicDataSource.setAcquireRetryAttempts(Integer.valueOf(acquireRetryAttempts).intValue());
}
if (notEmpty(preferredTestQuery)) {
basicDataSource.setPreferredTestQuery(preferredTestQuery);
}
if (notEmpty(checkoutTimeout)) {
basicDataSource.setCheckoutTimeout(Integer.valueOf(checkoutTimeout).intValue());
}
if (notEmpty(checkoutTimeout)) {
basicDataSource.setCheckoutTimeout(Integer.valueOf(checkoutTimeout).intValue());
}
if (notEmpty(idleConnectionTestPeriod)) {
basicDataSource.setIdleConnectionTestPeriod(Integer.valueOf(idleConnectionTestPeriod).intValue());
}
if (notEmpty(initialPoolSize)) {
basicDataSource.setInitialPoolSize(Integer.parseInt(initialPoolSize));
}
if (notEmpty(maxPoolSize)) {
basicDataSource.setMaxPoolSize(Integer.parseInt(maxPoolSize));
}
if (notEmpty(minPoolSize)) {
basicDataSource.setMinPoolSize(Integer.parseInt(minPoolSize));
}
if (notEmpty(acquireIncrement)) {
basicDataSource.setAcquireIncrement(Integer.parseInt(acquireIncrement));
}
if (notEmpty(maxIdleTime)) {
basicDataSource.setMaxIdleTime(Integer.parseInt(maxIdleTime));
}
if (notEmpty(maxIdleTimeExcessConnections)) {
basicDataSource.setMaxIdleTimeExcessConnections(Integer.parseInt(maxIdleTimeExcessConnections));
}
if (notEmpty(maxConnectionAge)) {
basicDataSource.setMaxConnectionAge(Integer.parseInt(maxConnectionAge));
}
if (notEmpty(maxStatements)) {
basicDataSource.setMaxStatements(Integer.parseInt(maxStatements));
}
if (notEmpty(maxStatementsPerConnection)) {
basicDataSource.setMaxStatementsPerConnection(Integer.parseInt(maxStatementsPerConnection));
}
if (notEmpty(numHelperThreads)) {
basicDataSource.setNumHelperThreads(Integer.parseInt(numHelperThreads));
}
}
return basicDataSource;
}
private boolean notEmpty(String s) {
return (s != null) && (s.length() > 0);
}
}
3,在com.ibatis.sqlmap.engine.builder.xml下SqlMapConfigParser类的registerDefaultTypeAliases方法中添加如下代码:
this.vars.typeHandlerFactory.putTypeAlias("C3P0", C3P0DataSourceFactory.class.getName());
4,在com.ibatis.common.exception下新增异常处理类,如果没有此包,可以新建,代码见附件Exception.rar(NestedException.class , NestedRuntimeException.class)
5, ibatis配置文件如下,注意property中的name必须和下面一致:
<transactionManager type="JDBC">
<dataSource type="C3P0">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
<property name="initialPoolSize" value="10" />
<property name="maxPoolSize" value="100" />
<property name="minPoolSize" value="10" />
<property name="acquireIncrement" value="5" />
<property name="maxIdleTime" value="3600" />
<property name="maxIdleTimeExcessConnections" value="1200" />
<property name="maxConnectionAge" value="27000" />
<property name="maxStatements" value="200" />
<property name="maxStatementsPerConnection" value="50" />
<property name="numHelperThreads" value="10" />
<property name="idleConnectionTestPeriod" value="5" />
<property name="checkoutTimeout" value="30000"/>
<property name="preferredTestQuery" value="select 1"/>
<property name="acquireRetryDelay" value="1000"/>
<property name="acquireRetryAttempts" value="1"/>
<property name="testConnectionOnCheckin" value="true"/>
<property name="automaticTestTable" value="c3p0Test"/>
</dataSource>
</transactionManager>
配置中只支持如上属性配置,如果需要加额外属性请在第二步的C3P0Configuration类的legacyC3P0Configuration方法中增加
附件ibatis-2.3.0.677.jar包是已扩展,无需修改
增加c3p0支持包:c3p0-0.9.1.2.jar
PS: 以上只限ibatis-2.3.0.677版本,其他版本按照此方式未必行得通
以下亲测可用
PS: 以下只限ibatis-2.3.0.677版本