微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – 使用相同存储库和模型类的多个数据源的Spring Boot?

我必须做一个Spring Boot 1.5版应用程序,它可以这样做:它创建一个对象并尝试持久化到两个数据源(例如:2个数据库名为:test_book_1和Postgresql中的test_book_2).

我找到了一个可以用于2个不同对象的例子(作者:A,书籍:B),它们可以存储在不同的数据库中(A转到test_book_1,B转到test_book_2).这是一个很好的例子,但它不是我想要的.
Store separate objects to different data sources

我认为我需要定义2个自定义JPA DatabaseConfigurations,并需要将它们配置为管理相同的存储库和域类.但是,Spring只使用第二个类作为限定符来注入JPA存储库(我知道当两个配置指向同一个类时,第二个类可以覆盖).

问题是,我怎么能告诉Spring让它知道什么时候应该从想要的数据源中注入正确的Bean(BookRepository)(我想将对象持久保存到两个数据源,而不仅仅是第二个数据源).

以下是上面示例链接中的修改代码.

一个application.properties文件,它被修改为在Postgresql中创建2个数据库,而不是在Postgresql中创建1个,在MysqL中创建1个.

server.port=8082
# -----------------------
# POSTGREsql DATABASE CONfigURATION
# -----------------------
    spring.postgresql.datasource.url=jdbc:postgresql://localhost:5432/test_book_db
spring.postgresql.datasource.username=petauser
spring.postgresql.datasource.password=petapasswd
spring.postgresql.datasource.driver-class-name=org.postgresql.Driver

# ------------------------------
# POSTGREsql 1 DATABASE CONfigURATION
# ------------------------------

   spring.MysqL.datasource.url=jdbc:postgresql://localhost:5432/test_author_db
spring.MysqL.datasource.username=petauser
spring.MysqL.datasource.password=petapasswd
spring.MysqL.datasource.driver-class-name=org.postgresql.Driver

包:com.roufid.tutorial.configuration
class APostgresqlConfiguration

package com.roufid.tutorial.configuration;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerfactorybean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.roufid.tutorial.entity.postgresql.Book;

/**
 * Spring configuration of the "Postgresql" database.
 *
 * @author Radouane ROUFID.
 *
 */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "postgresqlEntityManager",transactionManagerRef = "postgresqlTransactionManager",basePackages = "com.roufid.tutorial.dao.postgresql"
)
public class APostgresqlConfiguration {

    /**
     * Postgresql datasource deFinition.
     *
     * @return datasource.
     */
    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.postgresql.datasource")
    public DataSource postgresqlDataSource() {
        return DataSourceBuilder
                .create()
                .build();
    }

    /**
     * Entity manager deFinition.
     *
     * @param builder an EntityManagerFactoryBuilder.
     * @return LocalContainerEntityManagerfactorybean.
     */
    @Primary
    @Bean(name = "postgresqlEntityManager")
    public LocalContainerEntityManagerfactorybean postgresqlEntityManagerFactory(EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(postgresqlDataSource())
                .properties(hibernateProperties())
                .packages(Book.class)
                .persistenceUnit("postgresqlPU")
                .build();
    }

    @Primary
    @Bean(name = "postgresqlTransactionManager")
    public PlatformTransactionManager postgresqlTransactionManager(@Qualifier("postgresqlEntityManager") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }

    private MapClassPathResource("hibernate.properties");

        try {
            Properties properties = PropertiesLoaderUtils.loadProperties(resource);
            return properties.entrySet().stream()
                    .collect(Collectors.toMap(
                            e -> e.getKey().toString(),e -> e.getValue())
                    );
        } catch (IOException e) {
            return new HashMap

包:com.roufid.tutorial.configuration
MysqLConfiguration

package com.roufid.tutorial.configuration;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerfactorybean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.roufid.tutorial.entity.MysqL.Author;
import com.roufid.tutorial.entity.postgresql.Book;

/**
 * Spring configuration of the "MysqL" database.
 *
 * @author Radouane ROUFID.
 *
 */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "MysqLEntityManager",transactionManagerRef = "MysqLTransactionManager",basePackages = "com.roufid.tutorial.dao.postgresql"
)
public class MysqLConfiguration {

    /**
     * MysqL datasource deFinition.
     *
     * @return datasource.
     */
    @Bean
    @ConfigurationProperties(prefix = "spring.MysqL.datasource")
    public DataSource MysqLDataSource() {
        return DataSourceBuilder
                .create()
                .build();
    }

    /**
     * Entity manager deFinition.
     *
     * @param builder an EntityManagerFactoryBuilder.
     * @return LocalContainerEntityManagerfactorybean.
     */
    @Bean(name = "MysqLEntityManager")
    public LocalContainerEntityManagerfactorybean MysqLEntityManagerFactory(EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(MysqLDataSource())
                .properties(hibernateProperties())
                .packages(Book.class)
                .persistenceUnit("MysqLPU")
                .build();
    }

    /**
     * @param entityManagerFactory
     * @return
     */
    @Bean(name = "MysqLTransactionManager")
    public PlatformTransactionManager MysqLTransactionManager(@Qualifier("MysqLEntityManager") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }

    private MapClassPathResource("hibernate.properties");
    }
}    try {
            Properties properties = PropertiesLoaderUtils.loadProperties(resource);
            return properties.entrySet().stream()
                    .collect(Collectors.toMap(
                            e -> e.getKey().toString(),Object>();
        }
    }
}

包com.roufid.tutorial.dao.postgresql
class BookRepository

package com.roufid.tutorial.dao.postgresql;

import org.springframework.data.repository.CrudRepository;

import com.roufid.tutorial.entity.postgresql.Book;

/**
 * Book repository.
 * 
 * @author Radouane ROUFID.
 *
 */
public interface BookRepository extends CrudRepository

包com.roufid.tutorial.entity.postgresql
班级书

package com.roufid.tutorial.entity.postgresql;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "BOOK")
public class Book implements Serializable {

    private static final long serialVersionUID = -9019470250770543773L;

    @Id
    private Long id;

    @Column
    private String name;

    @Column
    private Long authorId;

    ...
    // Setters,Getters

}

还有一个注入BookRepository的测试类,它只使用MysqLConfiguration类(第二个数据源).

@RunWith(springrunner.class)
@SpringBoottest
public class ApplicationTest {
@Autowired
private BookRepository bookRepository;
@Before
public void init() {   
    Book book = new Book();
    book.setId(bookId);
    book.setName("Spring Boot Book");

    // How can it persist to the first datasource?  
    bookRepository.save(book);
}

}

最佳答案
看起来你需要多租户支持.

一个基于Spring的解决方

您需要实现CurrentTenantIdentifierResolver接口

public String resolveCurrentTenantIdentifier()

并扩展

AbstractDataSourceBasedMultiTenantConnectionProviderImpl

为租户返回DataSource

查看更多here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐