SpringBoot -- 通过简单的修改配置修改连接的数据库

背景

  项目要求,开发环境使用postgres数据库,给客户部署时使用oracle,而只需要修改一个配置来完成。

方案

  1. 对于单数据源,保证容器中只有一个DataSource。
  2. 对于多数据源,保证需要灵活变化的那个DataSource容器中只存在一个。
  3. 项目中应该是一套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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot是一个用于简化Spring应用开发的框架,而Druid是一个高效的数据库连接池。在Spring Boot项目中使用Druid连接池可以提供高性能的数据库连接管理和监控功能。 要在Spring Boot中使用Druid连接池,需要以下步骤: 1. 在项目的pom.xml文件中添加Druid依赖: ```xml <dependencies> <!-- Spring Boot Starter JDBC --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!-- Druid依赖 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.6</version> </dependency> </dependencies> ``` 2. 在application.properties或application.yml文件中配置Druid连接池相关属性,例如: ```properties spring.datasource.url=jdbc:mysql://localhost:3306/mydb spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver # Druid连接配置 spring.datasource.druid.initial-size=5 spring.datasource.druid.min-idle=5 spring.datasource.druid.max-active=20 spring.datasource.druid.max-wait=60000 spring.datasource.druid.time-between-eviction-runs-millis=60000 spring.datasource.druid.min-evictable-idle-time-millis=300000 spring.datasource.druid.validation-query=SELECT 1 spring.datasource.druid.test-while-idle=true spring.datasource.druid.test-on-borrow=false spring.datasource.druid.test-on-return=false spring.datasource.druid.filters=stat spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20 spring.datasource.druid.use-global-data-source-stat=true ``` 3. 在启动类上添加`@EnableTransactionManagement`和`@MapperScan`注解,例如: ```java @SpringBootApplication @EnableTransactionManagement @MapperScan("com.example.mapper") public class MyApp { public static void main(String[] args) { SpringApplication.run(MyApp.class, args); } } ``` 以上是在Spring Boot项目中使用Druid连接池的基本配置步骤,你可以根据自己的需求修改配置参数来满足具体业务场景。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值