package com.taobao.yugong.common.db;
import java.util.Map;
import java.util.Properties;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.druid.pool.DruidDataSource;
import com.google.common.base.Function;
import com.google.common.collect.MigrateMap;
import com.taobao.yugong.common.lifecycle.AbstractYuGongLifeCycle;
import com.taobao.yugong.common.lifecycle.YuGongLifeCycle;
import com.taobao.yugong.common.model.DataSourceConfig;
import com.taobao.yugong.common.model.DbType;
import com.taobao.yugong.exception.YuGongException;
/**
* 获取数据库连接
*
* @author agapple 2013年2月25日 下午8:00:41
* @since 1.0.0
*/
public class DataSourceFactory extends AbstractYuGongLifeCycle implements YuGongLifeCycle {
private static final Logger logger = LoggerFactory.getLogger(DataSourceFactory.class);
private int maxWait = 5 * 1000;
private int minIdle = 0;
private int initialSize = 0;
private int maxActive = 32;
private Map<DataSourceConfig, DataSource> dataSources;
public void start() {
super.start();
dataSources = MigrateMap.makeComputingMap(new Function<DataSourceConfig, DataSource>() {
public DataSource apply(DataSourceConfig config) {
return createDataSource(config.getUrl(),
config.getUsername(),
config.getPassword(),
config.getType(),
config.getProperties());
}
});
}
public void stop() {
super.stop();
for (DataSource source : dataSources.values()) {
DruidDataSource basicDataSource = (DruidDataSource) source;
basicDataSource.close();
}
dataSources.clear();
}
public DataSource getDataSource(DataSourceConfig config) {
return dataSources.get(config);
}
public DataSource getDataSource(String url, String userName, String password, DbType dbType, Properties props) {
return dataSources.get(new DataSourceConfig(url, userName, password, dbType, props));
}
private DataSource createDataSource(String url, String userName, String password, DbType dbType, Properties props) {
try {
int maxActive = Integer.valueOf(props.getProperty("maxActive", String.valueOf(this.maxActive)));
if (maxActive < 0) {
maxActive = 200;
}
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(url);
dataSource.setUsername(userName);
dataSource.setPassword(password);
dataSource.setUseUnfairLock(true);
dataSource.setNotFullTimeoutRetryCount(2);
dataSource.setInitialSize(initialSize);
dataSource.setMinIdle(minIdle);
dataSource.setMaxActive(maxActive);
dataSource.setMaxWait(maxWait);
dataSource.setDriverClassName(dbType.getDriver());
// 动态的参数
if (props != null && props.size() > 0) {
for (Map.Entry<Object, Object> entry : props.entrySet()) {
dataSource.addConnectionProperty(String.valueOf(entry.getKey()), String.valueOf(entry.getValue()));
}
}
if (dbType.isOracle()) {
dataSource.addConnectionProperty("restrictGetTables", "true");
dataSource.addConnectionProperty("oracle.jdbc.V8Compatible", "true");
dataSource.setValidationQuery("select 1 from dual");
dataSource.setExceptionSorter("com.alibaba.druid.pool.vendor.OracleExceptionSorter");
} else if (dbType.isMysql() || dbType.isDRDS()) {
dataSource.addConnectionProperty("useServerPrepStmts", "false");
dataSource.addConnectionProperty("rewriteBatchedStatements", "true");
dataSource.addConnectionProperty("allowMultiQueries", "true");
dataSource.addConnectionProperty("readOnlyPropagatesToServer", "false");
dataSource.setValidationQuery("select 1");
dataSource.setExceptionSorter("com.alibaba.druid.pool.vendor.MySqlExceptionSorter");
dataSource.setValidConnectionCheckerClassName("com.alibaba.druid.pool.vendor.MySqlValidConnectionChecker");
} else {
logger.error("Unknow database type");
}
return dataSource;
} catch (Throwable e) {
throw new YuGongException("create dataSource error!", e);
}
}
public void setMaxWait(int maxWait) {
this.maxWait = maxWait;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public void setInitialSize(int initialSize) {
this.initialSize = initialSize;
}
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
}