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.properties
defina 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 :
- Ao configurar várias fontes de dados, a diferença de uma única fonte de dados é que
spring.datasource
depois de configurar um nome de fonte de dadosprimary
esecondary
distinguir diferentes configurações de fonte de dados, este prefixo será usado na inicialização subsequente das fontes de dados. - 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ãospring.datasource.secondary.url
. Se esse erro ocorrer durante a configuraçãojava.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:
- 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 @ConfigurationProperties
pode ser conhecido que estas duas fontes de dados ter carregado a configuração de spring.datasource.primary.*
e , respectivamente spring.datasource.secondary.*
. @Primary
A 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.
- 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
@EnableJpaRepositories
Especifique a localização do Repositório na anotação no nome da classeLocalContainerEntityManagerFactoryBean
Ao 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-8
diretó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!