package com.zcxk.meterreadingsystemv2.dbs; import com.alibaba.druid.pool.DruidDataSource; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.boot.autoconfigure.MybatisProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import javax.sql.DataSource; import java.util.HashMap; import java.util.Map; /** * 数据源配置类,在tomcat启动时触发,在该类中生成多个数据源实例并将其注入到 ApplicationContext 中 */ @Slf4j @Configuration @EnableConfigurationProperties(MybatisProperties.class) public class DataSourceConfigurer { //自动注入环境类,用于获取配置文件的属性值 @Autowired private Environment evn; private MybatisProperties mybatisProperties; public DataSourceConfigurer(MybatisProperties properties) { this.mybatisProperties = properties; } /** * 创建数据源对象 * @param dbType 数据库类型 * @return data source */ private DruidDataSource createDataSource(String dbType) { //如果不指定数据库类型,则使用默认数据库连接 String dbName = dbType.trim().isEmpty() ? "default" : dbType.trim(); DruidDataSource dataSource = new DruidDataSource(); String prefix = "db." + dbName +"."; log.info("初始化数据库 dbName = {}",dbName ); dataSource.setUrl(evn.getProperty( prefix + "url")); dataSource.setUsername(evn.getProperty( prefix + "username")); dataSource.setPassword(evn.getProperty( prefix + "password")); dataSource.setDriverClassName(evn.getProperty( prefix + "driver-class-name")); dataSource.setDbType(evn.getProperty( prefix + "type")); dataSource.setConnectionErrorRetryAttempts(1); dataSource.setBreakAfterAcquireFailure(true); // 请求失败之后中断 dataSource.setMaxWait(5000);//请求失败后等待时间 return dataSource; } /** * spring boot 启动后将自定义创建好的数据源对象放到TargetDataSources中用于后续的切换数据源用 * (比如:DynamicDataSourceContextHolder.setDataSourceKey("dbMall"),手动切换到dbMall数据源 * 同时指定默认数据源连接 * @return 动态数据源对象 */ @Bean public DynamicDataSource dynamicDataSource() { //获取动态数据库的实例(单例方式) DynamicDataSource dynamicDataSource = DynamicDataSource.getInstance(); //创建兴平数据库连接对象 DruidDataSource xingpingDataSource = createDataSource("xingping"); //创建新蒲新区数据库连接对象 DruidDataSource xpDataSource = createDataSource("xp"); //创建萝北数据库连接对象 DruidDataSource lbDataSource = createDataSource("lb"); //创建绥滨数据库连接对象 DruidDataSource suibinDataSource = createDataSource("suibin"); //创建同江数据库连接对象 //DruidDataSource tongjiangDataSource = createDataSource("tongjiang"); //创建绥滨数据库连接对象 DruidDataSource jlDataSource = createDataSource("jl"); //创建绥阳数据库连接对象 DruidDataSource suiyangDataSource = createDataSource("suiyang"); //创建巴里坤数据库连接对象 //DruidDataSource balikunDataSource = createDataSource("balikun"); //创建泾阳数据库连接对象 //DruidDataSource jingyangDataSource = createDataSource("jingyang"); //创建泾阳数据库连接对象 //DruidDataSource huichuanDataSource = createDataSource("huichuan"); //创建通用数据库连接对象 DruidDataSource commonDataSource = createDataSource("common"); //创建物联网云平台数据库连接对象 DruidDataSource smartCityDataSource = createDataSource("smart-city"); Map map = new HashMap<>(); //自定义数据源key值,将创建好的数据源对象,赋值到targetDataSources中,用于切换数据源时指定对应key即可切换 map.put("xingping", xingpingDataSource); map.put("xp", xpDataSource); map.put("lb", lbDataSource); map.put("suibin", suibinDataSource); //map.put("tongjiang", tongjiangDataSource); map.put("suiyang", suiyangDataSource); //map.put("balikun", balikunDataSource); //map.put("jingyang", jingyangDataSource); //map.put("huichuan", huichuanDataSource); map.put("common", commonDataSource); map.put("jl", jlDataSource); map.put("smart-city", smartCityDataSource); dynamicDataSource.setTargetDataSources(map); //设置默认数据源 dynamicDataSource.setDefaultTargetDataSource(smartCityDataSource); return dynamicDataSource; } /** * 配置mybatis的sqlSession连接动态数据源 * @param dynamicDataSource * @return * @throws Exception */ @Bean public SqlSessionFactory sqlSessionFactory( @Qualifier("dynamicDataSource") DataSource dynamicDataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dynamicDataSource); bean.setMapperLocations(mybatisProperties.resolveMapperLocations()); bean.setTypeAliasesPackage(mybatisProperties.getTypeAliasesPackage()); bean.setConfiguration(mybatisProperties.getConfiguration()); return bean.getObject(); } @Bean(name = "sqlSessionTemplate") public SqlSessionTemplate sqlSessionTemplate( @Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } /** * 将动态数据源添加到事务管理器中,并生成新的bean * @return the platform transaction manager */ @Bean public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dynamicDataSource()); } }