springboot Jpa多数据源(不同库)配置过程

 更新时间:2024年05月06日 09:38:05   作者:Mr-Wanter  
这篇文章主要介绍了springboot Jpa多数据源(不同库)配置过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

一、前言

springboot版本不同对多数据源配置代码有一定影响,部分方法和配置略有不同。

本文采用的springboot版本为2.3.12,数据源为mysql和postgresql

二、配置实战

2.1 基础pom

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>
	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
		<version>5.1.21</version>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-data-jpa</artifactId>
	</dependency>
	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
		<version>${mysql.version}</version>
	</dependency>
</dependencies>

2.2 配置文件

spring.datasource.mysql.jdbc-url=jdbc:mysql://localhost:3306/heilongjiang?characterEncoding=UTF-8&useSSL=false&useTimezone=true&serverTimezone=GMT%2B8
spring.datasource.mysql.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.mysql.username=root
spring.datasource.mysql.password=123456

spring.datasource.pg.jdbc-url=jdbc:postgresql://localhost:5432/hljsyjt?useUnicode=true&characterEncoding=utf8&currentSchema=emergencydev,expert,public
spring.datasource.pg.driver-class-name=org.postgresql.Driver
spring.datasource.pg.username=postgres
spring.datasource.pg.password=postgres

spring.jpa.properties.hibernate.mysql-dialect=org.hibernate.dialect.MySQLDialect
spring.jpa.properties.hibernate.pg-dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false

2.3 数据源配置类

package com.gsafety.bg.industrial.config;

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;


/**
 * @author Mr.wanter
 * @time 2021-8-11 0011
 * @description
 */

@Configuration
public class DataSourceConfig {

    @Bean("dataSourceMysql")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.mysql")
    public DataSource dataSourceMysql() {
        return DataSourceBuilder.create().build();
    }


    @Bean("dataSourcePg")
    @ConfigurationProperties(prefix = "spring.datasource.pg")
    public DataSource dataSourcePg() {
        return DataSourceBuilder.create().build();
    }
}

2.4 数据源指定配置类

mysql指定数据源:

package com.gsafety.bg.industrial.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
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.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Mr.wanter
 * @time 2021-8-11 0011
 * @description
 */

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "entityManagerFactoryMysql",//配置连接工厂 entityManagerFactory
        transactionManagerRef = "transactionManagerMysql", //配置 事物管理器  transactionManager
        basePackages = {"com.gsafety.bg.industrial.dao"}//设置持久层所在位置
)
public class MysqlDataSourceConfig {

    @Autowired
    private JpaProperties jpaProperties;

    @Autowired
    private HibernateProperties hibernateProperties;
    // 自动注入配置好的数据源
    @Autowired
    @Qualifier("dataSourceMysql")
    private DataSource mysqlDataSource;
    // 获取对应的数据库方言
    @Value("${spring.jpa.properties.hibernate.mysql-dialect}")
    private String mysqlDialect;

    /**
     * @param builder
     * @return
     */
    @Bean(name = "entityManagerFactoryMysql")
    @Primary
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryMysql(EntityManagerFactoryBuilder builder) {
        Map<String, String> map = new HashMap<>();
        // 设置对应的数据库方言
        map.put("hibernate.dialect", mysqlDialect);
        jpaProperties.setProperties(map);
        Map<String, Object> properties = hibernateProperties.determineHibernateProperties(
                jpaProperties.getProperties(), new HibernateSettings());
        return builder
                //设置数据源
                .dataSource(mysqlDataSource)
                //设置数据源属性
                .properties(properties)
                //设置实体类所在位置.扫描所有带有 @Entity 注解的类
                .packages("com.gsafety.bg.industrial.dao.po")
                // Spring会将EntityManagerFactory注入到Repository之中.有了 EntityManagerFactory之后,
                // Repository就能用它来创建 EntityManager 了,然后 EntityManager 就可以针对数据库执行操作
                .persistenceUnit("mysqlPersistenceUnit")
                .build();
    }

    /**
     * 配置事物管理器
     *
     * @param builder
     * @return
     */
    @Bean(name = "transactionManagerMysql")
    @Primary
    PlatformTransactionManager transactionManagerMysql(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactoryMysql(builder).getObject());
    }

}

pg指定数据源:

package com.gsafety.bg.industrial.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
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.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Mr.wanter
 * @time 2021-8-11 0011
 * @description
 */

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "entityManagerFactoryPg",//配置连接工厂 entityManagerFactory
        transactionManagerRef = "transactionManagerPg", //配置 事物管理器  transactionManager
        basePackages = {"com.gsafety.bg.data.dao"}//设置持久层所在位置
)
public class PgDataSourceConfig {

    @Autowired
    private JpaProperties jpaProperties;

    @Autowired
    private HibernateProperties hibernateProperties;
    //自动注入配置好的数据源
    @Autowired
    @Qualifier("dataSourcePg")
    private DataSource PgDataSource;
    // 获取对应的数据库方言
    @Value("${spring.jpa.properties.hibernate.pg-dialect}")
    private String pgDialect;

    /**
     * @param builder
     * @return
     */
    @Bean(name = "entityManagerFactoryPg")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryPg(EntityManagerFactoryBuilder builder) {
        Map<String, String> map = new HashMap<>();
        // 设置对应的数据库方言
        map.put("hibernate.dialect", pgDialect);
        jpaProperties.setProperties(map);
        Map<String, Object> properties = hibernateProperties.determineHibernateProperties(
                jpaProperties.getProperties(), new HibernateSettings());
        return builder
                //设置数据源
                .dataSource(PgDataSource)
                //设置数据源属性
                .properties(properties)
                //设置实体类所在位置.扫描所有带有 @Entity 注解的类
                .packages("com.gsafety.bg.data.dao.po")
                // Spring会将EntityManagerFactory注入到Repository之中.有了 EntityManagerFactory之后,
                // Repository就能用它来创建 EntityManager 了,然后 EntityManager 就可以针对数据库执行操作
                .persistenceUnit("pgPersistenceUnit")
                .build();

    }

    /**
     * 配置事物管理器
     *
     * @param builder
     * @return
     */
    @Bean(name = "transactionManagerPg")
    PlatformTransactionManager transactionManagerPg(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactoryPg(builder).getObject());
    }

}

2.5 如何应用

数据源配置类中指定了扫描po和dao包的路径

例如entityManagerFactoryPg中的com.gsafety.bg.data.dao.po和com.gsafety.bg.data.dao

那么我们只需要在指定的包下创建po和dao即可,service包层次不受影响,自定义即可。

三数据源同理即可。

左侧为双数据源(与本篇实战内容一致),右侧为三数据源(三数据源目录结构示例)。

其他编码常规开发即可

  • po:
@Entity
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "jc_repertory")
public class JcRepertoryPO implements Serializable {

  //some fields

}
  • dao:
public interface JcRepertoryDao extends JpaRepository<JcRepertoryPO, String>, JpaSpecificationExecutor<JcRepertoryPO> {

}
  • service:
public interface JcRepertoryService {

    List<JcRepertoryPO> list();

}
@Service
public class JcRepertoryServiceImpl implements JcRepertoryService {

    @Resource
    private JcRepertoryDao jcRepertoryDao;

    @Override
    public List<JcRepertoryPO> list() {
        List<JcRepertoryPO> all = jcRepertoryDao.findAll();
        return all;
    }
}
  • controller 略

启动类添加扫描

@SpringBootApplication_(_scanBasePackages = _{_"com.gsafety.bg.data", "com.gsafety.bg.industrial"_})_

三、遇到的问题 数据库连接报错

1.jdbcUrl is required with driverClassName

  • 主要原因是在1.0 配置数据源的过程中主要是写成:spring.datasource.url 和spring.datasource.driverClassName。
  • 而在2.0升级之后需要变更成:spring.datasource.jdbc-url和spring.datasource.driver-class-name
spring.datasource.pg.jdbc-url=jdbc:postgresql://localhost:5432/hljsyjt?useUnicode=true&characterEncoding=utf8&currentSchema=emergencydev,expert,public
spring.datasource.pg.driver-class-name=org.postgresql.Driver

2.Paging query needs to have a Pageable parameter!

  • 原系统中对jap的Repository进行了封装,采用常规方式调用即可。

3.more than one ‘primary’ bean found among candidates

  • 2.4 数据源指定配置类 中只有一个类中的方法添加 @Primary 另外一个不要加这个注解

4.互联网查询的代码中JpaProperties没有getHibernateProperties

  • 与springboot版本有关,上面代码已修改。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • spring cloud学习入门之config配置教程

    spring cloud学习入门之config配置教程

    这篇文章主要给大家介绍了关于spring cloud学习入门之config配置的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用spring cloud具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-09-09
  • java Signleton模式详解及示例代码

    java Signleton模式详解及示例代码

    Singleton模式是创建模式。这种模式只涉及一个类是负责创建自己的对象。该类确保只有一个对象获得创建。这个类提供了一种方法来访问它的唯一对象
    2016-10-10
  • 深入理解 Java 中的 Switch 语句示例详解

    深入理解 Java 中的 Switch 语句示例详解

    在Java编程中,switch语句通过表达式值来执行不同代码块,本文介绍switch语法、案例、注意事项,以及与if语句的对比,包括基本语法、关键字、表达式、case常量、break和default的使用,以及如何根据输入的字符输出星期、大小写转换、成绩判断和季节判断等实际应用场景
    2024-10-10
  • Java基础面试题之volatile详解

    Java基础面试题之volatile详解

    Volatile可以看做是轻量级的 Synchronized,它只保证了共享变量的可见性,下面这篇文章主要给大家介绍了关于Java基础面试题之volatile的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • 因不会远程debug调试我被项目经理嘲笑了

    因不会远程debug调试我被项目经理嘲笑了

    这篇文章主要介绍了远程debug调试的相关内容,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-08-08
  • springboot整合多数据源配置方式

    springboot整合多数据源配置方式

    这篇文章主要介绍了springboot整合多数据源配置,多数据源整合springboot+mybatis使用分包方式整合,springboot+druid+mybatisplus使用注解整合,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2021-12-12
  • 浅谈java中null是什么,以及使用中要注意的事项

    浅谈java中null是什么,以及使用中要注意的事项

    下面小编就为大家带来一篇浅谈java中null是什么,以及使用中要注意的事项。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • Spring如何利用@Value注解读取yml中的map配置

    Spring如何利用@Value注解读取yml中的map配置

    这篇文章主要介绍了Spring如何利用@Value注解读取yml中的map配置,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • httpclient的disableConnectionState方法工作流程

    httpclient的disableConnectionState方法工作流程

    这篇文章主要为大家介绍了httpclient的disableConnectionState方法工作流程源码解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • logback EvaluatorFilter日志过滤器源码解读

    logback EvaluatorFilter日志过滤器源码解读

    这篇文章主要为大家介绍了logback EvaluatorFilter日志过滤器源码解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11

最新评论