Spring Boot +JPA怎么配置多数据源?
- 工作小总结
- 时间:2023-06-14 17:49
- 2916人已阅读
简介
有时候,我们需要在项目中配置多数据源。项目框架是SpringBoot+JPA,怎么配置多数据源呢?一、配置文件添加多数据源配置文件中配置多个数据源。如下:server: port: 8841spring: datasource: admin:
🔔🔔🔔好消息!好消息!🔔🔔🔔
有需要的朋友👉:联系凯哥
有时候,我们需要在项目中配置多数据源。项目框架是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数据库中添加数据

运行结果:

同样方法,测试从admin库中获取数据,也正常。
至此,Spring Boot +JPA配置多数据源就完成了。
填坑:
这里最终要的一个坑是:Hibernate中的数据库方言配置,很多博文都没有此步,导致不同类型的数据库连接时依然用同一种数据库方言
org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
此日志就是数据库方言的内容,两个数据源都会加载各自的数据库方言。
