spring 引导中的多个数据源 - jdbcTemplate 为空
multiple data source in spring boot - jdbcTemplate is null
我在 spring 引导项目中使用多个数据源,
application.properties
#first DB
integration.datasource.jdbc-url=jdbc:sqlserver://localhost:port1/my_sample_schema1
integration.datasource.username=username
integration.datasource.password=password
integration.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
integration.jpa.database-platform=org.hibernate.dialect.SQLServer2012Dialect
integration.jpa.show-sql=true
#second DB
spring.datasource.jdbc-url=jdbc:sqlserver://localhost:port2/my_sample_schema2
spring.datasource.username=username
spring.datasource.password=password
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.platform=org.hibernate.dialect.SQLServer2012Dialect
spring.jpa.show-sql=true
DBConfig.java
@Configuration
public class DBConfig {
@Primary
@Bean(name = "integrationDataSource")
@ConfigurationProperties(prefix = "integration.datasource")
public DataSource integrationDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "mainDataSource")
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource mainDataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Autowired
@Bean(name = "integrationJdbcTemplate")
public JdbcTemplate integrationJdbcTemplate(@Qualifier("integrationDataSource") DataSource integrationDataSource) {
return new JdbcTemplate(integrationDataSource);
}
@Bean(name ="mainJdbcTemplate")
@Autowired
public JdbcTemplate mainJdbcTemplate(@Qualifier("mainDataSource") DataSource mainDataSource) {
return new JdbcTemplate(mainDataSource);
}
}
SampleClass.java
@Slf4j
@Component
public class SampleClass{
@Autowired
private JdbcTemplate mainJdbcTemplate;
@Autowired
@Qualifier("integrationJdbcTemplate")
private static JdbcTemplate integrationTemplate;
public static final String SELECT_QUERY = "select * from tableA";
public List<SampleDto> getDBData(SampleDto fileData) {
List<SampleDto> data = null;
try {
data = integrationTemplate.query(
SampleClass.SELECT_QUERY, new Object[] { param1, param2 },
new SampleDataMapper());
} catch (DataAccessException e) {
log.error(e.getMessage(), e);
}
return data;
}
}
在 SampleClass.java 中,我将 integrationTemplate 作为 null 获取。为什么会这样? mainJdbcTemplate 正在运行。但是 integrationTemplate 变为 null 并且无法执行查询。
问题是您的 static
字段带有 @Autowired
With @Autowired
在构造 bean 之后立即注入字段,然后再调用任何配置方法。阅读 here 了解有关 Ioc 和 Bean 注入的更多信息。
删除 static
:
@Autowired
@Qualifier("integrationJdbcTemplate")
private JdbcTemplate integrationTemplate;
当然可以,但是不推荐:
private static JdbcTemplate integrationTemplate;
@Autowired
public void setIntegrationJdbcTemplate(JdbcTemplate integrationTemplate){
SampleClass.integrationTemplate = integrationTemplate;
}
按名称自动装配
如果您使用与用于 bean 初始化的名称完全相同的名称,则无需输入 @Qualifier
,只需使用 as:
@Autowired
private JdbcTemplate integrationJdbcTemplate;
那是因为 Spring 知道要注入哪个 bean。如果你有更多相同类型的 beans 那么它会抛出 NoUniqueBeanDefinitionException
然后你用 @Qualifier
.
定义它
我还建议将您的字段标记为 final
,以作为良好做法。
我在 spring 引导项目中使用多个数据源,
application.properties
#first DB
integration.datasource.jdbc-url=jdbc:sqlserver://localhost:port1/my_sample_schema1
integration.datasource.username=username
integration.datasource.password=password
integration.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
integration.jpa.database-platform=org.hibernate.dialect.SQLServer2012Dialect
integration.jpa.show-sql=true
#second DB
spring.datasource.jdbc-url=jdbc:sqlserver://localhost:port2/my_sample_schema2
spring.datasource.username=username
spring.datasource.password=password
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.platform=org.hibernate.dialect.SQLServer2012Dialect
spring.jpa.show-sql=true
DBConfig.java
@Configuration
public class DBConfig {
@Primary
@Bean(name = "integrationDataSource")
@ConfigurationProperties(prefix = "integration.datasource")
public DataSource integrationDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "mainDataSource")
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource mainDataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Autowired
@Bean(name = "integrationJdbcTemplate")
public JdbcTemplate integrationJdbcTemplate(@Qualifier("integrationDataSource") DataSource integrationDataSource) {
return new JdbcTemplate(integrationDataSource);
}
@Bean(name ="mainJdbcTemplate")
@Autowired
public JdbcTemplate mainJdbcTemplate(@Qualifier("mainDataSource") DataSource mainDataSource) {
return new JdbcTemplate(mainDataSource);
}
}
SampleClass.java
@Slf4j
@Component
public class SampleClass{
@Autowired
private JdbcTemplate mainJdbcTemplate;
@Autowired
@Qualifier("integrationJdbcTemplate")
private static JdbcTemplate integrationTemplate;
public static final String SELECT_QUERY = "select * from tableA";
public List<SampleDto> getDBData(SampleDto fileData) {
List<SampleDto> data = null;
try {
data = integrationTemplate.query(
SampleClass.SELECT_QUERY, new Object[] { param1, param2 },
new SampleDataMapper());
} catch (DataAccessException e) {
log.error(e.getMessage(), e);
}
return data;
}
}
在 SampleClass.java 中,我将 integrationTemplate 作为 null 获取。为什么会这样? mainJdbcTemplate 正在运行。但是 integrationTemplate 变为 null 并且无法执行查询。
问题是您的 static
字段带有 @Autowired
With @Autowired
在构造 bean 之后立即注入字段,然后再调用任何配置方法。阅读 here 了解有关 Ioc 和 Bean 注入的更多信息。
删除 static
:
@Autowired
@Qualifier("integrationJdbcTemplate")
private JdbcTemplate integrationTemplate;
当然可以,但是不推荐:
private static JdbcTemplate integrationTemplate;
@Autowired
public void setIntegrationJdbcTemplate(JdbcTemplate integrationTemplate){
SampleClass.integrationTemplate = integrationTemplate;
}
按名称自动装配
如果您使用与用于 bean 初始化的名称完全相同的名称,则无需输入 @Qualifier
,只需使用 as:
@Autowired
private JdbcTemplate integrationJdbcTemplate;
那是因为 Spring 知道要注入哪个 bean。如果你有更多相同类型的 beans 那么它会抛出 NoUniqueBeanDefinitionException
然后你用 @Qualifier
.
我还建议将您的字段标记为 final
,以作为良好做法。