【问题标题】:Spring Boot Multiple Datasource Set upSpring Boot 多数据源设置
【发布时间】:2020-07-24 02:15:16
【问题描述】:

我是 springboot 新手,我需要在我的项目中设置多个数据库我正在使用 postgresql 这是我的属性文件。

如果我正在运行我的应用程序,那么无论@primay 注释我只提供我能够访问的数据库,但我需要同时访问这两个数据库。

注意:如果我同时添加了 db @primary 注释,那么会出现 postconstructor 0 错误。我在 if else 块中的查询有时我需要访问 abc db 有时我需要访问 xyz db 但是在 springconfig 中我只保留@primary 我得到的那个 db url

我尝试让@primary 都获得异常,并尝试在我的 springconfig 文件中添加@configurationProperties 获得异常

spring.datasource1.url=jdbc:postgresql://100.17.13.26:123/abc
spring.datasource1.username=ENC(vAIVaqTTZ89eYBWBDbUxgGdhciXm3GuB)
spring.datasource1.password=ENC(abZypzjEuvLfbovYs0oGdeRnUqM8e+k1)
spring.datasource1.driver-class-name=org.postgresql.Driver

spring.datasource2.url=jdbc:postgresql://100.17.13.26:123/xyz
spring.datasource2.username=ENC(vAIVaqTTZ89eYBWBDbUxgGdhciXm3GuB)
spring.datasource2.password=ENC(abZypzjEuvLfbovYs0oGdeRnUqM8e+k1)
spring.datasource2.driver-class-name=org.postgresql.Driver

我添加了@springBootApplication SpringConfig 类

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

@Configuration
public class SpringConfiguration {
    @Autowired
    private Environment env;

    
    @Bean(name = "abc")
    public DataSource firstDataSource() {
        System.out.println("from first DB");
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(env.getProperty("spring.datasource1.driver-class-name"));
        dataSource.setUrl(env.getProperty("spring.datasource1.url"));
        dataSource.setUsername(env.getProperty("spring.datasource1.username"));
        dataSource.setPassword(env.getProperty("spring.datasource1.password"));
        System.out.println("from first DB end");
        return dataSource;
    }
    @Primary
    @Bean(name = "xyz")
    public DataSource secondDataSource() {
        System.out.println("from second DB");
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(env.getProperty("spring.datasource2.driver-class-name"));
        dataSource.setUrl(env.getProperty("spring.datasource2.url"));
        dataSource.setUsername(env.getProperty("spring.datasource2.username"));
        dataSource.setPassword(env.getProperty("spring.datasource2.password"));
        System.out.println("from second DB end");
        return dataSource;
    }

    @Bean(name = "abc")
    public JdbcTemplate template(@Qualifier("abc") DataSource ds) {
        System.out.println("calling first db");
        return new JdbcTemplate(ds);
    }

    @Bean(name = "xyz")
    public JdbcTemplate template1(@Qualifier("xyz") DataSource ds) {
        System.out.println("calling second db");
        return new JdbcTemplate(ds);
    }

}

【问题讨论】:

    标签: java spring postgresql spring-boot


    【解决方案1】:

    在访问第二个非主数据库时,您可能必须使用 @Qualifier。

    @Autowired
    @Qualifier("abc") 
    DataSource dataSource;
    

    【讨论】:

    • 感谢我使用的回复,我仍然得到@primary db url而不是第二个
    【解决方案2】:

    JdbcTemplate bean 应该与 DataSource bean 具有相同的名称。

    这个简单的例子不能启动:

    // In Config.java
    @Configuration
    class Config{
      @Bean("a")
      public String a() {
        return "a";
      }
    
      @Bean("b")
      public String b() {
        return "b";
      }
    
      @Bean("a")
      public Integer c(@Qualifier("a") String a) {
        return a.length();
      }
    
      @Bean("b")
      public Integer d(@Qualifier("b") String b) {
        return b.length();
      }
    }
    
    // In Comp.java
    @Component
    public static class Comp {
      private final String s;
      private final Integer i;
    
      public Comp(@Qualifier("a") String s, @Qualifier("b") Integer i) {
    
        this.s = s;
        this.i = i;
      }
    
      @EventListener(ApplicationReadyEvent.class)
      public void ok() {
        System.out.println(s);
        System.out.println(i);
      }
    }
    

    因为你的配置和上面一样,它也不会启动!

    如何解决:

    在上面的示例中,如果将 Integer bean 上的名称“a”和“b”更改为“c”和“d”,并相应地更改 Comp 构造函数中的限定符值,它可以工作很好。

    附言我不建议使用 Environment bean 来获取您的配置值;我个人改用@Value("${the.key}")

    【讨论】:

    • 感谢您的回复,但我使用的是相同的,我将 SpringConfiguration 类的代码放在这里。
    • 请仔细阅读答案,如果我的建议还是不行,那就修改原问题让不同bean不共享名字
    • 如果它对您有帮助,那么您应该投票并接受答案。
    猜你喜欢
    • 2021-03-16
    • 1970-01-01
    • 2019-09-09
    • 2015-02-21
    • 1970-01-01
    • 2016-05-03
    • 1970-01-01
    • 2016-01-17
    • 2015-01-26
    相关资源
    最近更新 更多