在现代微服务架构中,服务通常需要与多个数据库交互。这可能是由于各种原因,例如,集成遗留系统、不同类型的存储需求,或者只是出于性能优化的需求。Spring Boot 由于其灵活的配置和强大的数据访问库,使得配置多个数据库变得简单易行。在本全面指南中,我们将探讨如何在 Spring Boot 微服务中设置和管理多个数据库连接,使之更高效。
目录- 引言
- 为什么要使用多个数据库?
- 搭建 Spring Boot 项目
- 配置多个数据源
- 创建数据源配置类
- 定义实体管理对象
- 创建仓库(Repository)
- 测试配置设置
- 结论
微服务通常需要与多种数据库进行交互。例如,可以使用SQL数据库来存储事务性数据,而使用NoSQL数据库来存储非结构化数据。Spring Boot提供了出色的配置和管理多个数据源的能力,因此,它成为现代微服务架构的理想选择。
2. 为什么要使用多个数据库?有几个原因可能需要你在微服务架构中使用多个数据库(multiple databases):
- 遗留系统集成: 与现有遗留系统中的数据库进行集成。
- 优化性能: 使用针对特定类型数据(如关系型和非关系型)优化的不同数据库。
- 数据隔离: 根据安全、合规或组织需要将数据隔离。
- 可扩展性: 通过将数据负载分布在不同的数据库上提高性能。
要开始, 请使用Spring Initializr或你常用的IDE来创建一个新的Spring Boot项目。
Maven 依赖项在你的 pom.xml
文件中,添加 Spring Data JPA 以及你需要的数据库(如 H2、PostgreSQL、MySQL 等)的依赖项。例如,H2 用于内存中的数据库。
<dependencies>
<!-- 下面是一些常用的依赖项,用于启动Spring Boot应用的数据访问和Web功能。 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>运行时</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>运行时</scope>
</dependency>
<!-- 根据需要添加其他数据库依赖项 -->
</dependencies>
4. 配置多个数据源连接:
在 application.yml
或 [application.properties](http://application.properties)
文件中,配置每个数据库的连接配置。
spring:
datasource:
primary:
url: jdbc:h2:mem:primarydb
driver-class-name: org.h2.Driver
username: sa
password: password
secondary:
url: jdbc:postgresql://localhost:5432/secondarydb
driver-class-name: org.postgresql.Driver
username: postgres
password: password
jpa:
primary:
database-platform: org.hibernate.dialect.H2Dialect
hibernate:
ddl-auto: update
secondary:
database-platform: org.hibernate.dialect.PostgreSQLDialect
hibernate:
ddl-auto: update
5. 配置数据源
接下来,,为每个数据源分别创建单独的配置类。
主要数据源设置package com.example.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
@Configuration
@EnableJpaRepositories(
basePackages = "com.example.primary.repository",
entityManagerFactoryRef = "primaryEntityManagerFactory",
transactionManagerRef = "primaryTransactionManager"
)
public class PrimaryDataSourceConfig {
@Bean(name = "primaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "primaryEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory(
@Qualifier("primaryDataSource") DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
em.setPackagesToScan(new String[] { "com.example.primary.entity" });
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
return em;
}
@Bean(name = "primaryTransactionManager")
public PlatformTransactionManager primaryTransactionManager(
@Qualifier("primaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
辅助数据源设置
package com.example.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
@Configuration
@EnableJpaRepositories(
basePackages = "com.example.secondary.repository",
entityManagerFactoryRef = "secondaryEntityManagerFactory",
transactionManagerRef = "secondaryTransactionManager"
)
public class SecondaryDataSourceConfig {
@Bean(name = "secondaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "secondaryEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactory(
@Qualifier("secondaryDataSource") DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
em.setPackagesToScan(new String[] { "com.example.secondary.entity" });
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
return em;
}
@Bean(name = "secondaryTransactionManager")
public PlatformTransactionManager secondaryTransactionManager(
@Qualifier("secondaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
6. 定义实体管理器
为每个数据库定义实体类。请确保将它们放置在配置文件中指定的对应文件夹中。
主数据库条目 包 com.example.primary.entity;
导入 javax.persistence.Entity;
导入 javax.persistence.GeneratedValue;
导入 javax.persistence.GenerationType;
导入 javax.persistence.Id;
@Entity
public class PrimaryEntity {
@Id
@GeneratedValue(生成策略 = GenerationType.IDENTITY)
private Long id;
private String name;
// 获取器和设置器
}
次要数据库实体(Secondary 数据库实体).
包 com.example.secondary.entity;
导入 javax.persistence.Entity;
导入 javax.persistence.GeneratedValue;
导入 javax.persistence.GenerationType;
导入 javax.persistence.Id;
@Entity
公共类 SecondaryEntity {
@Id
@GeneratedValue(策略 = GenerationType.IDENTITY)
私有 Long id;
私有 String description;
// getter和setter
}
7. 创建存储库
为每个数据库创建存储库接口,并确保它们放在正确的配置包中。
主要仓库package com.example.primary.repository;
import com.example.secondary.entity.SecondaryEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface SecondaryRepository extends JpaRepository<SecondaryEntity, Long> {
}
备用仓库
package com.example.secondary.repository;
import com.example.secondary.entity.SecondaryEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface SecondaryRepository extends JpaRepository<SecondaryEntity, Long> {
}
8 测试这个配置:
最后,创建一个简单的REST控制器以测试设置。此控制器将使用两个存储库来执行增删改查操作。
控制器示例 package com.example.controller;
import com.example.primary.entity.PrimaryEntity;
import com.example.primary.repository.PrimaryRepository;
import com.example.secondary.entity.SecondaryEntity;
import com.example.secondary.repository.SecondaryRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@Autowired
private PrimaryRepository primaryRepository;
@Autowired
private SecondaryRepository secondaryRepository;
@GetMapping("/test")
public String test() {
PrimaryEntity primaryEntity = new PrimaryEntity();
primaryEntity.setName("Primary Entity");
primaryRepository.save(primaryEntity);
SecondaryEntity secondaryEntity = new SecondaryEntity();
secondaryEntity.setDescription("Secondary Entity");
secondaryRepository.save(secondaryEntity);
return "数据已保存!";
}
}
运行应用
跑步
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦