【springboot】动态数据库配置

默认配置

在Spring Boot应用程序中,如果在类路径下存在某个数据库依赖(例如MySQL),则必须提供相应的数据源信息,否则应用程序将无法启动。

  • 如果想要在不配置数据源的情况下启动应用程序,可以参照下面的做法修改主类配置
//告诉Spring Boot在启动应用程序时,不自动配置数据源。
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
public class MyApplication{
    public static void main(String[] args){
        SpringApplication.run(MyApplication.class,args);
    }
}

动态数据源切换方法

  1. 在启动程序中,添加上述exclude配置,使程序在没有配置数据源的时候也能启动
  2. 当系统初始化后,会向类路径下写入install.back文件
  3. 创建一个InstallUtils工具类并提供一个返回类型为布尔值isInstall()方法,该方法用于判断install.back文件是否存在
public class InstallUtils {
    public static Boolean isInstall() {
        String installFile = InstallUtils.class.getResource("/").getPath()+"/install.back";
        File file = new File(installFile);
        return file.exists();
    }
}
  1. 使用@ConfigurationProperties注解和@Value注解将.properties或.yml配置文件中的属性绑定到Java对象
    使用java bean 注入yaml中的配置
@Configuration
public class DruidProperty {
 
    @Value( "${spring.datasource.druid.initialSize}" )
    private int initialSize;
 
    @Value ( "${spring.datasource.druid.minIdle}" )
    private int minIdle;
 
    @Value ( "${spring.datasource.druid.maxActive}" )
    private int maxActive;
 
    @Value("${spring.datasource.druid.maxWait}")
    private int maxWait;
 
    @Value ( "${spring.datasource.druid.timeBetweenEvictionRunsMillis}" )
    private int timeBetweenEvictionRunsMillis;
 
    @Value("${spring.datasource.druid.minEvictableIdleTimeMillis}")
    private int minEvictableIdleTimeMillis;
 
    @Value("${spring.datasource.druid.maxEvictableIdleTimeMillis}")
    private int maxEvictableIdleTimeMillis;
 
    @Value("${spring.datasource.druid.validationQuery}")
    private String validationQuery;
 
    @Value("${spring.datasource.druid.testWhileIdle}")
    private boolean testWhileIdle;
 
    @Value("${spring.datasource.druid.testOnBorrow}")
    private boolean testOnBorrow;
 
    @Value("${spring.datasource.druid.testOnReturn}")
    private boolean testOnReturn;
 
    public DruidDataSource druidDataSource(DruidDataSource dataSource){
        dataSource.setInitialSize(initialSize);
        dataSource.setMaxActive(maxActive);
        dataSource.setMinIdle(minIdle);
        dataSource.setMaxWait(maxWait);
        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        dataSource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis);
        dataSource.setValidationQuery(validationQuery);
        dataSource.setTestWhileIdle(testWhileIdle);
        dataSource.setTestOnBorrow(testOnBorrow);
        dataSource.setTestOnReturn(testOnReturn);
        try {
            dataSource.addFilters("stat,wall");
        } catch (SQLException e) {
            e.printStackTrace();
        }
 
        return dataSource;
    }
 
}
  1. 想要实现动态数据源,只需要自定义一个数据源类并继承AbstractRoutingDataSource,然后覆盖determineCurrentLookupKey()即可
public class DynamicDataSource extends AbstractRoutingDataSource {
    //构造函数,用于设置默认的数据源和目标数据源
    public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object,Object>targetDataSource){
        super.setDefaultTargetDataSource(defaultTargetDataSource);
        super.setTargetDataSources(targetDataSource);
        super.afterPropertiesSet();
    }
 
    //覆盖determineCurrentLookupKey()
    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceHolder.getDatasource();
    }

6.注入自定义数据源

  • H2数据源是应用的默认数据源,在管理员第一次访问后台或未初始化系统前,都将使用此数据源
@Bean
@ConfigurationProperties(prefix = "spring.datasource.druid.h2")
//前缀为“spring.datasource.druid.h2”的配置属性绑定到DruidDataSource的成员变量上。
public DataSource h2DataSource(DruidProperty druidProperty){ //DruidProperty类已经使用@Value注解对其成员变量进行绑定,在此可以直接使用
    DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
    return druidProperty.druidDataSource(dataSource);
}
  • 当管理员初始化后台数据后才配置此数据源
  • 要实现这样的一种设置,可以借助SpringBoot的@ConditionalOnResource注解来实现。
    @ConditionalOnResource注解的原理是当存在某个资源文件时才注册当前的Bean到SpringBoot中
    此外,还需要将从前端获取到的数据库连接,用户名和密码手动设置到DruidDataSource上(前端提交的数据库信息被存放到mysql.properties文件中)
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.druid.mysql")
    @ConditionalOnResource(resources = "classpath:install.back")
    public DataSource mysqlDataSource(DruidProperty druidProperty){
        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
        Properties properties = PropertiesUtils.getProperties("mysql.properties");
        dataSource.setUrl(properties.getProperty("url"));
        dataSource.setUsername(properties.getProperty("username"));
        dataSource.setPassword(properties.getProperty("password"));
        return druidProperty.druidDataSource(dataSource);
    }
  1. 配置动态数据源
    新建一个自定义数据源,使用@Primary注解指定该数据源是主数据源,H2数据源和MySQL数据源的切换将由此数据源完成
    @Bean(name = "dynamicDataSource")
    @Primary
    public DynamicDataSource dynamicDataSource(DataSource h2DataSource,DataSource mysqlDataSource){
        Map<Object,Object> targetDataSource = new HashMap<>(2);
        targetDataSource.put(DataBaseType.H2.name(),h2DataSource);
        targetDataSource.put(DataBaseType.MYSQL.name(),mysqlDataSource);
        if(InstallUtils.isInstall()){
            return new DynamicDataSource(mysqlDataSource,targetDataSource);
        }else{
            return new DynamicDataSource(h2DataSource,targetDataSource);
        }
    }

参考链接:https://blog.csdn.net/tianshan2010/article/details/103941369

posted @ 2023-02-22 14:21  xiaoyu_jane  阅读(763)  评论(0编辑  收藏  举报