项目启动时没有初始化数据源,只根据用户请求的域名(IP地址)获取数据库配置(域名和配置文件中的数据库连接信息之间的映射关系),然后动态创建数据源并访问相应的数据库 .
现在,我们如何为这100多个数据源添加事务管理?
- 部分是与数据源相关的配置(和许多)application.yml .
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
filters: stat
maxActive: 5
initialSize: 1
maxWait: 60000
minIdle: 1
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: select 'x'
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
maxOpenPreparedStatements: 20
#*****user-host(ip) -数据库参数*****
192.168.3.187-8081:
name: test
url: jdbc:mysql://192.168.1.70/test7086?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true
username: root
password: 123456
192.168.1.70-9090:
name: test
url: jdbc:mysql://localhost:3306/kist_import_02?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
username: root
password: 123456
192.168.1.70-86:
name: test
url: jdbc:mysql://192.168.1.70:3306/test7086?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
username: root
password: 123456
192.168.1.70-88:
name: test
url: jdbc:mysql://192.168.1.70:3306/test7088?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
username: root
password: 123456
192.168.3.88:
name: test
url: jdbc:mysql://192.168.3.88:3306/import_test?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
username: root
password: 123456
- 数据源创建类
包com.kismart.common.dbs;
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component;
import javax.sql.DataSource; import java.sql.SQLException; import java.util.concurrent.ConcurrentHashMap;
@Component公共类DruidDataSource {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired private Environment env;
//保存创建的dts public static ConcurrentHashMap dsmap = new ConcurrentHashMap();
/ **
-
@param host客户请求主机域名
-
@return * / public DataSource getDataSource(String host){if(dsmap.get(host)!= null){return dsmap.get(host); com.alibaba.druid.pool.DruidDataSource datasource = new com.alibaba.druid.pool.DruidDataSource(); datasource.setUrl(env.getProperty("spring.datasource." host ".url")); datasource.setUsername(env.getProperty("spring.datasource." host ".username")); datasource.setPassword(env.getProperty("spring.datasource." host ".password")); datasource.setDriverClassName(env.getProperty("spring.datasource.driverClassName")); datasource.setMaxActive(Integer.parseInt(env.getProperty("spring.datasource.maxActive"))); try {datasource.setFilters(env.getProperty("spring.datasource.filters")); } catch(SQLException e){logger.error("druid configuration initialization filter",e); } datasource.setConnectionProperties(env.getProperty("spring.datasource.connectionProperties")); datasource.setName(主机); dsmap.put(主机,数据源);返回数据源; }}
3.sqlsession工厂类
@Component
@MapperScan("com.test.dao.impl")
public class BuildSqlSessionFactory {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private Environment env;
@Autowired
private DruidDataSource druidDataSource;
/**
*
* @param host 客户机域名
* @return
* @throws Exception
*/
public SqlSessionFactory getSqlSessionFactory(String host) throws Exception {
SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
fb.setDataSource(druidDataSource.getDataSource(host));
fb.setTypeAliasesPackage(env.getProperty("mybatis.type-aliases-package"));
fb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(env.getProperty("mybatis.mapper-locations")));
return fb.getObject();
}
}
4.BaseDao数据库通用工具类
@Component
public class BaseDao <T>{
@Autowired
protected BuildSqlSessionFactory sqlSessionFactory;
/**
* 获取所有 无任何参数
* @param host
* @return
*/
public List<T> save(String host,List list){
int i= null;
SqlSession sqlSession = null;
try {
sqlSession = sqlSessionFactory.getSqlSessionFactory(host).openSession();
i = sqlSession.insert(this.getClass().getName()+".save",list);
} catch (Exception e) {
System.out.println("Error --- "+this.getClass().getName()+" -> save数据库异常 --- ");
e.printStackTrace();
}finally {
sqlSession.close();
}
return i;
}
}
5.controller方法(主机是客户请求的域名或IP地址,每个方法都有此参数,用于获取数据库对应的数据库连接) .
@Controller
@RequestMapping("/test")
public class TestController {
@Autowired
private TestService testService;
/**
* @param req
* @return
*/
@RequestMapping("/save")
@ResponseBody
public Map save(HttpServletRequest req){
String host = getHost(req); // host:192.168.1.12
try{
testService.save(host);
return SUCCESS();
}catch (Exception e){
return ERROR();
}
}
6.service
@Service("testService")
public class TestService {
@Autowired
private TestDaoImpl testDao;
public int save(String host){
List<Test> tests = new ArrayList();
Test test = new Test();
test.setId(1);
test.setName("Tom");
tests.add(test);
int r = testDao.save(host,tests);
return r;
}
}
- Dao界面
公共接口TestDao {}
- daoImpl
@Repository(“testDao”)公共类TestDaoImpl扩展BaseDao实现TestDao {// BaseDao已经设计好了常用的基本方法(增仓改查),}
该项目是一个标准的spring boot2.0项目 . 没有实体类Test.java和testMapper.xml . 原因是该实体有两个字段,而mapper是一个SQL .