Spring Boot配置和使用两个DataSource

juv*_*tus 174 java spring spring-mvc spring-boot

我是Spring和Spring Boot的新手.如何配置和使用两个数据源.

例如,这是第一个数据源的内容.

application.properties

#first db
spring.datasource.url = [url]
spring.datasource.username = [username]
spring.datasource.password = [password]
spring.datasource.driverClassName = oracle.jdbc.OracleDriver

#second db ...
Run Code Online (Sandbox Code Playgroud)

应用类

@SpringBootApplication
public class SampleApplication
{
    public static void main(String[] args) {
        SpringApplication.run(SampleApplication.class, args);
    }
}
Run Code Online (Sandbox Code Playgroud)

如何修改application.properties以添加其他数据源?如何将其自动装配以供其他仓库使用?

K. *_*ddy 206

干得好

#first db
spring.datasource.url = [url]
spring.datasource.username = [username]
spring.datasource.password = [password]
spring.datasource.driverClassName = oracle.jdbc.OracleDriver

#second db ...
spring.secondDatasource.url = [url]
spring.secondDatasource.username = [username]
spring.secondDatasource.password = [password]
spring.secondDatasource.driverClassName = oracle.jdbc.OracleDriver


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

@Bean
@ConfigurationProperties(prefix="spring.secondDatasource")
public DataSource secondaryDataSource() {
    return DataSourceBuilder.create().build();
}
Run Code Online (Sandbox Code Playgroud)

  • 请查看http://www.baeldung.com/spring-data-jpa-multiple-databases,它描述了您正在寻找的内容. (14认同)
  • @K。Siva Prasad Reddy 好的,但我有 2 个不同的 JPARepositories - Spring Boot 如何知道要使用哪个数据源?每个 JPARepository 应该使用不同的数据库 (5认同)
  • @Matley您可能正在寻找https://www.javadevjournal.com/spring-boot/multiple-data-sources-with-spring-boot/这个博客文章。 (2认同)

Sur*_*oen 31

使用Spring Boot 1.5.8.RELEASE更新2018-01-07

大多数答案没有提供如何使用它们(作为数据源本身和事务),只提供如何配置它们.

您可以在https://www.surasint.com/spring-boot-with-multiple-databases-example/中查看可运行的示例和一些说明.

我在这里复制了一些代码.

首先,您必须像这样设置application.properties

#Database
database1.datasource.url=jdbc:mysql://localhost/testdb
database1.datasource.username=root
database1.datasource.password=root
database1.datasource.driver-class-name=com.mysql.jdbc.Driver

database2.datasource.url=jdbc:mysql://localhost/testdb2
database2.datasource.username=root
database2.datasource.password=root
database2.datasource.driver-class-name=com.mysql.jdbc.Driver
Run Code Online (Sandbox Code Playgroud)

然后将它们定义为提供程序(@Bean),如下所示:

@Bean(name = "datasource1")
@ConfigurationProperties("database1.datasource")
@Primary
public DataSource dataSource(){
    return DataSourceBuilder.create().build();
}

@Bean(name = "datasource2")
@ConfigurationProperties("database2.datasource")
public DataSource dataSource2(){
    return DataSourceBuilder.create().build();
}
Run Code Online (Sandbox Code Playgroud)

注意我有@Bean(name ="datasource1")和@Bean(name ="datasource2"),那么当我们需要数据源为@Qualifier("datasource1")和@Qualifier("datasource2")时,你可以使用它,例如

@Qualifier("datasource1")
@Autowired
private DataSource dataSource;
Run Code Online (Sandbox Code Playgroud)

如果您关心事务,则必须为它们定义DataSourceTransactionManager,如下所示:

@Bean(name="tm1")
@Autowired
@Primary
DataSourceTransactionManager tm1(@Qualifier ("datasource1") DataSource datasource) {
    DataSourceTransactionManager txm  = new DataSourceTransactionManager(datasource);
    return txm;
}

@Bean(name="tm2")
@Autowired
DataSourceTransactionManager tm2(@Qualifier ("datasource2") DataSource datasource) {
    DataSourceTransactionManager txm  = new DataSourceTransactionManager(datasource);
    return txm;
}
Run Code Online (Sandbox Code Playgroud)

那你可以像使用它一样

@Transactional //this will use the first datasource because it is @primary
Run Code Online (Sandbox Code Playgroud)

要么

@Transactional("tm2")
Run Code Online (Sandbox Code Playgroud)

这应该足够了.请参阅上面链接中的示例和详细信息.

  • 链接 https://www.surasint.com/spring-boot-with-multiple-databases-example/ 不再有效。 (4认同)

Far*_*ook 23

请参阅官方文档


创建多个数据源与创建第一个数据源的工作方式相同.如果您使用JDBC或JPA的默认自动配置(那么任何@Autowired注入将获取一个),您可能希望将其中一个标记为@Primary.

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

@Bean
@ConfigurationProperties(prefix="datasource.secondary")
public DataSource secondaryDataSource() {
    return DataSourceBuilder.create().build();
}
Run Code Online (Sandbox Code Playgroud)


Cha*_*oka 5

这是完整的解决方案

#First Datasource (DB1)
db1.datasource.url: url
db1.datasource.username:user
db1.datasource.password:password

#Second Datasource (DB2)
db2.datasource.url:url
db2.datasource.username:user
db2.datasource.password:password
Run Code Online (Sandbox Code Playgroud)

由于我们要访问两个不同的数据库(db1、db2),因此我们需要单独配置每个数据源配置,如下所示:

public class DB1_DataSource {
@Autowired
private Environment env;
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean db1EntityManager() {
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(db1Datasource());
    em.setPersistenceUnitName("db1EntityManager");
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    em.setJpaVendorAdapter(vendorAdapter);
    HashMap<string, object=""> properties = new HashMap<>();
    properties.put("hibernate.dialect",
            env.getProperty("hibernate.dialect"));
    properties.put("hibernate.show-sql",
            env.getProperty("jdbc.show-sql"));
    em.setJpaPropertyMap(properties);
    return em;
}

@Primary
@Bean
public DataSource db1Datasource() {

    DriverManagerDataSource dataSource
            = new DriverManagerDataSource();
    dataSource.setDriverClassName(
            env.getProperty("jdbc.driver-class-name"));
    dataSource.setUrl(env.getProperty("db1.datasource.url"));
    dataSource.setUsername(env.getProperty("db1.datasource.username"));
    dataSource.setPassword(env.getProperty("db1.datasource.password"));

    return dataSource;
}

@Primary
@Bean
public PlatformTransactionManager db1TransactionManager() {

    JpaTransactionManager transactionManager
            = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(
            db1EntityManager().getObject());
    return transactionManager;
}
}
Run Code Online (Sandbox Code Playgroud)

第二个数据源:

public class DB2_DataSource {

@Autowired
private Environment env;

@Bean
public LocalContainerEntityManagerFactoryBean db2EntityManager() {
    LocalContainerEntityManagerFactoryBean em
            = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(db2Datasource());
    em.setPersistenceUnitName("db2EntityManager");
    HibernateJpaVendorAdapter vendorAdapter
            = new HibernateJpaVendorAdapter();
    em.setJpaVendorAdapter(vendorAdapter);
    HashMap<string, object=""> properties = new HashMap<>();
    properties.put("hibernate.dialect",
            env.getProperty("hibernate.dialect"));
    properties.put("hibernate.show-sql",
            env.getProperty("jdbc.show-sql"));
    em.setJpaPropertyMap(properties);
    return em;
}

@Bean
public DataSource db2Datasource() {
    DriverManagerDataSource dataSource
            = new DriverManagerDataSource();
    dataSource.setDriverClassName(
            env.getProperty("jdbc.driver-class-name"));
    dataSource.setUrl(env.getProperty("db2.datasource.url"));
    dataSource.setUsername(env.getProperty("db2.datasource.username"));
    dataSource.setPassword(env.getProperty("db2.datasource.password"));

    return dataSource;
}

@Bean
public PlatformTransactionManager db2TransactionManager() {
    JpaTransactionManager transactionManager
            = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(
            db2EntityManager().getObject());
    return transactionManager;
}
}
Run Code Online (Sandbox Code Playgroud)

您可以在我的博客上找到完整的示例: Spring Boot with Multiple DataSource Configuration


小智 5

# Here '1stDB' is the database name
spring.datasource.url=jdbc:mysql://localhost/A
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
 
 
# Here '2ndDB' is the database name
spring.second-datasourcee.url=jdbc:mysql://localhost/B
spring.second-datasource.username=root
spring.second-datasource.password=root
spring.second-datasource.driver-class-name=com.mysql.jdbc.Driver
Run Code Online (Sandbox Code Playgroud)
# Here '1stDB' is the database name
spring.datasource.url=jdbc:mysql://localhost/A
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
 
 
# Here '2ndDB' is the database name
spring.second-datasourcee.url=jdbc:mysql://localhost/B
spring.second-datasource.username=root
spring.second-datasource.password=root
spring.second-datasource.driver-class-name=com.mysql.jdbc.Driver
Run Code Online (Sandbox Code Playgroud)

  • @AmirKeshavarz我的答案可能有点......晚了,但是你必须将 datasource.url 修改为 datasource.jdbc-url 并且它会起作用 (3认同)

Wal*_*rer 5

我还必须从Spring Boot应用程序设置到2个数据源的连接,这并不容易-Spring Boot文档中提到的解决方案不起作用。经过长时间的互联网研究,我使它起作用,并且主要思想来自本文和其他地方。

以下解决方案是用Kotlin编写的,并且可以与Spring Boot 2.1.3Hibernate Core 5.3.7一起使用。主要问题是仅设置不同的DataSource配置是不够的,但还需要为两个数据库配置EntityManagerFactoryTransactionManager

这是第一个(主)数据库的配置:

@Configuration
@EnableJpaRepositories(
    entityManagerFactoryRef = "firstDbEntityManagerFactory",
    transactionManagerRef = "firstDbTransactionManager",
    basePackages = ["org.path.to.firstDb.domain"]
)
@EnableTransactionManagement
class FirstDbConfig {

    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.firstDb")
    fun firstDbDataSource(): DataSource {
        return DataSourceBuilder.create().build()
    }

    @Primary
    @Bean(name = ["firstDbEntityManagerFactory"])
    fun firstDbEntityManagerFactory(
        builder: EntityManagerFactoryBuilder,
        @Qualifier("firstDbDataSource") dataSource: DataSource
    ): LocalContainerEntityManagerFactoryBean {
        return builder
            .dataSource(dataSource)
            .packages(SomeEntity::class.java)
            .persistenceUnit("firstDb")
            // Following is the optional configuration for naming strategy
            .properties(
                singletonMap(
                    "hibernate.naming.physical-strategy",
                    "org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl"
                )
            )
            .build()
    }

    @Primary
    @Bean(name = ["firstDbTransactionManager"])
    fun firstDbTransactionManager(
        @Qualifier("firstDbEntityManagerFactory") firstDbEntityManagerFactory: EntityManagerFactory
    ): PlatformTransactionManager {
        return JpaTransactionManager(firstDbEntityManagerFactory)
    }
}
Run Code Online (Sandbox Code Playgroud)

这是第二个数据库的配置:

@Configuration
@EnableJpaRepositories(
    entityManagerFactoryRef = "secondDbEntityManagerFactory",
    transactionManagerRef = "secondDbTransactionManager",
    basePackages = ["org.path.to.secondDb.domain"]
)
@EnableTransactionManagement
class SecondDbConfig {

    @Bean
    @ConfigurationProperties("spring.datasource.secondDb")
    fun secondDbDataSource(): DataSource {
        return DataSourceBuilder.create().build()
    }

    @Bean(name = ["secondDbEntityManagerFactory"])
    fun secondDbEntityManagerFactory(
        builder: EntityManagerFactoryBuilder,
        @Qualifier("secondDbDataSource") dataSource: DataSource
    ): LocalContainerEntityManagerFactoryBean {
        return builder
            .dataSource(dataSource)
            .packages(EntityFromSecondDb::class.java)
            .persistenceUnit("secondDb")
            .build()
    }

    @Bean(name = ["secondDbTransactionManager"])
    fun secondDbTransactionManager(
        @Qualifier("secondDbEntityManagerFactory") secondDbEntityManagerFactory: EntityManagerFactory
    ): PlatformTransactionManager {
        return JpaTransactionManager(secondDbEntityManagerFactory)
    }
}
Run Code Online (Sandbox Code Playgroud)

数据源的属性如下:

spring.datasource.firstDb.jdbc-url=
spring.datasource.firstDb.username=
spring.datasource.firstDb.password=

spring.datasource.secondDb.jdbc-url=
spring.datasource.secondDb.username=
spring.datasource.secondDb.password=
Run Code Online (Sandbox Code Playgroud)

属性的问题在于,我必须定义jdbc-url而不是url,因为否则我会遇到异常。

ps 另外,您的数据库中可能会有不同的命名方案,对我来说就是这种情况。由于Hibernate 5不支持以前的所有命名方案,因此我不得不使用此答案中的解决方案-也许它也会对某人有所帮助。

  • 我在实体和表命名方面遇到问题。它对我的回答很有帮助:`mapOf("hibernate.physical_naming_strategy" to "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy", "hibernate.implicit_naming_strategy" to "org.springframework.boot.orm.jpa .hibernate.SpringImplicitNamingStrategy" )` (2认同)

归档时间:

查看次数:

183439 次

最近记录:

6 年,1 月 前