Spring Boot多数据源配置

来源:互联网 发布:郑州管家婆软件怎么样 编辑:程序博客网 时间:2024/06/01 08:08
  • 动机

    • 在最近的项目中,由于新项目要和老项目整合(新旧业务过渡),因此需要将的数据库表与老数据库表做数据库同步。
  • 方案

    • 利用Spring Boot支持多数据源的特性,配置两个数据源来实现该需求。(这篇博客不讨论业务层面的实现方式,只讨论多数据源的配置。)
  • 实现

    1. 新建两个配置类(即加@Configuration注解的类),一个为PrimaryDatasourceConfig,用来配置本项目的数据源;另一个叫SecondDatasourceCOnfig,用来配置需要同步的数据源。代码如下:

      @Configurationpublic class PrimaryDatasourceConfig {    @Bean(name = "primaryDataSource")    @Primary    @ConfigurationProperties(prefix = "primary.datasource")    public DataSource dataSource() {        return DataSourceBuilder.create().build();    }}@Configurationpublic class SecondDatasourceConfig {    @Bean(name = "secondDataSource")    @ConfigurationProperties(prefix = "second.datasource")    public DataSource dataSource() {        return DataSourceBuilder.create().build();    }}

      其中@Primary注解是用来指定优先使用的数据源。
      @ConfigurationProperties是用来指定该数据远,从application.properties中读取前缀为“XXX”的配置作为该数据源的配置。
      并且由于这两个数据源的类型都是DataSource,因此我们需要为这两个Bean指定不同的名称,这样能够在后面注入的时候通过名称来注入相应的Bean。

    2. 再新建两个配置类,来配置EntityManager与JdbcTemplate。代码如下:

      @Configuration@EnableTransactionManagement(proxyTargetClass = true)//开启注解管理方式@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactoryPrimary",//指定LocalContainerEntityManagerFactoryBean        transactionManagerRef = "transactionManagerPrimary",//指定使用哪个EntityManager        basePackages = { "org.model" })//指定该数据源对于的model包public class RepositoryPrimaryConfig {    @Autowired    private JpaProperties jpaProperties;    @Autowired    @Qualifier("primaryDataSource")//指定使用哪个数据源    private DataSource primaryDataSource;    @Bean(name = "entityManagerPrimary")    @Primary//由于这个数据源是Primary,因此这里配置的Bean都加上@Primary注解。    //即在@Autowired时,没有用指定@Qualifier指定哪个数据源配置时,默认使用这个。    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {        return entityManagerFactory(builder).getObject()                .createEntityManager();    }    @Bean(name = "entityManagerFactoryPrimary")    @Primary    public LocalContainerEntityManagerFactoryBean entityManagerFactory(            EntityManagerFactoryBuilder builder) {        return builder.dataSource(primaryDataSource)                .properties(getVendorProperties(primaryDataSource))                .packages("org.model") // 设置实体类所在位置                .persistenceUnit("PrimaryPersistenceUnit")                .build();    }      private Map<String, String> getVendorProperties(DataSource dataSource) {        return jpaProperties.getHibernateProperties(dataSource);    }    @Bean(name = "transactionManagerPrimary")    @Primary    PlatformTransactionManager transactionManager(            EntityManagerFactoryBuilder builder) {        return new JpaTransactionManager(                entityManagerFactory(builder).getObject());    }    @Bean    @Primary    public JdbcTemplate primaryJdbcTemplate(DataSource dataSource) {        return new JdbcTemplate(dataSource);    }}@Configuration@EnableTransactionManagement(proxyTargetClass = true)@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactorySecond",        transactionManagerRef = "transactionManagerSecond",        basePackages = { "org.second" })public class RepositorySecondConfig {    @Autowired    private JpaProperties jpaProperties;    @Autowired    @Qualifier("secondDataSource")    private DataSource secondDataSource;    @Bean(name = "entityManagerSecond")    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {        return entityManagerFactory(builder).getObject()                .createEntityManager();    }    @Bean(name = "entityManagerFactorySecond")    public LocalContainerEntityManagerFactoryBean entityManagerFactory(            EntityManagerFactoryBuilder builder) {        return builder.dataSource(secondDataSource)                .properties(getVendorProperties(jwcDataSource))                .packages("org.second") // 设置实体类所在位置                .persistenceUnit("SecondPersistenceUnit").build();    }    private Map<String, String> getVendorProperties(DataSource dataSource) {        return jpaProperties.getHibernateProperties(dataSource);    }    @Bean(name = "transactionManagerSecond")    PlatformTransactionManager transactionManager(            EntityManagerFactoryBuilder builder) {        return new JpaTransactionManager(                entityManagerFactory(builder).getObject());    }    @Bean(name = "secondJdbcTemplate")    public JdbcTemplate jdbcTemplate(            @Qualifier("secondDataSource") DataSource dataSource) {        return new JdbcTemplate(dataSource);    }}
    3. 当使用第二个数据源的时候,@Autowired时用@Qualifier指定第二个数据源即可。例如要注入jdbcTemplate。

      @Autowired
      @Qualifier("secondJdbcTemplate")
      private JdbcTemplate jdbcTemplate;

      如果没有@Qualifier("secondJdbcTemplate"),默认指定Primary数据源。