如何在spring boot中访问非主数据源?

时间:2018-05-30 05:54:51

标签: java spring 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;
}

DAO:

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

这一切都很好。 然后我尝试添加另一个DB。我删除了我的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(&#34; second.spring.datasource&#34;)四处,没有帮助。我尝试在DAO的方法中添加限定符,没有帮助。我尝试在主类中添加限定符,Autowired和run方法 - 没有帮助。当我添加&#34; second.spring.datasource&#34;时,它也没有帮助。在application.properties上。

我做错了什么?我还该怎么办?我可以看到访问多个DB的其他代码,但它们太复杂了,有许多Bean和其他特定于hibernate的属性 - 而不是简单的Spring引导定义。我必须转向休眠并使用许多bean和事务管理器吗?

1 个答案:

答案 0 :(得分:1)

基本上你需要告诉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.*

相关问题