2025年3月26日 星期三 甲辰(龙)年 月廿五 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Spring Boot

SpringBoot配置双数据源(一个项目同时连接操作两台数据库)

时间:02-13来源:作者:点击数:34

前言:

近期公司要上线3.0版本,需要将2.0的数据迁移到3.0中继续沿用,由于3.0的数据库相比2.0.的数据库改动很大,最主要的是2.0数据库的主键为自然数自增主键,而3.0数据库的主键为UUID2,所以只能使用程序动态迁移!

声明:

本教程使用的持久化框架为JPA,所以数据源也是基于JPA。采用的是SpringBoot2 + SpringDataJPA + MySQL + 双数据源!

一、双数据源的适用场景:

1、主从库分离(数据库读写分离)

2、数据迁移

3、系统版本升级,数据库升级到另外一款

二、application.yml中配置

  • spring:
  • jpa:
  • hibernate:
  • ddl-auto: create
  • naming:
  • physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
  • implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
  • open-in-view: true
  • show-sql: true
  • generate-ddl: true
  • datasource: #database
  • primary: # 3.0 Datasource
  • jdbc-url: jdbc:mysql://127.0.0.1:3306/gtu?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
  • username: root
  • password: 123456
  • secondary: # 2.0 Datasource
  • jdbc-url: jdbc:mysql://127.0.0.1:3306/gtu-not-completed?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
  • username: root
  • password: 123456

注:配置文件中需要指定两个数据源,这里在配置的时候是没有自动提示的,因为这是我们自定义的,需要在程序中动态读取。

三、读取application.yml配置的两个数据源,并将其注入到Spring的IOC容器中

  • @Configuration
  • public class DataSourceConfig {
  • @Bean(name = "primaryDataSource")
  • @Qualifier("primaryDataSource")
  • @Primary
  • @ConfigurationProperties(prefix = "spring.datasource.primary")
  • public DataSource primaryDataSource() {
  • return DataSourceBuilder.create().build();
  • }
  • @Bean(name = "secondaryDataSource")
  • @Qualifier("secondaryDataSource")
  • @ConfigurationProperties(prefix = "spring.datasource.secondary")
  • public DataSource secondaryDataSource() {
  • return DataSourceBuilder.create().build();
  • }
  • }

注解解释:

@Configuration:SpringBoot启动将该类作为配置类,同配置文件一起加载

@Bean:将该实体注入到IOC容器中

@Qualifier:指定数据源名称,与Bean中的name属性原理相同,主要是为了确保注入成功

@Primary:指定主数据源

@ConfigurationProperties:将配置文件中的数据源读取进到方法中,进行build

四、以类的方式配置两个数据源

(1)主数据源(对应DataSourceConfig类中的primaryDataSource)

  • @Configuration
  • @EnableTransactionManagement
  • @EnableJpaRepositories(
  • entityManagerFactoryRef = "entityManagerFactoryPrimary",
  • transactionManagerRef = "transactionManagerPrimary",
  • basePackages = {"com.gtcloud.repository"}) // 指定该数据源操作的DAO接口包
  • public class PrimaryConfig {
  • @Autowired
  • @Qualifier("primaryDataSource")
  • private DataSource primaryDataSource;
  • @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)
  • .properties(getVendorProperties())
  • .packages("com.gtcloud.model") //设置实体类所在位置
  • .persistenceUnit("primaryPersistenceUnit")
  • .build();
  • }
  • private Map getVendorProperties() {
  • HashMap<String, Object> properties = new HashMap<>();
  • properties.put("hibernate.dialect",
  • env.getProperty("hibernate.dialect"));
  • properties.put("hibernate.ddl-auto",
  • "create");
  • properties.put("hibernate.physical_naming_strategy",
  • "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");
  • properties.put("hibernate.implicit_naming_strategy",
  • "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy");
  • return properties;
  • }
  • @Autowired
  • private Environment env;
  • @Primary
  • @Bean(name = "transactionManagerPrimary")
  • public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
  • return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
  • }
  • }

(2)从(次)数据源

  • @Configuration
  • @EnableTransactionManagement
  • @EnableJpaRepositories(
  • entityManagerFactoryRef = "entityManagerFactorySecondary",
  • transactionManagerRef = "transactionManagerSecondary",
  • basePackages = {"com.gtmove.repository"}) //设置DAO接口层所在包位置
  • public class SecondaryConfig {
  • @Autowired
  • @Qualifier("secondaryDataSource")
  • private DataSource secondaryDataSource;
  • @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)
  • .properties(getVendorProperties())
  • .packages("com.gtmove.model") //设置实体类所在包的位置
  • .persistenceUnit("primaryPersistenceUnit")
  • .build();
  • }
  • private Map getVendorProperties() {
  • HashMap<String, Object> properties = new HashMap<>();
  • properties.put("hibernate.hbm2ddl.auto",
  • env.getProperty("hibernate.hbm2ddl.auto"));
  • properties.put("hibernate.ddl-auto",
  • env.getProperty("update"));
  • properties.put("hibernate.dialect",
  • env.getProperty("hibernate.dialect"));
  • properties.put("hibernate.physical_naming_strategy",
  • "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");
  • properties.put("hibernate.implicit_naming_strategy",
  • "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy");
  • return properties;
  • }
  • @Autowired
  • private Environment env;
  • @Bean(name = "transactionManagerSecondary")
  • PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
  • return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
  • }
  • }

这两个类主要配置每个数据源,包括事务管理器、以及实体管理器等配置。

注:必须要指定DAO接口所在的包以及实体类所在的包。每个数据源主要操作它指定的资源(DAO接口CURD、实体类)

五、注意点:

1、SpringBoot启动类必须关闭 --程序启动加载的仓库(@EnableJpaRepositories),因为在数据源配置类中已经开启了。如果没有去掉,程序会跑不起来!

  • @SpringBootApplication(scanBasePackages = {""}) // 指定加载程序主包,存在默认值【可选】
  • //@EntityScan({""})
  • //@EnableJpaRepositories(basePackages = {""})
  • public class Gt3datamoverApplication {
  • public static void main(String[] args) {
  • SpringApplication.run(Gt3datamoverApplication.class, args);
  • }
  • }

2、如果需要对数据源连接的表进行DDL(正向生成表、程序启动动态更新表),需要在PrimaryConfig类中 /SecondaryConfig类中的getVendorProperties()方法中进行手动设置(此教程都已设置好了!)

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门