春季引导多数据源设置

huangapple 未分类评论42阅读模式
英文:

Spring Boot Multiple Datasource Set up

问题

以下是翻译好的部分:

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("来自第一个数据库");
        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("来自第一个数据库结束");
        return dataSource;
    }
    
    @Primary
    @Bean(name = "xyz")
    public DataSource secondDataSource() {
        System.out.println("来自第二个数据库");
        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("来自第二个数据库结束");
        return dataSource;
    }

    @Bean(name = "abc")
    public JdbcTemplate template(@Qualifier("abc") DataSource ds) {
        System.out.println("调用第一个数据库");
        return new JdbcTemplate(ds);
    }

    @Bean(name = "xyz")
    public JdbcTemplate template1(@Qualifier("xyz") DataSource ds) {
        System.out.println("调用第二个数据库");
        return new JdbcTemplate(ds);
    }
}
英文:

I am new with springboot i need to setup multiple database in my project i am using postgresql this is my properties file.

If i am running my application so whatever @primay annotation i am giving only that db i able to access but i need to access both db.

Note : if i am adding both db @primary annotation then getting postconstructor 0 something error. my query in if else block sometimes i need to access abc db and sometimes i need to access xyz db but whatever in springconfig i m keeping @primary only that db url i am getting

I tried making @primary both getting exception and i tried @configurationProperties adding in my springconfig file getting exception

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

i add in @springBootApplication SpringConfig class

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);
	}

}

答案1

得分: 0

你在访问第二个非主要数据库时可能需要使用 @Qualifier。

@Autowired
@Qualifier("abc") 
DataSource dataSource;
英文:

You might have to use @Qualifier while accessing second non primary db.

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

答案2

得分: 0

JdbcTemplate的bean名称**不应**与DataSource的bean名称相同。

这个简单的例子**无法**启动:

```java
// 在 Config.java 中
@Configuration
class Config {
  @Bean("a")
  public String a() {
    return "a";
  }

  @Bean("b")
  public String b() {
    return "b";
  }

  @Bean("c")
  public Integer c(@Qualifier("a") String a) {
    return a.length();
  }

  @Bean("d")
  public Integer d(@Qualifier("b") String b) {
    return b.length();
  }
}

// 在 Comp.java 中
@Component
public static class Comp {
  private final String s;
  private final Integer i;

  public Comp(@Qualifier("c") String s, @Qualifier("d") 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}")来代替。


<details>
<summary>英文:</summary>

The JdbcTemplate beans should **NOT** have the same names as the DataSource Beans.

This simple example **DOES NOT** boot: 

// 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);
}
}


**Because your config is the same as the above, it will NOT boot either!**

**HOW TO FIX IT:**

In the above example, if you change the names &quot;a&quot; and &quot;b&quot; on the `Integer` beans to &quot;c&quot; and &quot;d&quot;, and change the qualifier value in the `Comp` constructor accordingly, it works fine.

p.s. I don&#39;t recommend ever using the `Environment` bean to grab your config values; personally I use `@Value(&quot;${the.key}&quot;)` instead.

</details>



huangapple
  • 本文由 发表于 2020年7月24日 10:15:16
  • 转载请务必保留本文链接:https://java.coder-hub.com/63065774.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定