首页 > 其他分享 >springboot Jpa多数据源(不同库)配置

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

时间:2024-03-06 17:57:42浏览次数:30  
标签:jpa springboot Jpa 数据源 springframework spring import org

原文链接: https://cloud.tencent.com/developer/article/2147878?areaSource=102001.2&traceId=pjZ5wzrM7kIDFLonYcL2O

一、前言

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
  1. Paging query needs to have a Pageable parameter!

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

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

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

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

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

标签:jpa,springboot,Jpa,数据源,springframework,spring,import,org
From: https://www.cnblogs.com/fswhq/p/18057187

相关文章

  • SpringBoot整合Log4j2日志框架
    SpringBoot底层默认使用logback日志框架。切换使用Log4j2日志框架。pom.xml配置<!--web场景启动器--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> <!--排除默认日志框架--><......
  • springboot3+vue3(四.2)ThreadLocal优化
    解决痛点:我们在拦截器内已经获取并解析了一遍token数据,如图:然后在获取当前登录用户详细信息时又做了一遍同样的操作,如图:后续如果说需要用到当前登录用户的信息时都要带上token参数,这样是很冗余的。这时就会用到ThreadLocal来进行优化处理。 ThreadLocal工具类/***......
  • SpringBoot集成亚马逊的S3对象存储
    依赖导入:aws-java-sdk-s3<dependencyManagement><dependencies><dependency><groupId>com.amazonaws</groupId><artifactId>aws-java-sdk-bom</artifactId>......
  • SpringBoot中集成LiteFlow(轻量、快速、稳定可编排的组件式规则引擎)实现复杂业务解耦
    场景在业务开发中,经常遇到一些串行或者并行的业务流程问题,而业务之间不必存在相关性。使用策略和模板模式的结合可以解决这个问题,但是使用编码的方式会使得文件太多,在业务的部分环节可以这样操作,在项目角度就无法一眼洞穿其中的环节和逻辑。一些拥有复杂业务逻辑的系统,核心业......
  • SpringBoot整合Caffeine本地缓存
    一、Caffeine性能二、Caffeine配置注意:1、weakValues和softValues不可以同时使用。2、maximumSize和maximumWeight不可以同时使用。3、expireAfterWrite和expireAfterAccess同事存在时,以expireAfterWrite为准。三、软引用和弱引用软引用:如果一个对象只具有......
  • springboot集成neo4j
    1创建一个springboot项目引入neo4j的依赖<!--neo4j依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-neo4j</artifactId></dependency>......
  • springboot 应用程序 pom节点版本冲突问题解决思路
    springboot应用程序pom节点版本冲突问题解决思路一、首先 mavenhelper 查看是否有冲突 conflicts 二、allDenpendencies  查询如poi 查询冲突 ps: <scope>compile</scope>  compile:这是默认的依赖项范围。指定为compile的依赖项将在编译、测试和......
  • springboot - 配置文件 @ConfigurationProperties
    1.简单属性@Configuration@ConfigurationProperties(prefix="mail")publicclassConfigProperties{privateStringhostName;privateintport;privateStringfrom;//standardgettersandsetters}注意:如果我们不在POJO中使用@Configurati......
  • SpringBoot中try/catch异常并回滚事务(自动回滚/手动回滚/部分回滚)
    https://www.cnblogs.com/cfas/p/16423510.html https://www.cnblogs.com/konglxblog/p/16229175.htmlSpringBoot异常处理回滚事务详解(自动回滚、手动回滚、部分回滚)(事务失效) 参考:https://blog.csdn.net/zzhongcy/article/details/102893309概念事务定义事务,就是一......