java - 如何在 Spring Boot 中访问非主 DataSource?
问题描述
我有最简单的spring boot程序:主要:
@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired
private AdapterFixRepository adapterFixRepository;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Transactional(readOnly = true)
@Override
public void run(String... args) {
System.out.println("Id 736: " + adapterFixRepository.getById(736L));
}
}
实体:
@Data
@Entity
public class AdapterFix {
@Id
@GeneratedValue
Long id;
private String senderCompId;
}
道:
public interface AdapterFixRepository extends CrudRepository<AdapterFix, Long> {
String SELECT_ADAPTER_FIX_BY_ID = " SELECT fix.*, adp.*, stm.* " +
" FROM `tr-dev`.adapter_fix AS fix " +
" INNER JOIN `tr-dev`.adapter AS adp ON fix.ID = adp.ID " +
" INNER JOIN `tr-dev`.stream_types AS stm ON stm.ID = fix.STREAM_TYPES_ID " +
" WHERE fix.ID = :id";
AdapterFix findById(@Param("id") Long id);
@Query(value = SELECT_ADAPTER_FIX_BY_ID, nativeQuery = true)
AdapterFix getById(@Param("id") Long id);
}
并且在 application.properties 中:
spring.datasource.url=jdbc:mysql://localhost:3306/tr-dev?autoReconnect=true
spring.datasource.username=root
spring.datasource.password=***
spring.datasource.driverClassName=com.mysql.jdbc.Driver
这一切都很好。然后我尝试添加另一个数据库。我删除了我的 application.properties,并添加了这个配置文件:
@Configuration
@Qualifier("second.spring.datasource")
public class DataSourceConfig {
@Primary
@Bean(name = "first.spring.datasource")
@ConfigurationProperties(prefix = "first.spring.datasource")
@Qualifier("first.spring.datasource")
public DataSource firstDataSource() {
return DataSourceBuilder.create().url("jdbc:mysql://localhost:3306/tr-dev?autoReconnect=true").username("root").password("***").
driverClassName("com.mysql.jdbc.Driver").build();
}
@Bean(name = "second.spring.datasource")
@Qualifier("second.spring.datasource")
@ConfigurationProperties(prefix = "second.spring.datasource")
public DataSource secondDataSource() {
return DataSourceBuilder.create().url("jdbc:mysql://10.2.5.63:3306/tr-dev?autoReconnect=true").username("root").password("***").
driverClassName("com.mysql.jdbc.Driver").build();
}
}
它是从我的第一个数据源中选择的。我尝试在周围添加 @Qualifier("second.spring.datasource") ,但没有帮助。我尝试在 DAO 的方法中添加限定符,但没有帮助。我尝试在主类、Autowired 和 run 方法中添加限定符 - 没有帮助。当我在 application.properties 上添加“second.spring.datasource”时,它也没有帮助。
我究竟做错了什么?我还应该做什么?我可以看到访问多个 DB 的其他代码,但是它们太复杂了,有许多 Bean 和其他休眠特定属性——而不是简单的 Spring Boot 定义。我必须转向休眠并使用许多 bean 和事务管理器吗?
解决方案
基本上你需要告诉spring哪些实体属于哪个数据库。以下代码假定 Spring Boot 2.0。您还需要配置哪个存储库属于哪个配置。对于存储库,这是通过@EnableJpaRepositories
在LocalContainerEntityManagerFactoryBean
.
主数据库配置:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = {"primary.repository.package"}
)
public class JpaPrimaryConfig {
@Bean
@Primary
@ConfigurationProperties("datasource")
public DataSourceProperties primaryDataSourceProperties() {
return new DataSourceProperties();
}
@Primary
@Bean(name = "dataSource")
@ConfigurationProperties(prefix = "datasource")
public DataSource configurePrimaryDataSource() {
return primaryDataSourceProperties().initializeDataSourceBuilder().build();
}
@Primary
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(configurePrimaryDataSource());
entityManagerFactoryBean.setPackagesToScan("primary.entity.package");
entityManagerFactoryBean.setPersistenceUnitName("primaryPersistenceUnit");
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
return entityManagerFactoryBean;
}
@Primary
@Bean(name = {"transactionManager", "primaryTransactionManager"})
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
}
辅助数据库配置:
@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "secondaryEntityManagerFactory",
transactionManagerRef = "secondaryTransactionManager",
basePackages = {"secondary.repository.package"}
)
public class JpaSecondaryConfig {
@Bean
@ConfigurationProperties("datasource.secondary")
public DataSourceProperties secondaryDataSourceProperties() {
return new DataSourceProperties();
}
@Bean(name = "secondaryDataSource")
@ConfigurationProperties(prefix = "datasource.secondary")
public DataSource configureSecondaryDataSource() {
return secondaryDataSourceProperties().initializeDataSourceBuilder().build();
}
@Bean(name = "secondaryEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(configureSecondaryDataSource());
entityManagerFactoryBean.setPackagesToScan("secondary.entity.package");
entityManagerFactoryBean.setPersistenceUnitName("secondaryPersistenceUnit");
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
return entityManagerFactoryBean;
}
@Bean(name = "secondaryTransactionManager")
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
}
然后,您可以像往常一样使用应用程序属性配置这两个数据源。主数据库配置位于默认datasource.*
路径下,辅助配置位于datasource.secondary.*
推荐阅读
- javascript - 如何基于 Hexcode Jquery 显示货币符号?
- hive - 处理语句时出错:FAILED:执行错误,从 org.apache.hadoop.hive.ql.exec.mr.MapRedTask 返回代码 2 (state=08S01,code=2)
- r - 如何在 Spark 本地模式下检查任务日志
- hive - 在hive中,如何在hql中生成动态表名?
- java - 当结果集有参数时,如何在可自动关闭的资源中设置参数?
- typescript - 打字稿:使用“枚举”值作为“类型”
- performance - 如何在 Jmeter 中更改 http 请求名称
- html - HTML 中的制表符顺序是否合乎逻辑?
- python - Python - 相当于 Ruby 新方法
- java - 如何反转组成句子的字符数组