Tutorial básico do Spring Boot 2.x: Configuração de múltiplas fontes de dados Spring Data JPA

No artigo anterior, apresentamos a implementação da configuração de várias fontes de dados ao usar JdbcTemplate para acesso a dados. Em seguida, continuamos a aprender como concluir a configuração e o uso de várias origens de dados ao usar Spring Data JPA.

Adicione a configuração de várias fontes de dados

Primeiro, application.propertiesdefina duas configurações de banco de dados que você deseja vincular ao arquivo de configuração Spring Boot , como este:

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

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

# 日志打印执行的SQL
spring.jpa.show-sql=true
# Hibernate的DDL策略
spring.jpa.hibernate.ddl-auto=create-drop

Exceto pela configuração relacionada ao próprio JPA, a configuração da origem de dados é completamente consistente com a configuração JdbcTemplate.

Descrição e nota :

  1. Ao configurar várias fontes de dados, a diferença de uma única fonte de dados é que spring.datasourcedepois de configurar um nome de fonte de dados primarye secondarydistinguir diferentes configurações de fonte de dados, este prefixo será usado na inicialização subsequente das fontes de dados.
  2. Conexão de fonte de dados de configuração 2.x e 1.x configuração itens são diferentes: uso 2.x spring.datasource.secondary.jdbc-url, e 1.x uso versão spring.datasource.secondary.url. Se esse erro ocorrer durante a configuração java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName., é um problema com este item de configuração.

Inicialize a fonte de dados e a configuração JPA

Depois de preencher as informações de configuração para várias fontes de dados, crie uma classe de configuração para carregar as informações de configuração, inicialize a fonte de dados e inicialize o JdbcTemplate usado por cada fonte de dados.

Como a configuração do JPA é mais responsável do que a do JdbcTemplate, dividiremos a configuração para lidar com:

  1. Crie uma classe de configuração separada para várias fontes de dados, como a seguinte:
@Configuration
public class DataSourceConfiguration {
    
    

    @Primary
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.primary")
    public DataSource primaryDataSource() {
    
    
        return DataSourceBuilder.create().build();
    }

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

}

Você pode ver que o conteúdo é exatamente o mesmo do JdbcTemplate. Ele @ConfigurationPropertiespode ser conhecido que estas duas fontes de dados ter carregado a configuração de spring.datasource.primary.*e , respectivamente spring.datasource.secondary.*. @PrimaryA anotação especifica a fonte de dados principal, ou seja, quando não especificamos qual fonte de dados, a diferença real deste Bean será usada na seguinte configuração JPA.

  1. Crie a configuração JPA das duas origens de dados, respectivamente.

Configuração JPA da fonte de dados primária:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef="entityManagerFactoryPrimary",
        transactionManagerRef="transactionManagerPrimary",
        basePackages= {
    
     "com.didispace.chapter38.p" }) //设置Repository所在位置
public class PrimaryConfig {
    
    

    @Autowired
    @Qualifier("primaryDataSource")
    private DataSource primaryDataSource;

    @Autowired
    private JpaProperties jpaProperties;
    @Autowired
    private HibernateProperties hibernateProperties;

    private Map<String, Object> getVendorProperties() {
    
    
        return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
    }

    @Primary
    @Bean(name = "entityManagerPrimary")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
    
    
        return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
    }

    @Primary
    @Bean(name = "entityManagerFactoryPrimary")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary (EntityManagerFactoryBuilder builder) {
    
    
        return builder
                .dataSource(primaryDataSource)
                .packages("com.didispace.chapter38.p") //设置实体类所在位置
                .persistenceUnit("primaryPersistenceUnit")
                .properties(getVendorProperties())
                .build();
    }

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

}

Configuração JPA da fonte de dados secundária:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef="entityManagerFactorySecondary",
        transactionManagerRef="transactionManagerSecondary",
        basePackages= {
    
     "com.didispace.chapter38.s" }) //设置Repository所在位置
public class SecondaryConfig {
    
    

    @Autowired
    @Qualifier("secondaryDataSource")
    private DataSource secondaryDataSource;

    @Autowired
    private JpaProperties jpaProperties;
    @Autowired
    private HibernateProperties hibernateProperties;

    private Map<String, Object> getVendorProperties() {
    
    
        return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
    }

    @Bean(name = "entityManagerSecondary")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
    
    
        return entityManagerFactorySecondary(builder).getObject().createEntityManager();
    }

    @Bean(name = "entityManagerFactorySecondary")
    public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary (EntityManagerFactoryBuilder builder) {
    
    
        return builder
                .dataSource(secondaryDataSource)
                .packages("com.didispace.chapter38.s") //设置实体类所在位置
                .persistenceUnit("secondaryPersistenceUnit")
                .properties(getVendorProperties())
                .build();
    }

    @Bean(name = "transactionManagerSecondary")
    PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
    
    
        return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
    }

}

Descrição e nota :

  • Ao usar JPA, você precisa criar pacotes diferentes para origens de dados diferentes para armazenar a Entidade e Repositório correspondentes, de modo a facilitar a varredura de partição da classe de configuração
  • @EnableJpaRepositoriesEspecifique a localização do Repositório na anotação no nome da classe
  • LocalContainerEntityManagerFactoryBeanAo criar, especifique a localização da Entidade
  • A outra atenção principal é que, ao injetar um no outro, basicamente não há grande problema com a nomenclatura de diferentes fontes de dados e diferentes configurações.

faça um teste

Depois de concluir o acima, podemos escrever uma classe de teste para tentar se a configuração de várias fontes de dados acima está correta, como a seguinte:

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter38ApplicationTests {
    
    

    @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());

        messageRepository.save(new Message("o1", "aaaaaaaaaa"));
        messageRepository.save(new Message("o2", "bbbbbbbbbb"));
        messageRepository.save(new Message("o3", "cccccccccc"));

        Assert.assertEquals(3, messageRepository.findAll().size());
    }

}

Descrição e nota :

  • A lógica da verificação do teste é muito simples, ou seja, inserir dados em diferentes fontes de dados por meio de diferentes Repositórios, e depois consultar se o número total está correto
  • Os detalhes de Entidade e Repositório são omitidos aqui, os leitores podem baixar o exemplo completo no exemplo de código abaixo para visualizá-lo

Exemplo de código

Para exemplos relacionados neste artigo, você pode visualizar os chapter3-8diretórios no seguinte warehouse :

  • Github : https: //github.com/dyc87112/SpringBoot-Learning/
  • Gitee : https: //gitee.com/didispace/SpringBoot-Learning/

Se você acha que este artigo é bom, seja bem-vindo, suporte Star, sua atenção é minha motivação para persistência!

Leitura Relacionada

Acho que você gosta

Origin blog.csdn.net/dyc87112/article/details/106919883
Recomendado
Clasificación