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

createh51个月前 (03-16)技术教程6

概述

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...

JDBC与ORM发展与联系 JDBC简介(九)

回顾下JDBC的概念:JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Ja...

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

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

GBASE南大通用数据JDBC处理数据类型与 Java 数据的类型的灵活转换

由于 SQL 数据类型和 Java 数据类型是不同的,因此需要某种机制在使用 Java 类型的应用程序和使用 SQL 类型的数据库之间来读写数据。为此,JDBC 提供了 getXXX 和 setXXX...

Javaweb知识 day19 Filter&Listener

今日内容 1. Filter:过滤器 2. Listener:监听器一、Filter:过滤器1.1概念: * 生活中的过滤器:净水器,空气净化器,土匪、 * web中的过滤器:当访问服务器的资源时,过...