Spring Boot+Jpa多数据源配置的完整步骤

关于

有时候,随着业务的发展,项目关联的数据来源会变得越来越复杂,使用的数据库会比较分散,这个时候就会采用多数据源的方式来获取数据。另外,多数据源也有其他好处,例如分布式数据库的读写分离,集成多种数据库等等。

下面分享我在实际项目中配置多数据源的案例。话不多说了,来一起看看详细的介绍吧

步骤

1.application.yml文件中,配置数据库源。这里primary是主库,secondary是从库。

server:
 port: 8089

# 多数据源配置
#primary
spring:
 primary:
 datasource:
  url: jdbc:mysql://127.0.0.1:3306/database1?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
  username: root
  password: ******
  driver-class-name: com.mysql.jdbc.Driver

 #secondary
 secondary:
 datasource:
  url: jdbc:mysql://127.0.0.1:3306/database1?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
  username: root
  password: ******
  driver-class-name: com.mysql.jdbc.Driver

 jpa:
 hibernate:
  primary-dialect: org.hibernate.dialect.MySQL5Dialect
  secondary-dialect: org.hibernate.dialect.MySQL5Dialect
 open-in-view: true
 show-sql: true

2.创建一个Spring配置类,其中spring.primary.datasource的路径参考yml文件的配置。

@Configuration
public class DataSourceConfig {

 @Bean(name = "primaryDataSource")
 @Qualifier("primaryDataSource")
 @ConfigurationProperties(prefix="spring.primary.datasource")
 public DataSource primaryDataSource() {
  return DataSourceBuilder.create().build();
 }

 @Bean(name = "secondaryDataSource")
 @Qualifier("secondaryDataSource")
 @Primary
 @ConfigurationProperties(prefix="spring.secondary.datasource")
 public DataSource secondaryDataSource() {
  return DataSourceBuilder.create().build();
 }

}

3.分别创建主库、从库的配置类。

注意:entity包和dao包的配置,以及@Primary注解指定主库。

主库配置类:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
  entityManagerFactoryRef = "entityManagerFactoryPrimary",
  transactionManagerRef = "transactionManagerPrimary",
  basePackages = {"com.infinitus.yunxiao_data.dao.primary"}) //设置Repository所在位置
public class PrimaryConfig {
 @Autowired
 private JpaProperties jpaProperties;

 @Autowired
 @Qualifier("primaryDataSource")
 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) {
  return builder
    .dataSource(primaryDataSource)
    .properties(getVendorProperties(primaryDataSource))
    .packages("com.infinitus.yunxiao_data.entity.primary") //设置实体类所在位置
    .persistenceUnit("primaryPersistenceUnit")
    .build();
 }

 private Map getVendorProperties(DataSource dataSource) {
  return jpaProperties.getHibernateProperties(dataSource);
 }

 @Primary
 @Bean(name = "transactionManagerPrimary")
 public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
  return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
 }
}

从库的配置类:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
  entityManagerFactoryRef = "entityManagerFactorySecondary",
  transactionManagerRef = "transactionManagerSecondary",
  basePackages = {"com.infinitus.yunxiao_data.dao.secondary"}) //设置Repository所在位置
public class SecondaryConfig {
 @Autowired
 private JpaProperties jpaProperties;

 @Autowired
 @Qualifier("secondaryDataSource")
 private DataSource secondaryDataSource;

 @Bean(name = "entityManagerSecondary")
 public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
  return entityManagerFactorySecondary(builder).getObject().createEntityManager();
 }

 @Bean(name = "entityManagerFactorySecondary")
 public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary(EntityManagerFactoryBuilder builder) {
  return builder
    .dataSource(secondaryDataSource)
    .properties(getVendorProperties(secondaryDataSource))
    .packages("com.infinitus.yunxiao_data.entity.secondary") //设置实体类所在位置
    .persistenceUnit("primaryPersistenceUnit")
    .build();
 }

 private Map getVendorProperties(DataSource dataSource) {
  return jpaProperties.getHibernateProperties(dataSource);
 }

 @Bean(name = "transactionManagerSecondary")
 PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
  return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
 }

}

4.分别创建主、从库dao类。

主dao:

@Repository
public interface PrimaryRepository extends JpaRepository<PrimaryEntity, Long> {

 @Query(value = "SELECT p FROM PrimaryEntity p")
 List<PrimaryEntity> queryList();

}

从dao:

@Repository
public interface SecondaryRepository extends JpaRepository<SecondaryEntity, Long> {

 @Query(value = "SELECT p FROM SecondaryEntity p")
 List<SecondaryEntity> queryList();

}

5.分别创建主、从库entity类。

主entity:

@Entity
@Table(name = "holiday_scheme")
@EntityListeners(AuditingEntityListener.class)
public class PrimaryEntity extends AbstractPersistable<Long> {
 @Column(name = "date")
 public String date;
 @Column(name = "hour")
 public String hour;
 @Column(name = "holiday")
 public String holiday;
 @Column(name = "holiday_explain")
 public String holiday_explain;

 public String getDate() {
  return date;
 }

 public void setDate(String date) {
  this.date = date;
 }

 public String getHour() {
  return hour;
 }

 public void setHour(String hour) {
  this.hour = hour;
 }

 public String getHoliday() {
  return holiday;
 }

 public void setHoliday(String holiday) {
  this.holiday = holiday;
 }

 public String getHoliday_explain() {
  return holiday_explain;
 }

 public void setHoliday_explain(String holiday_explain) {
  this.holiday_explain = holiday_explain;
 }

 @Override
 public String toString() {
  return "PrimaryEntity{" +
    "date='" + date + '\'' +
    ", hour='" + hour + '\'' +
    ", holiday='" + holiday + '\'' +
    ", holiday_explain='" + holiday_explain + '\'' +
    '}';
 }
}

从entity:

@Entity
@Table(name = "active_dashboards")
@EntityListeners(AuditingEntityListener.class)
public class SecondaryEntity extends AbstractPersistable<Long> {

 @Column(name = "dashboard_id")
 public String dashboard_id;
 @Column(name = "user_id")
 public String user_id;
 @Column(name = "order_index")
 public String order_index;

 public String getDashboard_id() {
  return dashboard_id;
 }

 public void setDashboard_id(String dashboard_id) {
  this.dashboard_id = dashboard_id;
 }

 public String getUser_id() {
  return user_id;
 }

 public void setUser_id(String user_id) {
  this.user_id = user_id;
 }

 public String getOrder_index() {
  return order_index;
 }

 public void setOrder_index(String order_index) {
  this.order_index = order_index;
 }

 @Override
 public String toString() {
  return "SecondaryEntity{" +
    "dashboard_id='" + dashboard_id + '\'' +
    ", user_id='" + user_id + '\'' +
    ", order_index='" + order_index + '\'' +
    '}';
 }
}

6.controller请求获取不同数据库的数据。

@RestController
@RequestMapping("/database")
public class MailController {
 private final Logger logger = LoggerFactory.getLogger(this.getClass());

 @Autowired
 PrimaryRepository primaryRepository;
 @Autowired
 SecondaryRepository secondaryRepository;

 @RequestMapping("/primary")
 @ResponseBody
 public String primary() {
  return primaryRepository.queryList().toString();
 }

 @RequestMapping("/secondary")
 @ResponseBody
 public String secondary() {
  return secondaryRepository.queryList().toString();
 }

}

注意

下面提两个在配置多数据源时遇到的坑点,一不注意就掉坑了。

1.Application类不需要配置@EnableJpaRepositories注解,会报如下错误。

A component required a bean named 'entityManagerFactory' that could not be f

2.注意检查dao类,获取数据的方法上格式是否正确,有没有某个字段是表中不存在的,避免启动异常。如下,SecondaryEntity表中是不存在job_name字段的,所以注释掉才能启动成功等。

//@Query(value = "SELECT p FROM SecondaryEntity p where p.job_name = ?1")
//List<SecondaryEntity> queryOdcRecord(String job_name);

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • 使用SpringBoot-JPA进行自定义保存及批量保存功能

    说明 SpringBoot版本:2.1.4.RELEASE java版本:1.8 文中所说JPA皆指spring-boot-starter-data-jpa 使用JPA保存一个Student对象 在JPA中保存一个对象,仅需要该对象,一个仓储即可. StudentDO实体类: @Getter @Setter @Entity @Table(name = "t_student") public class StudentDO { @Id @GeneratedValue(strategy =

  • Spring Boot + Jpa(Hibernate) 架构基本配置详解

    1.基于springboot-1.4.0.RELEASE版本测试 2.springBoot + hibernate + Druid + MySQL + servlet(jsp) 不废话,直接上代码 一.maven的pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=&qu

  • SpringBoot集成Spring Data JPA及读写分离

    相关代码: github OSCchina JPA是什么 JPA(Java Persistence API)是Sun官方提出的Java持久化规范,它为Java开发人员提供了一种对象/关联映射工具 来管理Java应用中的关系数据.它包括以下几方面的内容: 1.ORM映射 支持xml和注解方式建立实体与表之间的映射. 2.Java持久化API 定义了一些常用的CRUD接口,我们只需直接调用,而不需要考虑底层JDBC和SQL的细节. 3.JPQL查询语言 这是持久化操作中很重要的一个方面,通过面向对象

  • 详解SpringBoot实现JPA的save方法不更新null属性

    序言:直接调用原生Save方法会导致null属性覆盖到数据库,使用起来十分不方便.本文提供便捷方法解决此问题. 核心思路 如果现在保存某User对象,首先根据主键查询这个User的最新对象,然后将此User对象的非空属性覆盖到最新对象. 核心代码 直接修改通用JpaRepository的实现类,然后在启动类标记此实现类即可. 一.通用CRUD实现类 public class SimpleJpaRepositoryImpl<T, ID> extends SimpleJpaRepository&l

  • Spring Boot 2.X快速整合jpa过程解析

    一.JPA介绍 JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中. SpringData是Spring的一个子项目.用于简化数据库访问,支持NoSQL和关系数据存储,其主要目标是使数据库的访问变得方便快捷. Spring Data JPA致力于减少数据访问层(DAO)的开发量,开发者唯一要做的就只是声明持久层的接口,其他都交给Spring Data JPA 来帮你完成!

  • SpringBoot系列教程JPA之基础环境搭建的方法

    JPA(Java Persistence API)Java持久化API,是 Java 持久化的标准规范,Hibernate是持久化规范的技术实现,而Spring Data JPA是在 Hibernate 基础上封装的一款框架.JPA作为标准,实际上并没有说局限于某个固定的数据源,事实上mysql,mongo, solr都是ok的.接下来我们将介绍下springboot结合jpa 来实现mysql的curd以及更加复杂一点的sql支持 jpa系列教程将包含以下几块 环境搭建 基础的插入.修改.删除

  • SpringBoot Data JPA 关联表查询的方法

    SpringBoot Data JPA实现 一对多.多对一关联表查询 开发环境 IDEA 2017.1 Java1.8 SpringBoot 2.0 MySQL 5.X 功能需求 通过关联关系查询商店Store中所有的商品Shop,商店对商品一对多,商品对商店多对一,外键 store_id存在于多的一方.使用数据库的内连接语句. 表结构 tb_shop tb_store 实体类,通过注解实现 1.商店类Store.java package com.gaolei.Entity; import ja

  • Spring Boot+Jpa多数据源配置的完整步骤

    关于 有时候,随着业务的发展,项目关联的数据来源会变得越来越复杂,使用的数据库会比较分散,这个时候就会采用多数据源的方式来获取数据.另外,多数据源也有其他好处,例如分布式数据库的读写分离,集成多种数据库等等. 下面分享我在实际项目中配置多数据源的案例.话不多说了,来一起看看详细的介绍吧 步骤 1.application.yml文件中,配置数据库源.这里primary是主库,secondary是从库. server: port: 8089 # 多数据源配置 #primary spring: pri

  • spring boot + quartz集群搭建的完整步骤

    quartz集群能力: quartz集群分为水平集群和垂直集群,水平集群即将定时任务节点部署在不同的服务器,水平集群最大的问题就是时钟同步问题, quartz集群强烈要求时钟同步,若时钟不能同步,则会导致集群中各个节点状态紊乱,造成不可预知的后果,请自行搜索服务器时钟同步, 若能保证时钟同步,水平集群能保证服务的可靠性,其中一个节点挂掉或其中一个服务器宕机,其他节点依然正常服务:垂直集群则是集群各节点部署在同一台服务器, 时钟同步自然不是问题,但存在单点故障问题,服务器宕机会严重影响服务的可用性

  • Spring Boot集成Thymeleaf模板引擎的完整步骤

    简单介绍 目前在JavaEE领域有几中比较常用的模板引擎,分别是Jsp.Velocity.Freemarker.Thymeleaf,对Freemark语法不是特别熟悉,不过对于前端页面渲染效率来说,jsp其实还是最快的,Velocity次之.Thymeleaf虽然渲染效率不是很快,但是语法方面是比较轻巧的,Thymeleaf语法比Velocity轻巧,但是渲染效率不如Velocity thymeleaf 支持html5标准:是一种模板引擎框架(TemplateEngine Framework):

  • 解决spring boot 1.5.4 配置多数据源的问题

    spring boot 已经支持多数据源配置了,无需网上好多那些编写什么类的,特别麻烦,看看如下解决方案,官方的,放心! 1.首先定义数据源配置 #=====================multiple database config============================ #ds1 first.datasource.url=jdbc:mysql://localhost/test?characterEncoding=utf8&useSSL=true first.datasou

  • Spring boot如何快速的配置多个Redis数据源

    简介 redis 多数据源主要的运用场景是在需要使用多个redis服务器或者使用多个redis库,本文采用的是fastdep依赖集成框架,快速集成Redis多数据源并集成lettuce连接池,只需引入依赖后在yaml文件中配置多数据源连接信息即可. 源码地址 希望大家可以star支持一下,后续还会加入其它依赖的简易整合. https://github.com/louislivi/fastdep 引入依赖 Maven <dependency> <groupId>com.louisli

  • 在Spring Boot中加载XML配置的完整步骤

    开篇 在SpringBoot中我们通常都是基于注解来开发的,实话说其实这个功能比较鸡肋,但是,SpringBoot中还是能做到的.所以用不用是一回事,会不会又是另外一回事. 涛锅锅在个人能力能掌握的范围之内,一般是会得越多越好,都是细小的积累,发生质的改变,所以今天和小伙伴们一起分享一下. 实践 1.首先我们新建一个SpringBoot Project ,工程名为 xml 2.添加web依赖,点击Finish完成构建 3.我们新建一个类 SayHello 不做任何配置 package org.t

  • 详解spring boot jpa整合QueryDSL来简化复杂操作

    前言 使用过spring data jpa的同学,都很清楚,对于复杂的sql查询,处理起来还是比较复杂的,而本文中的QueryDSL就是用来简化JPA操作的. Querydsl定义了一种常用的静态类型语法,用于在持久域模型数据之上进行查询.JDO和JPA是Querydsl的主要集成技术.本文旨在介绍如何使用Querydsl与JPA组合使用.JPA的Querydsl是JPQL和Criteria查询的替代方法.QueryDSL仅仅是一个通用的查询框架,专注于通过Java API构建类型安全的SQL查

  • Spring Boot JPA如何把ORM统一起来

    JPA介绍 JPA(Java Persistence API)是Sun官方提出的Java持久化规范.它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据.他的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现在Hibernate,TopLink,JDO等ORM框架各自为营的局面.值得注意的是,JPA是在充分吸收了现有Hibernate,TopLink,JDO等ORM框架的基础上发展而来的,具有易于使用,伸缩性强等优点.从目前的开发社区的反应上看,JPA受到了

  • Springboot启动不检查JPA的数据源配置方式

    目录 Springboot启动不检查JPA的数据源配置 1.问题 2.方案 设置Springboot项目忽略JPA启动 解决方案 Springboot启动不检查JPA的数据源配置 1.问题 有时我们使用spring boot ,在依赖中配置了spring data jpa的依赖,此时spring boot启动时会自动检测数据源的配置,如果没有则报无数据源的错误. 但是这个依赖必须要有,因为代码需要根据一些条件选择是否启用数据源,则么办? 2.方案 在SpringApplication实例中设置如

  • Spring Boot JPA访问Mysql示例

    上篇演示了通过Maven构建Spring Boot 项目,引用web模块启动应用,完成简单的web 应用访问,本章内容在此基础上面加入数据访问与端口修改,下文代码与演例(本用例纯手工测试通过,放心入坑). 修改默认端口 在src\main\resources下加入application.properties内容如下 server.port=8888 项目目录结构 启动应用,日志显示: 端口已经由默认的8080 变更为8888 JPA访问mysql数据库 1.POM中加入 <!-- Spring

随机推荐