SpringBoot implements multiple data source configuration

Posted by AtomicRax on Mon, 20 Jul 2020 18:01:36 +0200

Spring boot for multi data source configuration

springBoot implements the configuration of multiple data sources application.properties Configure two data sources in

spring.datasource.primary.url=jdbc:mysql://localhost:3306/test1
spring.datasource.primary.username=root
spring.datasource.primary.password=root
spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.secondary.url=jdbc:mysql://localhost:3306/test2
spring.datasource.secondary.username=root
spring.datasource.secondary.password=root
spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver

Two datasources are required to read application.properties Different configurations of.

@Configuration
    public class DataSourceConfig{
        @Bean(name = "primaryDataSource")
        @Qualifier("primaryDataSource")
        @ConfigurationProperties(prefix="spring.datasource.primary")
        public DataSource primaryDataSource(){
            return DataSourceBuilder.create().build();
        }


        @Bean(name = "secondaryDataSource")
        @Qualifier("secondaryDataSource")
        @ConfigurationProperties(prefix="spring.datasource.secondary")
        public DataSource secondaryDataSource(){
            return DataSourceBuilder.create().build();
        }
    }

JdbcTemplate support

In springBoot, the support for JdbcTemplate is relatively simple, and you only need to inject the corresponding datasource

    @Bean(name = "primaryJdbcTemplate")
    public JdbcTemplate primaryJdbcTemplate(
    @Qualifier("primaryDataSource" DataSource dataSource){
        return new JdbcTemplate(dataSource);
    }

    @Bean(name = "secondaryJdbcTemplate")
    public JdbcTemplate secondaryJdbcTemplate(
    @Qualifier("secondaryDataSource" DataSource dataSource){
        return new JdbcTemplate(dataSource);
    }

In this way, different data sources will be configured into different jdbctemplates. When using it, you can use the @ Autowired annotation with @ Qualifier

    public class TemplateService{
        @Autowired
        @Qualifier("primaryJdbcTemplate")
        private JdbcTemplate primaryJdbaTemplate
    }

JPA support

JPA supports the configuration of multiple data sources. The configuration of DataSource is the same as shown in the JdbcTemplate above, and each JPA configuration must be matched with a configuration class. In the class, it is necessary to write the Entity entity class and Repository corresponding to the correct data source

    /**
 * @Author:High key city
 * @time: 
 * @Discription: Jpa Allocation of resources
 */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "entityManagerFactoryPrimary",
        transactionManagerRef = "transactionManagerPrimary",
        basePackages = {"com.gaojiancheng.demo.repository"}     //Set the location of the repository
)
public class PrimaryConfig {
    @Autowired
    @Qualifier("primaryDataSource")
    //Inject the previously configured PrimaryDataSource here
    private DataSource primaryDataSource;

    @Autowired
    private JpaProperties jpaProperties;

//Entity class manager, as a Bean, named entityManagerPrimary
    @Primary
    @Bean(name = "entityManagerPrimary")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder){
        return entityManagerFactoryBean(builder).getObject().createEntityManager();
    }


    @Primary
    @Bean(name = "entityManagerFactoryPrimary")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder){
        return builder.dataSource(primaryDataSource)
                .properties(getVendorProperties(primaryDataSource))
                .packages("com.gaojiancheng.demo.model")            //Set the location of entity class
                .persistenceUnit("primaryPersistenceUnit")
                .build();
    }

    private Map<String , String> getVendorProperties(DataSource dataSource){
        return jpaProperties.getHibernateProperties(dataSource);
    }

    @Primary
    @Bean(name = "transactionManagerPrimary")
    public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder){
        return new JpaTransactionManager(entityManagerFactoryBean(builder).getObject());
    }
}

It should be noted that the correct location of the entity class and repository should be written, and the entity class manager and other contents should be written according to the above contents.

When configuring the second data source, the difference is that the name of the DataSource injection is changed from PrimaryDataSource to SecondaryDataSource

Next, write the information for the entity class

/**
*Entity class User
*/
@Entity
public class User {
    @Id
    @GeneratedValue
    private Long id;
    @Column(nullable = false)
    private String name;
    @Column(nullable = false)
    private Integer age;
    public User(){}
    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
    // Omit getter and setter
}

Write the corresponding Repository

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

Finally, we test it with Junit

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Application.class)
public class ApplicationTests {
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private MessageRepository messageRepository;
    @Test
    public void test() throws Exception {
        userRepository.save(new User("aaa", 10));
        userRepository.save(new User("bbb", 20));
        userRepository.save(new User("ccc", 30));
        userRepository.save(new User("ddd", 40));
        userRepository.save(new User("eee", 50));
        Assert.assertEquals(5, userRepository.findAll().size());
        }
    }

Topics: Spring JDBC MySQL SpringBoot