下面是详细讲解“SpringBoot+Jpa项目配置双数据源的实现”的完整攻略。
一、项目结构
在项目结构上,我们需要将不同的数据源分别放在不同的包下,以避免混淆和管理上的困难。
myproject
├── src
│ └── main
│ ├── java
│ │ └── com.example.myproject
│ │ ├── datasource1
│ │ │ ├── Entity1.java
│ │ │ ├── Repository1.java
│ │ │ └── config
│ │ │ └── DataSource1Config.java
│ │ ├── datasource2
│ │ │ ├── Entity2.java
│ │ │ ├── Repository2.java
│ │ │ └── config
│ │ │ └── DataSource2Config.java
│ │ └── MyProjectApplication.java
│ └── resources
│ ├── application.properties
│ ├── application-datasource1.yml
│ └── application-datasource2.yml
└── pom.xml
其中 datasource1
和 datasource2
分别存放不同的数据源的相关实体和配置,MyProjectApplication
是主要的应用入口。
二、添加依赖
我们需要相应的依赖来支持双数据源的配置。在 pom.xml
中添加以下依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- 需要添加的额外依赖 -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
这里添加了 MySQL 数据库的依赖和 HikariCP 连接池的依赖。
三、配置数据源及 JPA
通过 SpringBoot 的自动配置,我们可以在 application.properties
或 application.yml
中配置数据库连接和 JPA 相关信息。同时,因为我们要配置多个数据源,所以我们需要分别编写两个额外的配置文件,分别为 application-datasource1.yml
和 application-datasource2.yml
。
1. application.properties
以下是 application.properties
文件的示例配置,该文件放在 resources
目录下:
# 主数据源配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456
# JPA 配置
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
# 次数据源配置
datasource2.driver-class-name=com.mysql.jdbc.Driver
datasource2.url=jdbc:mysql://localhost:3306/db2?useUnicode=true&characterEncoding=utf-8
datasource2.username=root
datasource2.password=123456
我们在这里定义了一个主数据源和一个次数据源的相关配置,分别对应了两个不同的数据库。
2. application-datasource1.yml
以下是 application-datasource1.yml
文件的示例配置,该文件也放在 resources
目录下:
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
hikari:
jdbc-url: jdbc:mysql://localhost:3306/db1_1?useUnicode=true&characterEncoding=utf-8
username: root
password: 123456
jpa:
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
ddl-auto: update
show-sql: true
这里我们使用了 HikariCP 数据源连接池,通过 spring.datasource.type
配置了连接池的类型。同时,我们配置了相关的 JPA 信息。
3. application-datasource2.yml
以下是 application-datasource2.yml
文件的示例配置,同样放在 resources
目录下:
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
hikari:
jdbc-url: jdbc:mysql://localhost:3306/db1_2?useUnicode=true&characterEncoding=utf-8
username: root
password: 123456
jpa:
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
ddl-auto: update
show-sql: true
该文件与 application-datasource1.yml
类似,只需更改数据库连接信息即可。
四、实现数据源切换
1. 配置类
我们可以创建一个配置类来设置两个数据源的相关信息,同时通过 @Primary
注释标注默认数据源为 datasource1
。该类代码如下:
@Configuration
public class DataSourceConfig {
@Bean(name = "datasource1")
@Primary
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource1() {
return DataSourceBuilder.create().build();
}
@Bean(name = "datasource2")
@ConfigurationProperties(prefix = "datasource2")
public DataSource dataSource2() {
return DataSourceBuilder.create().build();
}
}
这里我们使用 @ConfigurationProperties
注释标注了数据源的前缀,并使用 DataSourceBuilder
创建了对应的数据源。
2. 实现 JPA 配置
在每个数据源的实体和 Repository 中也需要进行一定的配置,以便于正确的使用对应的数据源。我们需要使用 @Qualifier
注释和 @Bean
注释注解当前数据源的 JPA 相关配置。例如:
Entity1.java
@Entity
@Table(name = "entity1")
@Qualifier("entityManagerFactory1")
public class Entity1 {
// ...
}
Repository1.java
public interface Repository1 extends JpaRepository<Entity1, Long> {
// ...
}
@Configuration
@EnableJpaRepositories(
basePackages = "com.example.myproject.datasource1",
entityManagerFactoryRef = "entityManagerFactory1",
transactionManagerRef = "transactionManager1"
)
public class DataSource1Config {
@Bean(name = "entityManagerFactory1")
@Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactory1(
EntityManagerFactoryBuilder builder,
@Qualifier("datasource1") DataSource dataSource) {
return builder
.dataSource(dataSource)
.packages("com.example.myproject.datasource1") // 数据库中对应实体的包名
.persistenceUnit("datasource1")
.build();
}
@Bean(name = "transactionManager1")
@Primary
public PlatformTransactionManager transactionManager1(
@Qualifier("entityManagerFactory1") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
这里在 @EnableJpaRepositories
的参数中指定了当前数据源的所在包名,并使用 @Qualifier
指定了当前数据源的实体管理器。
以及对另一份数据源的配置:
Entity2.java
@Entity
@Table(name = "entity2")
@Qualifier("entityManagerFactory2")
public class Entity2 {
// ...
}
Repository2.java
public interface Repository2 extends JpaRepository<Entity2, Long> {
// ...
}
@Configuration
@EnableJpaRepositories(
basePackages = "com.example.myproject.datasource2",
entityManagerFactoryRef = "entityManagerFactory2",
transactionManagerRef = "transactionManager2"
)
public class DataSource2Config {
@Bean(name = "entityManagerFactory2")
public LocalContainerEntityManagerFactoryBean entityManagerFactory2(
EntityManagerFactoryBuilder builder,
@Qualifier("datasource2") DataSource dataSource) {
return builder
.dataSource(dataSource)
.packages("com.example.myproject.datasource2") // 数据库中对应实体的包名
.persistenceUnit("datasource2")
.build();
}
@Bean(name = "transactionManager2")
public PlatformTransactionManager transactionManager2(
@Qualifier("entityManagerFactory2") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
同样的,在 @EnableJpaRepositories
参数中使用到了 @Qualifier
来指定当前数据源的实体管理器。
五、实现示例
我们这里提供两个简单的示例来演示双数据源的配置和切换。假设我们有两个表 entity1
和 entity2
,它们存放在两个不同的数据库中。
示例1
添加一个对应于第一个数据源的 Repository:
@Repository
public interface Entity1Repository extends JpaRepository<Entity1, Long> {
// ...
}
然后需要在对应的 Service 类上使用 @Qualifier
注释来指定使用的数据源:
@Service
public class Entity1Service {
private final Entity1Repository entity1Repository;
@Autowired
public Entity1Service(@Qualifier("entityManagerFactory1") EntityManager entityManager) {
this.entity1Repository =
new Entity1RepositoryImpl(
entityManager.getDelegate().unwrap(Session.class)
);
}
// ...
}
在 Entity1Service
的构造函数中,我们使用了 @Qualifier
注释来指定使用的数据源,通过 EntityManager
和 Session
来操作对应的数据库。
示例2
该示例为使用第二个数据源的 Repository,同样地需要使用 @Qualifier
注释指定当前使用的数据源。
@Repository
public interface Entity2Repository extends JpaRepository<Entity2, Long> {
// ...
}
@Service
public class Entity2Service {
private final Entity2Repository entity2Repository;
@Autowired
public Entity2Service(@Qualifier("entityManagerFactory2") EntityManager entityManager) {
this.entity2Repository =
new Entity2RepositoryImpl(
entityManager.getDelegate().unwrap(Session.class)
);
}
// ...
}
这里我们同样使用了 @Qualifier
注释来指定当前数据源。
六、总结
通过以上的配置,我们实现了 SpringBoot JPA 项目双数据源的配置和使用,并通过示例提供了更加具体的实现方法。双数据源的配置和使用并不复杂,在掌握了基本的配置和使用技巧之后,我们能够在自己的项目中快速的实现双数据源的配置和使用。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot+Jpa项目配置双数据源的实现 - Python技术站