spring boot 链接两个数据源,操作两个数据库

本文章使用的是持久化框架为JPA,所以数据源也是基于JPA。采用的是SpringBoot2 + SpringDataJPA + MySQL + 双数据源!

 

一、双数据源的适用场景:

1、主从库分离(数据库读写分离)

2、数据迁移

3、系统版本升级,数据库升级到另外一款

 

二、application.properties中配置

#mysql数据源
spring.datasource.one.type= com.alibaba.druid.pool.DruidDataSource
spring.datasource.one.jdbc-url= jdbc:mysql://localhost:3306/hongtianyu_sync?useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.one.username= root
spring.datasource.one.password= root
spring.datasource.one.driver-class-name= com.mysql.cj.jdbc.Driver
#spring.datasource.one.database:mysql
#sqlserver数据源
#spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.two.jdbc-url = jdbc:mariadb://192.168.7.22:3309/power?useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.two.username = zhongfu
spring.datasource.two.password = zhongfu
spring.datasource.two.driver-class-name = org.mariadb.jdbc.Driver

 

 

三、读取application.properties配置的两个数据源,并将其注入到Spring的IOC容器中

 

@Configuration
public class DataSourceConfig {

    /**
     * 
     * @return
     * @explains mysql 数据源
     */
    @Primary
    @Bean(name = "oneDataSource")
    @Qualifier(value = "oneDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.one")
    public DataSource mysqlDataSource() {
        return DataSourceBuilder.create().build();
    }
    
    /**
     * 
     * @return
     * @explains mariaDB数据源
     */
    @Bean(name = "twoDataSource")
    @Qualifier(value = "twoDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.two")
    public DataSource mariaDataSource() {
        return DataSourceBuilder.create().build();
    }
}

注解解释:

@Configuration:SpringBoot启动将该类作为配置类,同配置文件一起加载

@Bean:将该实体注入到IOC容器中

@Qualifier:指定数据源名称,与Bean中的name属性原理相同,主要是为了确保注入成功

@Primary:指定主数据源

@ConfigurationProperties:将配置文件中的数据源读取到方法中,进行build

 

 

四、以类的方式配置两个数据源

 

(1)主数据源(对应DataSourceConfig类中的oneDataSource)

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "entityManagerFactoryOne",//EntityManagerFactory引用
        transactionManagerRef = "transactionManagerOne",//transactionManager引用
        basePackages = {"com.diyuan.sync.dao"}) //设置oneDataSource应用到的包,设置DAO接口层所在包位置
public class OneDataSourceConfig {
    /**
     * @explains 注入mysql数据源
     */
    @Autowired
    @Qualifier("oneDataSource")
    private DataSource oneDataSource;
    /**
     * @explains 注入jpa配置实体
     */
    @Autowired
    private JpaProperties jpaProperties;
    @Autowired
    private HibernateProperties hibernateProperties;
    
    @Primary
    @Bean(name = "entityManagerOne")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
        return entityManagerFactoryOne(builder).getObject().createEntityManager();
    }
    /**
     * 
     * @param builder
     * @return 实体管理工厂
     * @explains 配置EntityManagerFactory实体
     * packges 扫描@Entity注释软件包名称
     * persistenceUnit 持久性单元的名称 如果只建立一个EntityManagerFactory 可以省略。如果有多个 则应该给不同的名字
     * properties 标准jpa或供应商特定配置的通用属性 这些属性覆盖构造函数中提供的任何值
     */
    @Primary
    @Bean(name = "entityManagerFactoryOne")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryOne(EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(oneDataSource)
                .properties(getVendorProperties())//获取jpa配置
                //.properties(hibernateProperties.determineHibernateProperties(getVendorProperties2(oneDataSource), new HibernateSettings()))
                .packages("com.diyuan.sync.model")//设置实体类所在位置
                .persistenceUnit("onePersistenceUnit")//持久化单位名称
                //.persistenceUnit("primaryPersistenceUnit")
                .build();
    }
    /**
     * 
     * @return
     * @explains 
     */
//  private Map<String, String> getVendorProperties2(DataSource dataSource){
//      jpaProperties.setDatabase(Database.MYSQL);
//      Map<String, String> map = new HashMap<>();
//          map.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
//          map.put("hibernate.hbm2ddl.auto", "update");
//