我必须做一个Spring Boot版本1.5的应用程序,它可以这样做:它创建一个对象,并尝试持久保留两个数据源(例如:2个名为test_book_1和test_book_2的数据库在Postgresql中)。使用相同的存储库和模型类的多个数据源的Spring Boot?
我发现了一个可以用于2个不同对象(作者:A,Book: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 类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 Map<String, Object> hibernateProperties() {
Resource resource = new ClassPathResource("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<String, Object>();
}
}
}
包: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 Map<String, Object> hibernateProperties() {
Resource resource = new ClassPathResource("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<String, 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<Book, Long> {
}
包com.roufid.tutorial.entity.postgresql 类Book
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
}
和测试类注入,这将仅使用MysqlConfiguration类(第二数据源)的BookRepository。
@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);
}
}
是的,看来我需要做到这一点,我发现一个很好的教程与多租户与单独的数据库http://anakiou.blogspot.de/2015/08/multi-tenant-application-with-spring。 HTML。 此外,我真正的问题也更简单,它会从现有数据库中读取对象并将此对象保存到新数据库中。我刚刚在教程链接中快速浏览过,因此不确定它可以支持这种情况。 –
检查弹簧代替http://www.mkyong.com/tutorials/spring-batch-tutorial/您描述的情况是典型的读者/处理器/作家。春天的读者和作家有很多 - 例如基于JDBC的 – StanislavL
谢谢,我检查了你发布的链接,它似乎写入数据到文件并插入到数据库,如果可能的话,为我一些陌生的语法。我宁愿通过JPA复制整个对象,因为两个数据库都共享由Hibernate创建的相同模式。在这里有一个例子,我阅读相当不错,在我的情况下https://stackoverflow.com/a/42960998/2028440 –