Spring Boot 1.0 && 2.0 + JPA 多数据源配置与使用

环境说明

  • Spring Boot 1.5.17.RELEASE Spring Boot 2.1.0.RELEASE
  • MySQL v5.6.19
  • PostgreSQL v10.4

无特殊说明,以下所说的环境均指 Spring Boot 2.1.0.RELEASE,如果使用的是 Spring Boot 1.5.17.RELEASE 这个版本,只需要调整下面有做说明的几处地方

连接配置

application.yml中定义如下信息:

spring:
  jpa:
    hibernate:
      # 多数据源下,该属性不生效,需要在配置中额外指定,这里仅表示普通定义
      ddl-auto: create-drop
    properties:
      hibernate:
        show_sql: true
        format_sql: true
        jdbc:
          lob:
            non_contextual_creation: true
    open-in-view: false
  # 定义不同数据源的连接信息
  datasource:
    hikari:
      mysql:
        # Spring Boot 1.0+ 版本:使用spring.datasource.url
        # Spring Boot 2.0+ 版本:使用spring.datasource.hikari.jdbc-url
        jdbc-url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
        username: root
        password: root
        # Spring Boot 1.0+ 版本:使用com.mysql.jdbc.Driver
        # Spring Boot 2.0+ 版本:使用com.mysql.cj.jdbc.Driver
        driver-class-name: com.mysql.cj.jdbc.Driver
      postgres:
        jdbc-url: jdbc:postgresql://localhost:5432/postgres
        username: postgres
        password: postgres
        driver-class-name: org.postgresql.Driver

配置数据源

根据上面定义的配置信息,配置这两个数据源:

// Spring Boot 1.0+ ,DataSourceBuilder所在包位置为:org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder
// Spring Boot 2.0+ ,DataSourceBuilder所在包位置为:org.springframework.boot.jdbc.DataSourceBuilder
@Configuration
public class DataSourceConfig {

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

    @Bean
    @ConfigurationProperties("spring.datasource.hikari.postgres")
    public DataSource postgresDataSource() {
        return DataSourceBuilder.create().build();
    }

}

JPA 支持

添加 mysql 对应数据源的 JPA 支持:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "mysqlEntityManagerFactory",
        transactionManagerRef = "mysqlTransactionManager",
        // 数据层所在的包位置
        basePackages = "cn.mariojd.springboot.multiple.datasource.jpa.mysql.repository")
public class MysqlDataSourceConfig {

    @Resource
    private Environment environment;

    @Resource
    @Qualifier("mysqlDataSource")
    private DataSource dataSource;

    @Bean
    @Primary
    public LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory(EntityManagerFactoryBuilder builder) {
        Map<String, Object> properties = new HashMap<>(4);
        // Spring Boot 1.0+ ,使用MySQLDialect
        // Spring Boot 2.0+ ,指定MySQLDialect会默认使用MyISAM引擎,改成MySQL55Dialect即可
        properties.put("hibernate.dialect", "org.hibernate.dialect.MySQL55Dialect");
        properties.put("hibernate.hbm2ddl.auto", environment.getProperty("spring.jpa.hibernate.ddl-auto"));
        return builder.dataSource(dataSource)
                .properties(properties)
                // 实体所在的包位置
                .packages("cn.mariojd.springboot.multiple.datasource.jpa.mysql.entity")
                .persistenceUnit("jpa-mysql")
                .build();
    }

    @Bean
    @Primary
    public PlatformTransactionManager mysqlTransactionManager(@Qualifier("mysqlEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }

}

添加 postgres 对应数据源的 JPA 支持:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "postgresEntityManagerFactory",
        transactionManagerRef = "postgresTransactionManager",
        // 数据层所在的包位置
        basePackages = "cn.mariojd.springboot.multiple.datasource.jpa.postgres.repository")
public class PostgresDataSourceConfig {

    @Resource
    private Environment environment;

    @Resource
    @Qualifier("postgresDataSource")
    private DataSource dataSource;

    @Bean
    public LocalContainerEntityManagerFactoryBean postgresEntityManagerFactory(EntityManagerFactoryBuilder builder) {
        Map<String, Object> properties = new HashMap<>(4);
        properties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
        properties.put("hibernate.hbm2ddl.auto", environment.getProperty("spring.jpa.hibernate.ddl-auto"));
        return builder.dataSource(dataSource)
                // 实体所在的包位置
                .properties(properties)
                .packages("cn.mariojd.springboot.multiple.datasource.jpa.postgres.entity")
                .persistenceUnit("jpa-postgres")
                .build();
    }

    @Bean
    public PlatformTransactionManager postgresTransactionManager(@Qualifier("postgresEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }

}

相关定义

mysql 对应的数据源配置中,定义了实体 Student 和对应的数据层接口 StudentRepository

@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;

    public Student(String name) {
        this.name = name;
    }
}
public interface StudentRepository extends JpaRepository<Student, Integer> {
}

postgres 对应的数据源配置中,定义了实体 Teacher 和对应的数据层接口 TeacherRepository

@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
public class Teacher {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;

    public Teacher(String name) {
        this.name = name;
    }
}
public interface TeacherRepository extends JpaRepository<Teacher, Integer> {
}

单元测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootJpaMultipleDataSourceTest {

    @Resource
    private StudentRepository studentRepository;

    @Resource
    private TeacherRepository teacherRepository;

    @Test
    public void test() {
        studentRepository.save(new Student("张三"));
        studentRepository.save(new Student("李四"));
        studentRepository.save(new Student("王五"));

        Assert.assertEquals(3, studentRepository.findAll().size());

        teacherRepository.save(new Teacher("张老师"));
        teacherRepository.save(new Teacher("李老师"));
        teacherRepository.save(new Teacher("王老师"));
        Assert.assertEquals(3, teacherRepository.findAll().size());
    }

}

参考链接

Using multiple datasources with Spring Boot and Spring Data Spring JPA – Multiple Databases Spring Boot多数据源配置与使用 How to connect to Multiple databases with Spring Data JPA Springboot2.0中Hibernate默认创建的mysql表为myisam引擎问题 关于springboot2.0.0配置多数据源出现jdbcUrl is required with driverClassName的错误 解决mysql java.sql.SQLException: The server time zone value ...

示例源码 欢迎关注我的个人公众号:超级码里奥 如果这对您有帮助,欢迎点赞和分享,转载请注明出处

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏石奈子的Java之路

原 荐 SpringBoot 2.0 系列0

2304
来自专栏CodingToDie

传统Spring项目使用FeignClient组件访问微服务

传统Spring项目使用 这里的传统 Spring项目指的是没有使用 spring boot的 spring项目,例如 ssm api 文件 和在spring ...

6.5K8
来自专栏乐沙弥的世界

MyCAT 日志文件描述

    MyCat是一个基于cobar兴起的开源数据库中间件系统,当前深受广大开源爱好者的追捧以及DBA粉丝们的广泛研究。主要是面对解决高并发,高负载,海量存...

1202
来自专栏有刻

Java 小记 — Spring Boot 注解

36813
来自专栏一个会写诗的程序员的博客

《Springboot极简教程》使用Spring Boot, JPA, Mysql, ThymeLeaf,gradle, Kotlin快速构建一个CRUD Web App

使用Spring Boot, JPA, Mysql, ThymeLeaf,gradle, Kotlin快速构建一个CRUD Web App

1722
来自专栏Albert陈凯

2018-11-17 面试必问问题TransactionalJava事务之一——Java事务的基本问题

关于加@Transactional注解的方法之间调用,事务是否生效的问题 https://blog.csdn.net/blacktal/article/det...

1882
来自专栏Strive

zabbix服务zabbix server is not running: the information...

搭建环境 | 系统:centos 7 | Java 1.8 | zabbix 3.4

1.3K4
来自专栏Ryan Miao

Spring-AOP实践 - 统计访问时间

公司的项目有的页面超级慢,20s以上,不知道用户会不会疯掉,于是老大说这个页面要性能优化。于是,首先就要搞清楚究竟是哪一步耗时太多。 我采用spring aop...

4598
来自专栏用户2442861的专栏

cmake教程4(find_package使用)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/haluoluo211/article/d...

2513
来自专栏Spring相关

快速创建SpringBoot+SSM解析

此处使用IDEA快速搭建SpringBoot应用,首先用SpringBoot搭建WEB工程:

1462

扫码关注云+社区