首页 > 解决方案 > 如何在 springboot 中连接到一个数据源上的 2 个不同模式

问题描述

我正在尝试从不同服务器中的多个数据库中提取数据。如我的代码所示,在配置不同的数据源后这已经成功,但是我看不到在同一连接上配置 2 个不同的数据源。

我试图在配置文件中创建 2 个 bean,但我仍然需要设置数据源。

@Configuration
@EnableJpaRepositories(basePackages = {"balances.Repository.World"},
        entityManagerFactoryRef = "ASourceEntityManager",transactionManagerRef = "ASourceTransactionManager")
@EnableTransactionManagement
public class World{
    @Autowired
    private Environment env;

    @Bean
    public LocalContainerEntityManagerFactoryBean ASourceEntityManager() {

        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(ASourceDatasource());
        em.setPackagesToScan(new String("balances.Repository.World"));
        em.setPersistenceUnitName("ASourceEntityManager");
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        HashMap<String, Object> properties = new HashMap<String, Object>();
        properties.put("hibernate.dialect",env.getProperty("app.datasource.ASource.hibernate.dialect"));
        properties.put("hibernate.show-sql",env.getProperty("app.datasource.ASource.show-sql"));
        em.setJpaPropertyMap(properties);
        return em;

    }
 
    @Bean
    @ConfigurationProperties(prefix = "app.datasource.ASource")
    public DataSource ASourceDatasource() {

        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        
  dataSource.setDriverClassName(env.getProperty("app.datasource.ASource.driverClassName"));
        dataSource.setUrl(env.getProperty("app.datasource.ASource.url"));
        dataSource.setUsername(env.getProperty("app.datasource.ASource.username"));
        dataSource.setPassword(env.getProperty("app.datasource.ASource.password"));

        return dataSource;
    }

    @ConfigurationProperties(prefix = "app.datasource.ASourceB")
    public DataSource ASourceDatasource() {

        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(env.getProperty("app.datasource.ASourceB.driverClassName"));
        dataSource.setUrl(env.getProperty("app.datasource.ASourceB.url"));
        dataSource.setUsername(env.getProperty("app.datasource.ASourceB.username"));
        dataSource.setPassword(env.getProperty("app.datasource.ASourceB.password"));

        return dataSource;
    }


    @Bean
    public PlatformTransactionManager ASourceTransactionManager() {

        JpaTransactionManager transactionManager
                = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(
                ASourceEntityManager().getObject());
        return transactionManager;
    }


标签: spring-bootjpa

解决方案


经过一番思考,我想出了一个可能有点hacky但可以完成工作的解决方法。我没有为我的 app.properties 中的第二个模式声明一个新的数据库连接,而是使用了一个连接。我将所有实体放在一个模型包中,并使用本机查询来访问另一个模式。在本机查询中,我将指定架构,例如:

 select * from DATABASE1.Id;  

此解决方案无法很好地扩展,因为它在处理大量实体时会产生大量工作,因此如果有一种方法可以在存储库中指定模式也会有所帮助。

我尝试使用实体属性来定义我的架构,但 jpa 似乎忽略了它并使用错误的架构为表添加前缀,例如,如果我用以下内容注释我的类

@Table(name = "Payment", schema = "DATABASE1", catalog = "")

结果查询将是“select * from DATABASE2.Payment”而不是 select * from DATABASE1.Payment


推荐阅读