当前位置: 首页 > article >正文

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>给注释掉


http://www.kler.cn/news/361960.html

相关文章:

  • MySQL-23.多表查询-内连接
  • 宇音天下最新力作 | VTX356语音识别合成芯片问世
  • vscode 预览markdown 文件
  • 什么是感知与计算融合?
  • 我国首个自主可控的操作系统——华为原生鸿蒙操作系统正式发布
  • 搭建微信AI机器人
  • LabVIEW提高开发效率技巧----高效文件I/O
  • 微信小程序上传图片添加水印
  • ARM/Linux嵌入式面经(四六):华为
  • transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)的计算过程
  • qt5.12.12插件机制无法加载插件问题
  • 毕业生找工作的攻略:从校园到职场的成功之路
  • R语言绘图——文本注释
  • LLaMA Factory环境配置
  • 猎板高频PCB的制成能力分享
  • CISAW安全集成,协助组织构建坚固的信息防护堡垒
  • 【一站式学会Kotlin】第二十五 Kotlin内部类和嵌套类的区别和案例
  • 智慧交通新征程:亿维锐创与图为科技达成战略合作
  • STM32+CubeMX -- 开发辅助工具
  • 蓝桥杯基本操作和运算
  • 【某农业大学计算机网络实验报告】实验一 集线器和交换机的对比
  • excel将文本型数字转变为数值型数字
  • ppt模板一键套用怎么操作?制作ppt基础步骤手把手教你
  • Java中的异步编程模型
  • LN9361 低噪声电荷泵 DC/DC 转换器
  • 什么是缓存?