java - Spring Boot 多数据源:如何在 java 类中配置多个 spring.jpa 属性
问题描述
应用程序.yml
spring:
security:
user:
name: test
password: admin
datasource:
platform: postgres
jdbc-url: jdbc:postgresql://localhost:5432/ktnb
username: xxxx
password: xxxx
driverClassName: org.postgresql.Driver
sqlserver-datasource:
jdbc-url: jdbc:sqlserver://192.168.0.10;databaseName=backup1
username: xxx
password: xxx
driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
PrimaryDBConfig.java
package com.ktnb.keahlian.config;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactory",
transactionManagerRef = "transactionManager",
basePackages = { "com.ktnb.keahlian.repository" }
)
public class PrimaryDBConfig {
@Primary
@Bean(name = "dataSource")
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean
entityManagerFactory(
EntityManagerFactoryBuilder builder,
@Qualifier("dataSource") DataSource dataSource
) {
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("spring.jpa.database", "postgresql");
properties.put("spring.jpa.show-sql", "true");
properties.put("spring.jpa.hibernate.ddl-auto", "create");
properties.put("spring.jpa.properties.hibernate.default_schema", "keahlian");
properties.put("spring.jpa.org.hibernate.envers.default_schema", "keahlian_envers");
properties.put("spring.jpa.org.hibernate.envers.audit_strategy", "org.hibernate.envers.strategy.ValidityAuditStrategy");
return builder
.dataSource(dataSource)
.packages("com.ktnb.keahlian.entity")
.persistenceUnit("primaryDB")
.properties(properties)
.build();
}
@Primary
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager(
@Qualifier("entityManagerFactory") EntityManagerFactory
entityManagerFactory
) {
return new JpaTransactionManager(entityManagerFactory);
}
}
但它找不到正确的表/模式,也无法在控制台中显示 sql。
开发数据库的主要数据源。
生产数据库的辅助数据源。
[INFO ] 2020-08-21 09:38:30.116 [http-nio-8080-exec-1] SessionListenerImpl - ==== Session is created ====
[INFO ] 2020-08-21 09:38:30.116 [http-nio-8080-exec-1] SessionListenerImpl - Total active session are 1
[WARN ] 2020-08-21 09:38:32.480 [http-nio-8080-exec-6] SqlExceptionHelper - SQL Error: 0, SQLState: 42P01
[ERROR] 2020-08-21 09:38:32.480 [http-nio-8080-exec-6] SqlExceptionHelper - ERROR: relation "pengguna" does not exist
Position: 467
解决方案
你能试试这个吗?
应用程序属性
primary.url={primary-database-url}
primary.username={primary-database-username}
primary.password={primary-database-password}
primary.driver-class-name=com.mysql.jdbc.Driver
primary.test-on-borrow=true
primary.validation-query=SELECT 1
secondary.url={secondary-database-url}
secondary.username={secondary-database-username}
secondary.password={secondary-database-password}
secondary.driver-class-name=com.mysql.jdbc.Driver
secondary.test-on-borrow=true
secondary.validation-query=SELECT 1
secondary.validation-interval=25200000
创建配置bean
@Bean(name = "primaryDataSource")
@ConfigurationProperties("primary")
@Primary
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "secondaryDataSource")
@ConfigurationProperties("secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
接下来,创建我们将用于访问数据访问层中的数据源的 JdbcTemplate bean。
@Bean(name = "primaryJdbcTemplate")
public JdbcTemplate primaryJdbcTemplate(@Qualifier("primary") DataSource primaryDs) {
return new JdbcTemplate(writeDs);
}
@Bean(name = “secondaryJdbcTemplate")
public JdbcTemplate secondaryJdbcTemplate(@Qualifier("secondary") DataSource secondaryDs) {
return new JdbcTemplate(secondaryDs);
}
尝试访问这样的属性:
@Resource(name = "primaryJdbcTemplate")
private JdbcTemplate primaryJdbcTemplate;
@Resource(name = "secondaryJdbcTemplate")
private JdbcTemplate secondaryJdbcTemplate;
primaryJdbcTemplate.query(“any-query-to-apply-on-primary-data-source”);
推荐阅读
- google-cloud-platform - Microsoft Authenticode 代码签名 (EV) + Google Cloud HSM?
- python - IndexError ::: 列表索引超出范围
- android - 如何测试 gradle 插件构建速度的影响
- msbuild - 从 Build Pipeline 的 bin 文件夹中删除一个 DLL
- android - Android Studio 3.5 在我的智能手机上部署问题
- postgresql - 引起:org.springframework.beans.factory.BeanCreationException:使用Spring Boot 2创建名称错误的bean时出错
- angular-material - mat-form-field floatLabel="never" 不起作用
- haskell - 如何创建一个接受参数列表并返回将参数应用于另一个函数的函数的函数
- php - 使用函数作为 while 参数,如 Wordpress
- reactjs - 在 React 和 Typescript 中只允许特定组件作为子组件