SpringBoot -- 通过简单的修改配置修改连接的数据库
向导背景方案SpringBoot篇单数据源情况1.通过spring.profile.active控制2.通过指定的配置参数决定数据源多数据源情况Spring篇背景 项目要求,开发环境使用postgres数据库,给客户部署时使用oracle,而只需要修改一个配置来完成。方案对于单数据源,保证容器中只有一个DataSource。对于多数据源,保证需要灵活变化的那个DataSource容器...
背景
项目要求,开发环境使用postgres数据库,给客户部署时使用oracle,而只需要修改一个配置来完成。
方案
- 对于单数据源,保证容器中只有一个DataSource。
- 对于多数据源,保证需要灵活变化的那个DataSource容器中只存在一个。
- 项目中应该是一套Mapper接口,两套Mapper.xml。不同的Driver,扫对应包下的Mapper.xml
SpringBoot篇
Springboot架构下,我们可以通过@Configuration来手动配置数据源,实现方式如下:
单数据源情况
1.通过spring.profile.active控制
例:sit配置postgre,pro配置oracle,
使用@Configuration手动配置数据源,在配置sqlSessionFactory时根据DriverType来指定扫对应的包,下面是代码示例:
application-sit.yml配置postgre数据源:
datasource:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/pgsqltest
username: xx
password: xx
application-dev.yml配置oracle数据源:
datasource:
driver-class-name: oracle.jdbc.driver.OracleDriver
url: jdbc:oracle:thin:@//xx:xx/xx
username: xx
password: xx
数据源配置类代码如下:
@Configuration
@MapperScan(basePackages = "com.bigblue.mapper")
public class DataSourceConfig {
private static final String TYPE_ORACLE = "oracle";
private static final String TYPE_MYSQL = "mysql";
private static final String TYPE_POSTGRE = "postgre";
@Bean
@ConfigurationProperties(prefix = "datasource")
public DataSource dataSource() {
return new DruidDataSource();
}
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
String driverClassName = ((DruidDataSource) dataSource).getDriverClassName();
//根据具体的驱动类型,扫对应的包
String driverType = TYPE_MYSQL;
if(driverClassName.contains(TYPE_ORACLE)){
driverType = TYPE_ORACLE;
}else if(driverClassName.contains(TYPE_POSTGRE)) {
driverType = TYPE_POSTGRE;
}
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:/mapper/"+driverType+"/**/**Mapper.xml"));
return bean.getObject();
}
@Bean
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
可以看到指定读取的属性前缀是datasource下的属性,然后在创建sqlSessionFactory时,根据具体的DriverType来扫对应的包下xml,这个时候就可以根据spring.profile.active配置指定激活哪个环境了,如果激活sit环境,则就会注入postgre的datasource,并且扫/mapper/postgre/**/Mapper.xml相关的文件;如果激活了oracle环境,则会注入oracle的datasource,扫/mapper/oracle//**Mapper.xml相关的文件。
2.通过指定的配置参数决定数据源
一个环境中指定了2个数据源,但只用其中一个,根据配置来决定用哪个数据源
application-dev.yml配置如下:
datasource:
active: datasource.postgre
postgre:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/pgsqltest
username: xx
password: xx
oracle:
driver-class-name: oracle.jdbc.driver.OracleDriver
url: jdbc:oracle:thin:@//xx:xx/xx
username: xx
password: xx
数据源配置类代码如下:
@Configuration
@MapperScan(basePackages = "com.bigblue.mapper")
public class DataSourceConfig {
private static final String TYPE_ORACLE = "oracle";
private static final String TYPE_MYSQL = "mysql";
private static final String TYPE_POSTGRE = "postgre";
@Autowired
private ApplicationContext context;
@Bean
// @ConfigurationProperties(prefix = "datasource")
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
String activeDataSource = context.getEnvironment().getProperty("datasource.active");
if (StringUtils.isEmpty(activeDataSource)) {
//如果该配置为空,则读取默认配置,
configDataSource(dataSource, "datasource.driver-class-name",
"datasource.url", "datasource.username", "datasource.password");
} else {
//如果该配置不为空,读取该配置激活的数据源配置
configDataSource(dataSource, activeDataSource + ".driver-class-name",
activeDataSource + ".url", activeDataSource + ".username", activeDataSource + ".password");
}
return dataSource;
}
private void configDataSource(DruidDataSource dataSource, String driverConf, String urlConf, String nameConf, String passwdConf) {
dataSource.setDriverClassName(getProp(driverConf));
dataSource.setUrl(getProp(urlConf));
dataSource.setUsername(getProp(nameConf));
dataSource.setPassword(getProp(passwdConf));
}
private String getProp(String confName) {
return context.getEnvironment().getProperty(confName);
}
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
String driverClassName = ((DruidDataSource) dataSource).getDriverClassName();
//根据具体的驱动类型,扫对应的包
String driverType = TYPE_MYSQL;
if (driverClassName.contains(TYPE_ORACLE)) {
driverType = TYPE_ORACLE;
} else if (driverClassName.contains(TYPE_POSTGRE)) {
driverType = TYPE_POSTGRE;
}
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:/mapper/" + driverType + "/**/**Mapper.xml"));
return bean.getObject();
}
@Bean
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
可以看到,配置类仍然只有一个,目的是保证容器中只有一个DataSource。因为yml配置有两个datasource,但我们一个环境只激活一个,我们可以通过datasource.active这个属性来配置需要激活的数据源配置前缀。下面sqlSessionFactory的创建和上面的一样,都是根据DriverType来决定扫对应的xml。
多数据源情况
其实和单数据源是一样的,无非多出来的那个数据源,再用另外一个配置类把多出来这个数据源注入即可。
例:yml中配置如下,其中oracle2是第二个数据源,postgre和oracle1只会启用其中一个:
datasource:
active: datasource.postgre
postgre:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/pgsqltest
username: xx
password: xx
oracle1:
driver-class-name: oracle.jdbc.driver.OracleDriver
url: jdbc:oracle:thin:@//xx:xx/xx
username: xx
password: xx
oracle2:
driver-class-name: oracle.jdbc.driver.OracleDriver
url: jdbc:oracle:thin:@//xx:xx/xx
username: xx
password: xx
配置类需要两个,一个配置类注入oracle2,一个配置类注入postgre或oracle1,根据配置决定,代码如下:
Oracle2的配置类代码:
@Configuration
@MapperScan(basePackages = "com.bigblue.mapper.oracle2", sqlSessionFactoryRef = "oracle2SqlSessionFactory")
public class OracleDataSource {
@Bean(name = "oracle2DS")
@ConfigurationProperties(prefix = "datasource.oracle2")
public DataSource dataSource() {
return new DruidDataSource();
}
@Bean(name = "oracle2SqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("oracle2DS") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:/mapper/oracle2/**Mapper.xml"));
return bean.getObject();
}
@Bean(name = "oracle2TransactionManager")
public DataSourceTransactionManager transactionManager(@Qualifier("oracle2DS") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
可以看到该配置类将oracle2数据源注入,beanId是oracle2DS,并且扫描oracle2文件夹下mapper和xml,使用oracle2SqlSessionFactory。
postgre和oracle1切换配置类代码:
@Configuration
@MapperScan(basePackages = "com.bigblue.mapper.primary", sqlSessionFactoryRef = "primarySqlSessionFactory")
public class DataSourceConfig {
private static final String TYPE_ORACLE = "oracle";
private static final String TYPE_MYSQL = "mysql";
private static final String TYPE_POSTGRE = "postgre";
@Autowired
private ApplicationContext context;
@Bean(name = "primaryDS")
// @ConfigurationProperties(prefix = "datasource")
@Primary
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
String activeDataSource = context.getEnvironment().getProperty("datasource.active");
if (StringUtils.isEmpty(activeDataSource)) {
//如果该配置为空,则读取默认配置,
configDataSource(dataSource, "datasource.driver-class-name",
"datasource.url", "datasource.username", "datasource.password");
} else {
//如果该配置不为空,读取该配置激活的数据源配置
configDataSource(dataSource, activeDataSource + ".driver-class-name",
activeDataSource + ".url", activeDataSource + ".username", activeDataSource + ".password");
}
return dataSource;
}
private void configDataSource(DruidDataSource dataSource, String driverConf, String urlConf, String nameConf, String passwdConf) {
dataSource.setDriverClassName(getProp(driverConf));
dataSource.setUrl(getProp(urlConf));
dataSource.setUsername(getProp(nameConf));
dataSource.setPassword(getProp(passwdConf));
}
private String getProp(String confName) {
return context.getEnvironment().getProperty(confName);
}
@Bean(name = "primarySqlSessionFactory")
@Primary
public SqlSessionFactory sqlSessionFactory(@Qualifier("primaryDS") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
String driverClassName = ((DruidDataSource) dataSource).getDriverClassName();
//根据具体的驱动类型,扫对应的包
String driverType = TYPE_MYSQL;
if (driverClassName.contains(TYPE_ORACLE)) {
driverType = TYPE_ORACLE;
} else if (driverClassName.contains(TYPE_POSTGRE)) {
driverType = TYPE_POSTGRE;
}
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:/mapper/" + driverType + "/**/**Mapper.xml"));
return bean.getObject();
}
@Bean(name = "primaryTransactionManager")
@Primary
public DataSourceTransactionManager transactionManager(@Qualifier("primaryDS") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
Spring篇
Springboot其实就是通过注解和配置类取代了xml的配置方式,cfs的DataSource、SqlSessionFactory、TransctionManager都是通过xml方式配置的,已经是通过配置的方式来决定数据源了,这里就不再赘述了。
更多推荐
所有评论(0)