springboot+jpa 配置多数据源

springboot+jpa 配置多数据源

使用的springboot的版本是2.2.5

项目结构是

在这里插入图片描述

1.在配置文件中添加如下依赖

       <dependency>
		 	<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-configuration-processor</artifactId>
 			<optional>true</optional>
		</dependency>
		<dependency>
 			<groupId>mysql</groupId>
 			<artifactId>mysql-connector-java</artifactId>
 			<version>5.1.34</version>
			<!-- <scope>runtime</scope>-->
		</dependency>

2.application.yml文件的配置

   server:
 port: 8081
spring:
 datasource:
 first:
 driver-class-name: com.mysql.jdbc.Driver
 jdbc-url: jdbc:mysql://localhost:3306/testa?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
 username: datahub
 password: datahub
 second:
 driver-class-name: com.mysql.jdbc.Driver
 jdbc-url: jdbc:mysql://localhost:3306/testb?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
 username: datahub
 password: datahub
 jpa:
 hibernate:
 ddl-auto: update
 naming:
 physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
 implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
 show-sql: true
 database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
 database: mysql
 redis:
 database: 0
 host: localhost
 port: 6379
 password:
 jedis:
 pool:
# 最大连接数,负数表示没有限制
 max-active: 8
# 最大阻塞等待时间,负数没有限制
 max-wait: -1
# 最大空闲连接
 max-idle: 10
# 最小空闲连接
 min-idle: 1
# 连接超时时间(ms)
 timeout: 1000

备注:这里参数可以随便配置,但是使用spring原生的要对应名称配置。url必须使用jdbc-url的名称

jpa的其他参数,主要是在jpaProperties里面

3.为多数据源配置相应的bean类

3.1 配置DataSourceConfiguration类
package com.example.config;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
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.sql.DataSource;
@Configuration
public class DataSourceConfiguration {
 /**
 * 第一个数据连接,默认优先级最高
 * @return
 */
 @Bean(name = "dataSourceFirst")
 @Primary
 @ConfigurationProperties(prefix = "spring.datasource.first")
 public DataSource dataSourceFirst(DataSourceProperties properties){
 //这种方式的配置默认只满足spring的配置方式,如果使用其他数据连接(druid),需要自己独立获取配置
 return DataSourceBuilder.create().build();
// return DataSourceBuilder.create(properties.getClassLoader())
// .type(HikariDataSource.class)
// .driverClassName(properties.determineDriverClassName())
// .url(properties.determineUrl())
// .username(properties.determineUsername())
// .password(properties.determinePassword())
// .build();
 }
 /**
 * 第二个数据源
 * @return
 */
 @Bean(name = "dataSourceSecond")
 @ConfigurationProperties(prefix = "spring.datasource.second")
 public DataSource dataSourceSecond(DataSourceProperties properties){
 return DataSourceBuilder.create().build();
// return DataSourceBuilder.create(properties.getClassLoader())
// .type(HikariDataSource.class)
// .driverClassName(properties.determineDriverClassName())
// .url(properties.determineUrl())
// .username(properties.determineUsername())
// .password(properties.determinePassword())
// .build();
 }
}
3.2 为每一个数据源配置相应的jpa相关配置
第一个数据源的配置JpaFirstConfiguration类
package com.example.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
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.orm.jpa.vendor.Database;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;
@Configuration
@EnableJpaRepositories(
 entityManagerFactoryRef = "entityManagerFactoryPrimary",
 transactionManagerRef = "transactionManagerPrimary",
 basePackages = {"com.example.repository.first"}
)
@EnableTransactionManagement
public class JpaFirstConfiguration {
 @Autowired
 private HibernateProperties hibernateProperties;
 @Autowired
 private JpaProperties jpaProperties;
 @Autowired
 @Qualifier("dataSourceFirst")
 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) {
 jpaProperties.setShowSql(true);
 jpaProperties.setDatabase(Database.MYSQL);
 jpaProperties.setDatabasePlatform("org.hibernate.dialect.MySQL5Dialect");
 jpaProperties.setGenerateDdl(true);
 jpaProperties.setOpenInView(true);
 Map<String, Object> properties = hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
 return builder
 .dataSource(primaryDataSource)
 .packages("com.example.domain.first") //设置实体类所在位置
 .persistenceUnit("primaryPersistenceUnit")
 .properties(properties)
 .build();
 }
 @Primary
 @Bean(name = "transactionManagerPrimary")
 public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
 return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
 }
}
第二个数据源的配置JpaSecondConfiguration类
package com.example.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
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.orm.jpa.vendor.Database;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;
@Configuration
@EnableJpaRepositories(
 entityManagerFactoryRef = "entityManagerFactorySecondary",
 transactionManagerRef = "transactionManagerSecondary",
 basePackages = {"com.example.repository.second"}
)
@EnableTransactionManagement
public class JpaSecondConfiguration {
 @Autowired
 private HibernateProperties hibernateProperties;
 @Autowired
 private JpaProperties jpaProperties;
 @Autowired
 @Qualifier("dataSourceSecond")
 private DataSource secondaryDataSource;
 @Primary
 @Bean(name = "entityManagerSecondary")
 public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
 return entityManagerFactorySecondary(builder).getObject().createEntityManager();
 }
 @Bean(name = "entityManagerFactorySecondary")
 public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary (EntityManagerFactoryBuilder builder) {
 jpaProperties.setShowSql(true);
 jpaProperties.setDatabase(Database.MYSQL);
 jpaProperties.setDatabasePlatform("org.hibernate.dialect.MySQL5Dialect");
 jpaProperties.setGenerateDdl(true);
 jpaProperties.setOpenInView(true);
 Map<String, Object> properties = hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
 return builder
 .dataSource(secondaryDataSource)
 .packages("com.example.domain.second") //设置实体类所在位置
 .persistenceUnit("secondaryPersistenceUnit")
 .properties(properties)
 .build();
 }
 @Bean(name = "transactionManagerSecondary")
 public PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
 return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
 }
}

然后在项目中写两个测试类验证配置是否生效。

4.在配置时遇到的问题及解决方法:

1.一开始的时候在配置工厂类的时候有一行用到的是jpaProperties.getHibernateProperties(new HibernateSettings()),但是在我的项目里面,找不到这个方法。

错误原因:与springboot的版本有关,在springboot2.0.0版本以后,该方法已经被替换掉了,具体的解决方法是可以用下面的一行替代。

hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings())

2.启动报错Access to DialectResolutionInfo cannot be null when ‘hibernate.dialect’ not set

错误原因:因为是自己写的JPA的Confgration,并不是springboot自动配置,所以在application.yml中的JPA配置不会起作用的,需要自己在Confgration类里边自已配置好hibernate.dialect属性

配置方式如下:

 jpaProperties.setShowSql(true);
 jpaProperties.setDatabase(Database.MYSQL);
 jpaProperties.setDatabasePlatform("org.hibernate.dialect.MySQL5Dialect");
 jpaProperties.setGenerateDdl(true);
 jpaProperties.setOpenInView(true);

3.mysql的驱动版本不对,记得换对应数据库版本的驱动包

4、将pom文件中的<packaging>pom</packaging>给注释掉

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张同学想摸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值