Spring Boot +JPA怎么配置多数据源?

  • 作者: 凯哥Java(公众号:凯哥Java)
  • 工作小总结
  • 时间:2023-06-14 17:49
  • 2045人已阅读
简介 有时候,我们需要在项目中配置多数据源。项目框架是SpringBoot+JPA,怎么配置多数据源呢?一、配置文件添加多数据源配置文件中配置多个数据源。如下:server:  port: 8841spring:  datasource:    admin:     

🔔🔔好消息!好消息!🔔🔔

 如果您需要注册ChatGPT,想要升级ChatGPT4。凯哥可以代注册ChatGPT账号代升级ChatGPT4

有需要的朋友👉:微信号 kaigejava2022

有时候,我们需要在项目中配置多数据源。项目框架是Spring Boot+JPA,怎么配置多数据源呢?

一、配置文件添加多数据源

配置文件中配置多个数据源。如下:

server:
  port: 8841
spring:
  datasource:
    admin:
      url: jdbc:sqlite:D:\data\db\back.db    
      driver-class-name: org.sqlite.JDBC
      username:
      password:
    other:
      url:  jdbc:sqlite:D:\data\db\my-test.db
     
      driver-class-name: org.sqlite.JDBC
  jpa:
    database: mysql
    show-sql: true
    hibernate:
      ddl-auto: update

说明:凯哥使用的是SQLite。MySQL数据库配置类似。如果需要配置的是MySQL多数据源,就改吧改吧。


二、代码添加

2.1:获取数据库配置信息的类

package com.kaigejava.config.datasource;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * @author kaigejava
 * @description         获取多数据源属性的
 * @company kaigejava
 * @since 2023/6/14 14:41
 */
@Component
@Data
public class DataSourceProperties {

    /**
     * admin库相关的数据库配置
     */
    @Value("${spring.datasource.admin.url}")
    private String adminUrl;
    @Value("${spring.datasource.admin.driver-class-name}")
    private String adminDriverClass;


    /**
     * other库相关的配置
     */
    @Value("${spring.datasource.other.url}")
    private String otherUrl;
    @Value("${spring.datasource.other.driver-class-name}")
    private String otherDriverClass;

}


2.2:数据源配置相关的类

package com.kaigejava.config.datasource;

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 javax.annotation.Resource;
import javax.sql.DataSource;

/**
 * @author kaigejava
 * @description
 * @company kaigejava
 * @since 2023/6/14 17:17
 */
@Configuration
public class DataSourceConfig {
    @Resource
    DataSourceProperties dataSourceProperties;

    @Bean
    @ConfigurationProperties("spring.datasource.one")
    @Primary
    DataSource dsOne() {
        return DataSourceBuilder.create()
                .url(dataSourceProperties.getAdminUrl())
                .driverClassName(dataSourceProperties.getAdminDriverClass())
                .build();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.two")
    DataSource dsTwo() {
        return DataSourceBuilder.create()
                .url(dataSourceProperties.getOtherUrl())
                .driverClassName(dataSourceProperties.getOtherDriverClass())
                .build();
    }
}


2.3:配置Admin数据库相关的数据源

package com.kaigejava.config.datasource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
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.transaction.PlatformTransactionManager;

import javax.annotation.Resource;
import javax.sql.DataSource;

/**
 * @author 凯哥Java
 * @description admin数据源
 * @company kaigejava
 * @since 2023/6/14 15:29
 */
@Configuration
@EnableJpaRepositories(basePackages = "com.kaigejava.adminjpa", entityManagerFactoryRef = "localContainerEntityManagerFactoryBeanOne", transactionManagerRef = "transactionManagerOne")
public class AdminDataSourceConfig {


    @Resource
    DataSourceProperties dataSourceProperties;

    @Autowired
    @Qualifier("dsOne")
    DataSource dsOne;

    @Autowired
    JpaProperties jpaProperties;

    @Bean
    @Primary
    LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBeanOne(EntityManagerFactoryBuilder builder) {
        return builder.dataSource(dsOne)
                .packages("com.kaigejava.adminjpa")
                .properties(jpaProperties.getProperties())
                .persistenceUnit("pu1")
                .build();
    }

    @Bean
    @Primary
    PlatformTransactionManager transactionManagerOne(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(localContainerEntityManagerFactoryBeanOne(builder).getObject());
    }



   
}

需要注意:admin是主数据源。所以需要使用@Primary注解标注


2.4:配置另外一个数据库的数据源信息 

package com.kaigejava.config.datasource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
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.transaction.PlatformTransactionManager;

import javax.annotation.Resource;
import javax.sql.DataSource;

/**
 * @author 凯哥Java
 * @description admin数据源
 * @company kaigejava
 * @since 2023/6/14 15:29
 */
@Configuration
@EnableJpaRepositories(basePackages = "com.kaigejava.bussiness",entityManagerFactoryRef = "localContainerEntityManagerFactoryBeanTwo",transactionManagerRef = "transactionManagerTwo")
public class OtherDataSourceConfig {



    @Resource
    DataSourceProperties dataSourceProperties;
    @Autowired
    @Qualifier("dsTwo")
    DataSource dsTwo;

    @Autowired
    JpaProperties jpaProperties;

    @Bean
    LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBeanTwo(EntityManagerFactoryBuilder builder) {
        return builder.dataSource(dsTwo)
                .packages("com.kaigejava.bussiness")
                .properties(jpaProperties.getProperties())
                .persistenceUnit("pu2")
                .build();
    }

    @Bean
    PlatformTransactionManager transactionManagerTwo(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(localContainerEntityManagerFactoryBeanTwo(builder).getObject());
    }


   
}


三:测试类

package com.kaigejava.bussiness.tstudenttest.controller;

import com.kaigejava.bussiness.tstudenttest.entity.StudentJpaEntity;
import com.kaigejava.bussiness.tstudenttest.service.IStudentJpaService;
import com.kaigejava.adminjpa.project.entity.ProjectJpaEntity;
import com.kaigejava.adminjpa.project.service.ProjectJpaService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

/**
 * @author 凯哥Java
 * @description
 * @company 凯哥Java
 * @since 2023/6/14 15:53
 */
@RestController
@RequestMapping("/student-test")
public class StudentController {

    //other数据库的
    @Resource
    private IStudentJpaService studentJpaService;

    //admin数据库的
    @Resource
    private ProjectJpaService projectJpaService;

    //向other数据库添加数据
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public StudentJpaEntity save(@RequestBody StudentJpaEntity paramaVo) {
        return studentJpaService.saveInfo(paramaVo);
    }


    //访问other数据库的
    @RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
    public StudentJpaEntity get(@PathVariable("id") Integer id) {
        return studentJpaService.findInfoById(id);
    }

    //访问admin数据库的
    @RequestMapping(value = "/getProject/{id}", method = RequestMethod.GET)
    public ProjectJpaEntity getProject(@PathVariable("id") Integer id) {
        return projectJpaService.findById(id);
    }



}


通过接口调用,向other数据库中添加数据

cbe425dbd8c005f06639e8999ba4fcf8.png

运行结果:

0c0408eb2e88ef5ed66dfd722cd618d8.png

同样方法,测试从admin库中获取数据,也正常。

至此,Spring Boot +JPA配置多数据源就完成了。



填坑:

这里最终要的一个坑是:Hibernate中的数据库方言配置,很多博文都没有此步,导致不同类型的数据库连接时依然用同一种数据库方言

org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect文章来源地址https://www.yii666.com/blog/48058.html?action=onAll

此日志就是数据库方言的内容,两个数据源都会加载各自的数据库方言。

6601c62eaf78a037134d858acfb9a3f2.png





TopTop