Spring Data与多数据源配置
今天我们来探讨如何在Spring Data中配置和使用多个数据源。
在现代应用程序中,处理多个数据源变得越来越常见。可能因为不同的数据存储需求,例如读写分离、跨系统数据访问,或者集成多个数据库系统。本文将详细讲解如何在Spring Boot中使用Spring Data配置多个数据源,并提供具体的Java代码示例。
一、项目依赖
首先,我们需要在pom.xml
中添加Spring Boot、Spring Data JPA以及数据库驱动的依赖。
<dependencies>
<!-- Spring Boot Starter Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- H2 Database -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<!-- MySQL Database -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
二、配置多数据源
我们将配置两个数据源:一个用于H2数据库,另一个用于MySQL数据库。
1. 配置文件
在application.yml
中配置数据源信息。
spring:
datasource:
h2:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password: password
mysql:
url: jdbc:mysql://localhost:3306/testdb
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: password
jpa:
hibernate:
ddl-auto: update
show-sql: true
properties:
hibernate:
dialect: org.hibernate.dialect.H2Dialect
format_sql: true
2. 数据源配置类
我们需要为每个数据源创建单独的配置类。
package cn.juwatech.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.context.annotation.Primary;
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 org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
@Configuration
@EnableTransactionManagement
public class DataSourceConfig {
@Primary
@Bean(name = "h2DataSource")
@ConfigurationProperties(prefix = "spring.datasource.h2")
public DataSource h2DataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "mysqlDataSource")
@ConfigurationProperties(prefix = "spring.datasource.mysql")
public DataSource mysqlDataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Bean(name = "h2EntityManagerFactory")
public LocalContainerEntityManagerFactoryBean h2EntityManagerFactory(@Qualifier("h2DataSource") DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
em.setPackagesToScan("cn.juwatech.model.h2");
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
em.setPersistenceUnitName("h2PU");
return em;
}
@Bean(name = "mysqlEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory(@Qualifier("mysqlDataSource") DataSource dataSource) {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource);
em.setPackagesToScan("cn.juwatech.model.mysql");
em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
em.setPersistenceUnitName("mysqlPU");
return em;
}
@Primary
@Bean(name = "h2TransactionManager")
public PlatformTransactionManager h2TransactionManager(@Qualifier("h2EntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
@Bean(name = "mysqlTransactionManager")
public PlatformTransactionManager mysqlTransactionManager(@Qualifier("mysqlEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
3. 启用JPA仓库
为每个数据源分别配置JPA仓库。
package cn.juwatech.config;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@Configuration
@EnableJpaRepositories(
basePackages = "cn.juwatech.repository.h2",
entityManagerFactoryRef = "h2EntityManagerFactory",
transactionManagerRef = "h2TransactionManager"
)
@EntityScan(basePackages = "cn.juwatech.model.h2")
public class H2DataSourceConfig {
}
@Configuration
@EnableJpaRepositories(
basePackages = "cn.juwatech.repository.mysql",
entityManagerFactoryRef = "mysqlEntityManagerFactory",
transactionManagerRef = "mysqlTransactionManager"
)
@EntityScan(basePackages = "cn.juwatech.model.mysql")
public class MysqlDataSourceConfig {
}
三、定义实体类
在不同的包中定义不同数据源的实体类。
package cn.juwatech.model.h2;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class H2Entity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
// getters and setters
}
package cn.juwatech.model.mysql;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class MysqlEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
// getters and setters
}
四、定义仓库接口
为每个数据源定义对应的仓库接口。
package cn.juwatech.repository.h2;
import cn.juwatech.model.h2.H2Entity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface H2EntityRepository extends JpaRepository<H2Entity, Long> {
}
package cn.juwatech.repository.mysql;
import cn.juwatech.model.mysql.MysqlEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface MysqlEntityRepository extends JpaRepository<MysqlEntity, Long> {
}
五、测试多数据源配置
最后,我们编写一个测试类,验证多数据源配置是否成功。
package cn.juwatech;
import cn.juwatech.model.h2.H2Entity;
import cn.juwatech.model.mysql.MysqlEntity;
import cn.juwatech.repository.h2.H2EntityRepository;
import cn.juwatech.repository.mysql.MysqlEntityRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MultiDataSourceApplication implements CommandLineRunner {
@Autowired
private H2EntityRepository h2EntityRepository;
@Autowired
private MysqlEntityRepository mysqlEntityRepository;
public static void main(String[] args) {
SpringApplication.run(MultiDataSourceApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
H2Entity h2Entity = new H2Entity();
h2Entity.setName("H2 Entity");
h2EntityRepository.save(h2Entity);
MysqlEntity mysqlEntity = new MysqlEntity();
mysqlEntity.setName("MySQL Entity");
mysqlEntityRepository.save(mysqlEntity);
System.out.println("H2 Entities: " + h2EntityRepository.findAll());
System.out.println("MySQL Entities: " + mysqlEntityRepository.findAll());
}
}
总结
通过本文的介绍,我们展示了如何在Spring Data中配置和使用多个数据源。我们首先配置了数据源,然后为每个数据源创建了单独的配置类和JPA仓库,最后验证了多数据源配置的正确性。这个示例展示了Spring Boot在处理多数据源时的灵活性和强大功能,希望对大家有所帮助。