Spring Data之多数据源配置和使用

createh52个月前 (03-16)技术教程11

概述

Spring Boot应用程序的典型场景是将数据存储在单个关系数据库中。但我们有时需要访问多个数据库。本文演示如何使用Spring Boot配置和使用多个数据源。

Spring数据源默认配置

在application.yml中声明数据源的配置方式:

spring:
  datasource:
    url: ...
    username: ...
    password: ...
    driverClassname: ..

Spring将这些设置映射到
org.springframework.boot.autoconfigure.jdbc.DataSourceProperties的实例:

@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceProperties implements BeanClassLoaderAware, InitializingBean {

    // ...

    /**
     * Fully qualified name of the JDBC driver. Auto-detected based on the URL by default.
     */
    private String driverClassName;

    /**
     * JDBC URL of the database.
     */
    private String url;

    /**
     * Login username of the database.
     */
    private String username;

    /**
     * Login password of the database.
     */
    private String password;

    // ...

}

@ConfigurationProperties注解将配置的属性自动映射到Java对象。

扩展默认数据源配置

要使用多个数据源,可以考虑遵循DataSourceProperties配置规则,创建多 bean映射相应的上下文数据源配置。

@Configuration
public class TodoDatasourceConfiguration {

    @Bean
    @ConfigurationProperties("spring.datasource.todos")
    public DataSourceProperties todosDataSourceProperties() {
        return new DataSourceProperties();
    }
}

@Configuration
public class TopicDatasourceConfiguration {

    @Bean
    @ConfigurationProperties("spring.datasource.topics")
    public DataSourceProperties topicsDataSourceProperties() {
        return new DataSourceProperties();
    }

}

数据源的配置必须如下所示:

spring:
  datasource:
    todos:
      url: ...
      username: ...
      password: ...
      driverClassName: ...
    topics:
      url: ...
      username: ...
      password: ...
      driverClassName: ...

然后就可以使用DataSourceProperties对象创建数据源:

@Bean
public DataSource todosDataSource() {
    return todosDataSourceProperties()
      .initializeDataSourceBuilder()
      .build();
}

@Bean
public DataSource topicsDataSource() {
    return topicsDataSourceProperties()
      .initializeDataSourceBuilder()
      .build();
}

Spring Data JDBC

使用Spring Data JDBC时,我们还需要为每个DataSource配置一个JdbcTemplate实例:

@Bean
public JdbcTemplate todosJdbcTemplate(@Qualifier("todosDataSource") DataSource dataSource) {
    return new JdbcTemplate(dataSource);
}

@Bean
public JdbcTemplate topicsJdbcTemplate(@Qualifier("topicsDataSource") DataSource dataSource) {
    return new JdbcTemplate(dataSource);
}

然后就可以通过指定@Qualifier来使用JdbcTemplate:

@Autowired
@Qualifier("topicsJdbcTemplate")
JdbcTemplate jdbcTemplate;

Spring Data JPA

当使用Spring Data JPA时,我们希望使用如下存储库,其中Todo是实体:

public interface TodoRepository extends JpaRepository {}

那我们需要为每个数据源声明EntityManager工厂:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
  basePackageClasses = Todo.class,
  entityManagerFactoryRef = "todosEntityManagerFactory",
  transactionManagerRef = "todosTransactionManager"
)
public class TodoJpaConfiguration {

    @Bean
    public LocalContainerEntityManagerFactoryBean todosEntityManagerFactory(
      Qualifier("todosDataSource") DataSource dataSource,
      EntityManagerFactoryBuilder builder) {
        return builder
          .dataSource(todosDataSource())
          .packages(Todo.class)
          .build();
    }

    @Bean
    public PlatformTransactionManager todosTransactionManager(
      @Qualifier("todosEntityManagerFactory") LocalContainerEntityManagerFactoryBean todosEntityManagerFactory) {
        return new JpaTransactionManager(Objects.requireNonNull(todosEntityManagerFactory.getObject()));
    }

}

我们需要对包进行拆分,以便为每个数据源提供一个@EnableJpaRepository。

要注入
EntityManagerFactoryBuilder,需要将其中一个数据源声明为@Primary。

这是因为
EntityManagerFactoryBuilder在
org.springframework.boot.autoconfig.org.jpa.JpaBaseConfiguration中声明,该类需要注入单个数据源。

配置Hikari连接池

如果我们想配置Hikari连接池,只需在数据源定义中添加@ConfigurationProperties即可:

@Bean
@ConfigurationProperties("spring.datasource.todos.hikari")
public DataSource todosDataSource() {
    return todosDataSourceProperties()
      .initializeDataSourceBuilder()
      .build();
}

然后就可以在application.properties按Hikari的配置规则添加连接池属性:

spring.datasource.todos.hikari.connectionTimeout=30000 
spring.datasource.todos.hikari.idleTimeout=600000 
spring.datasource.todos.hikari.maxLifetime=1800000 

结论

Spring Boot配置多个数据源可以考虑进行抽象化成通用模块,根据指定名称属性自动获取指定数据源。

相关文章

Java——JDBC有哪些使用方法?

JDBC的规范接口数据库厂商需要实现此接口(实现类)--数据库驱动作用与数据库创建链接发送sql语句接收返回值处理结果api详解DriverManager 类:管理 JDBC 驱动的基础服务。使用re...

Java程序设计——JDBC基础(JDBC编程)

目录JDBC(Java DataBase Connectivity))是一种执行SQL语句的Java API程序可以通过JDBC连接到关系数据库,从而实现对数据库的增删改查等操作JDBC访问数据库的三...

《极简Java新手编程之道》16.2JDBC技术

下面来介绍JDBC技术。JDBC数据库的技术叫做JDBC技术,使用JDBC技术的人可以分为三个角色。·第一个角色是JDBC的官方,就是加瓦的官方。加瓦官方提供的JDBC接口其实就是官方提供给我们的,都...

《JDBC》第14节:JDBC之获取数据库中的表信息和表字段信息

#长文创作激励计划#前面已经将JDBC中的基础知识都介绍差不多了,这一小节我们来介绍一下,如何使用JDBC获取数据库中的表信息。1.1、获取数据表信息获取数据表信息,需要通过DatabaseMetaD...

[Java速成] 数据库基础,Connector/J、JDBC、JPA的关系(day 7)

先来看一个问题:在创建 Java 项目,选择数据库依赖时,如下图,你知道该如何正确的选择合适你项目的依赖吗?看完这篇文章,就能有个很好的认知了。后续的文章中,我们也需要使用数据库,所以在正式开始使用...

Spring JDBC-Spring对DAO的支持详细讲解

【摘要】 概述Spring的DAO理念统一的异常体系统一的数据访问模板 使用模板和回调机制模板类 数据源 配置数据源 DBCP数据源C3P0数据源 获取JNDI数据源Spr...概述Spring的DA...