由于项目前期业务设计的原因,不同CP的数据放置在了同一个ip和端口的mongdb中,6个CP数据在同一个ip和端口下,但是数据库的名称、集合的名称各不相同。
现在需要一个查询系统,根据选择不同的cp去查询不同的database和集合拿到需要展现的数据
解决思路:
将不同cp对应的数据库的名称和集合的名称存放在mysql中的一张表里(db_info),初始化时将db_info中取出所有的mongodb数据库信息,将其初始化添加到动态数据源中。将数据源添加到map中,key为cp,value为mongdb数据源
mysql中创建db_info表
CREATE TABLE `db_info` (
`id` varchar(32) NOT NULL DEFAULT '' COMMENT 'cp英文名称',
`db_name` varchar(50) DEFAULT NULL COMMENT 'database名称',
`name` varchar(50) DEFAULT NULL COMMENT 'cp名称',
`order_name` varchar(50) DEFAULT NULL COMMENT '前台展示信息',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
在config.properties中配置mysql数据源和mongndb的ip和端口
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/epay?useUnicode=true&characterEncoding=utf8
jdbc.username=test
jdbc.password=test1
mongodb.host=192.168.162.130
mongodb.port=27019
applicationContent.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mybatis="http://www.mybatis.org/schema/mybatis"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:property-placeholder location="classpath:config.properties" />
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource"
destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="idleConnectionTestPeriod" value="0" />
<property name="idleMaxAge" value="240" />
<property name="maxConnectionsPerPartition" value="4" />
<property name="minConnectionsPerPartition" value="2" />
<property name="partitionCount" value="1" />
<property name="acquireIncrement" value="5" />
<property name="statementsCacheSize" value="100" />
<property name="releaseHelperThreads" value="3" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="net.th2w.web.epay.system.mapper" />
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
application-mongodb.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="mongoOptions" class="org.springframework.data.mongodb.core.MongoClientOptionsFactoryBean">
<property name="connectionsPerHost" value="8"></property>
<property name="threadsAllowedToBlockForConnectionMultiplier" value="4"></property>
<property name="connectTimeout" value="1000"></property>
<property name="maxWaitTime" value="1500"></property>
<property name="socketKeepAlive" value="true"></property>
<property name="socketTimeout" value="1500"></property>
</bean>
<bean id="mongo" class="org.springframework.data.mongodb.core.MongoClientFactoryBean">
<property name="mongoClientOptions" ref="mongoOptions"></property>
<property name="host" value="${mongodb.host}"></property>
<property name="port" value="${mongodb.port}"></property>
</bean>
<bean id="mongoTemplateManager" class="net.th2w.web.epay.system.datasource.DynamicDataSourceManager" init-method="init">
</bean>
</beans>
DynamicDataSourceManager.java
/**
* 动态数据源
* @author sermo
*
*/
public class DynamicDataSourceManager {
public Logger logger = LoggerFactory.getLogger(DynamicDataSourceManager.class);
private @Resource DbInfoService service;
private @Resource Mongo mongo;
private Map<String, MongoTemplate> map = new HashMap<>();
public void init() throws Exception{
logger.info("-------------->开始初始化加载创建动态数据源...");
List<DbInfo> list = service.findAll();
for (DbInfo dbInfo : list) {
createMongoTemplatePool(dbInfo);
}
logger.info("-------------->初始化加载创建动态数据源完毕,加载数:{}", list.size());
}
/**
* 创建数据源连接池
* @param sermo
*/
private void createMongoTemplatePool(DbInfo dbInfo) {
MongoTemplate template = new MongoTemplate(mongo, dbInfo.getDbName());
this.map.put(dbInfo.getId(), template);
}
/**
* 获取数据源
* @param templateId
* @return
* @throws Exception
*/
public MongoTemplate getMongoTemplate(String templateId) throws Exception{
MongoTemplate template = this.map.get(templateId);
if (template == null) {
logger.info("未找到[templateID={}]对应的数据源,则从数据库重新获取...", templateId);
DbInfo dbInfo = service.findById(templateId);
if (dbInfo == null) {
logger.info("从数据库重新获取,未找到[templateID={}]对应的数据源", templateId);
throw new Exception("未获取到匹配的动态数据源[ID="+templateId+"]");
}else{
createMongoTemplatePool(dbInfo);
template = this.map.get(templateId);
}
}else{
logger.info("已找到[templateID={}]对应的数据源!", templateId);
}
return template;
}
}
mongodb实现类 MongoDaoImpl.java
public class MongoDaoImpl<T> implements MongoDao<T> {
@Qualifier(value="mongoTemplateManager")
protected @Resource DynamicDataSourceManager dataSourceManager;
protected MongoTemplate template;
protected EntityMsg<T> entityMsg;
@SuppressWarnings("unchecked")
public MongoDaoImpl() {
this.entityMsg = new EntityMsg<T>((Class<T>) ReflectUtil.getSuperClassGenricType(this.getClass()));
}
@Override
public T findOne(Criteria criteria, String collectionName, String database) {
try {
template = dataSourceManager.getMongoTemplate(database);
return template.findOne(new Query(criteria), this.entityMsg.getClazz(), collectionName);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}