package com.xxx.xxxxxx.DynamicData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import com.alibaba.druid.pool.DruidDataSource;
import com.xxx.xxxxxx.Dao.DynamicDataSourceDao;
import com.xxx.xxxxxx.entity.DynamicDataSource;
import com.xxx.xxxxxx.Dao.DynamicDataSourceDao;
import com.xxx.xxxxxx.entity.DynamicDataSource;
@Component
public class DynamicDataSourceManager
{
private static final Logger logger = LoggerFactory.getLogger(DynamicDataSourceManager.class);
private Map<Long, DruidDataSource> dataSourcePoolMap = new HashMap<Long, DruidDataSource>();
@Autowired
private DynamicDataSourceDao dynamicDataSourceDao;
/**
* 初始化加载创建数据源连接池
*/
public void init()
{
logger.info("-------------->开始初始化加载创建动态数据源...");
//获取所有数据源配置信息
List<DynamicDataSource> dataSourceList = dynamicDataSourceDao.findAll();
for(DynamicDataSource adminDataSource : dataSourceList)
{
createDataSourcePool(adminDataSource);
}
logger.info("-------------->初始化加载创建动态数据源完毕,加载数:"+dataSourceList.size());
}
/**
* 创建数据源连接池
* @param adminDataSource
*/
public void createDataSourcePool(DynamicDataSource adminDataSource)
{
DruidDataSource druidDataSource = new DruidDataSource();
public class DynamicDataSourceManager
{
private static final Logger logger = LoggerFactory.getLogger(DynamicDataSourceManager.class);
private Map<Long, DruidDataSource> dataSourcePoolMap = new HashMap<Long, DruidDataSource>();
@Autowired
private DynamicDataSourceDao dynamicDataSourceDao;
/**
* 初始化加载创建数据源连接池
*/
public void init()
{
logger.info("-------------->开始初始化加载创建动态数据源...");
//获取所有数据源配置信息
List<DynamicDataSource> dataSourceList = dynamicDataSourceDao.findAll();
for(DynamicDataSource adminDataSource : dataSourceList)
{
createDataSourcePool(adminDataSource);
}
logger.info("-------------->初始化加载创建动态数据源完毕,加载数:"+dataSourceList.size());
}
/**
* 创建数据源连接池
* @param adminDataSource
*/
public void createDataSourcePool(DynamicDataSource adminDataSource)
{
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(adminDataSource.getDriverclassname());
String jdbcUrl=adminDataSource.getJdbcUrl();
/*********Mysql 批量插入加速处理************/
if(jdbcUrl.indexOf("mysql")>0 && jdbcUrl.indexOf("rewriteBatchedStatements") <0)
{
jdbcUrl=jdbcUrl+"&rewriteBatchedStatements=true";
}
druidDataSource.setUrl(jdbcUrl);
druidDataSource.setUsername(adminDataSource.getUserName());
druidDataSource.setPassword(adminDataSource.getPassword());
/* <!-- 配置初始化大小、最小、最大 --> */
druidDataSource.setInitialSize(3);
druidDataSource.setMinIdle(1);
druidDataSource.setMaxActive(5);
/* <!-- 配置获取连接等待超时的时间 --> */
druidDataSource.setMaxWait(60000);
/* <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> */
druidDataSource.setTimeBetweenEvictionRunsMillis(300000);
druidDataSource.setValidationQuery("SELECT 'x'");
druidDataSource.setTestWhileIdle(true);
druidDataSource.setTestOnReturn(false);
druidDataSource.setTestOnBorrow(false);
druidDataSource.setPoolPreparedStatements(true);
druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(20);
druidDataSource.setUseGlobalDataSourceStat(true);
try
{
druidDataSource.setFilters("stat");
}
catch (SQLException e)
{
logger.error("创建数据源异常:{}",ExceptionUtils.getFullStackTrace(e));
}
this.dataSourcePoolMap.put(adminDataSource.getId(), druidDataSource);
}
/**
* 获取数据源
* @param sourceId
* @return
*/
public JdbcTemplate getDataSourcePoolBySourceID(Long source_id) throws Exception
{
DruidDataSource druidDataSource = this.dataSourcePoolMap.get(source_id);
if(druidDataSource == null)
{
logger.info(String.format("未找到[SourceID=%d]对应的数据源,从数据库重新获取...", source_id));
//未获取到相应的数据源,则从数据库重新获取,来创建新的数据源连接池
DynamicDataSource adminDataSource = dynamicDataSourceDao.findOne(source_id);
if(adminDataSource == null)
{
logger.info(String.format("从数据库重新获取,未找到[SourceID=%d]对应的数据源", source_id));
throw new Exception("未获取到匹配的动态数据源[ID="+source_id+"]");
}
else if(adminDataSource.getSourceState() != 1)
{
logger.info(String.format("[SourceID=%d]对应的数据源状态未开启", source_id));
throw new Exception("匹配的动态数据源状态未开启[ID="+source_id+"]");
}
else
{
createDataSourcePool(adminDataSource);
druidDataSource = this.dataSourcePoolMap.get(source_id);
}
}
String jdbcUrl=adminDataSource.getJdbcUrl();
/*********Mysql 批量插入加速处理************/
if(jdbcUrl.indexOf("mysql")>0 && jdbcUrl.indexOf("rewriteBatchedStatements") <0)
{
jdbcUrl=jdbcUrl+"&rewriteBatchedStatements=true";
}
druidDataSource.setUrl(jdbcUrl);
druidDataSource.setUsername(adminDataSource.getUserName());
druidDataSource.setPassword(adminDataSource.getPassword());
/* <!-- 配置初始化大小、最小、最大 --> */
druidDataSource.setInitialSize(3);
druidDataSource.setMinIdle(1);
druidDataSource.setMaxActive(5);
/* <!-- 配置获取连接等待超时的时间 --> */
druidDataSource.setMaxWait(60000);
/* <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> */
druidDataSource.setTimeBetweenEvictionRunsMillis(300000);
druidDataSource.setValidationQuery("SELECT 'x'");
druidDataSource.setTestWhileIdle(true);
druidDataSource.setTestOnReturn(false);
druidDataSource.setTestOnBorrow(false);
druidDataSource.setPoolPreparedStatements(true);
druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(20);
druidDataSource.setUseGlobalDataSourceStat(true);
try
{
druidDataSource.setFilters("stat");
}
catch (SQLException e)
{
logger.error("创建数据源异常:{}",ExceptionUtils.getFullStackTrace(e));
}
this.dataSourcePoolMap.put(adminDataSource.getId(), druidDataSource);
}
/**
* 获取数据源
* @param sourceId
* @return
*/
public JdbcTemplate getDataSourcePoolBySourceID(Long source_id) throws Exception
{
DruidDataSource druidDataSource = this.dataSourcePoolMap.get(source_id);
if(druidDataSource == null)
{
logger.info(String.format("未找到[SourceID=%d]对应的数据源,从数据库重新获取...", source_id));
//未获取到相应的数据源,则从数据库重新获取,来创建新的数据源连接池
DynamicDataSource adminDataSource = dynamicDataSourceDao.findOne(source_id);
if(adminDataSource == null)
{
logger.info(String.format("从数据库重新获取,未找到[SourceID=%d]对应的数据源", source_id));
throw new Exception("未获取到匹配的动态数据源[ID="+source_id+"]");
}
else if(adminDataSource.getSourceState() != 1)
{
logger.info(String.format("[SourceID=%d]对应的数据源状态未开启", source_id));
throw new Exception("匹配的动态数据源状态未开启[ID="+source_id+"]");
}
else
{
createDataSourcePool(adminDataSource);
druidDataSource = this.dataSourcePoolMap.get(source_id);
}
}
JdbcTemplate jdbcTempleDynamic = new JdbcTemplate(druidDataSource);
return jdbcTempleDynamic;
}
/**
* 关闭所有数据源连接池
*/
public void close()
{
Set<Long> key = dataSourcePoolMap.keySet();
for (Iterator<Long> it = key.iterator(); it.hasNext();)
{
DruidDataSource druidDataSource = dataSourcePoolMap.get(it.next());
try
{
druidDataSource.close();
}
catch (Exception e)
{
logger.error("关闭连接池异常:comboPooledDataSource="+ToStringBuilder.reflectionToString(druidDataSource));
}
}
}
}
return jdbcTempleDynamic;
}
/**
* 关闭所有数据源连接池
*/
public void close()
{
Set<Long> key = dataSourcePoolMap.keySet();
for (Iterator<Long> it = key.iterator(); it.hasNext();)
{
DruidDataSource druidDataSource = dataSourcePoolMap.get(it.next());
try
{
druidDataSource.close();
}
catch (Exception e)
{
logger.error("关闭连接池异常:comboPooledDataSource="+ToStringBuilder.reflectionToString(druidDataSource));
}
}
}
}