我的猜测是这可以看作是一种多租户方法,一个租户是readonly,另一个租户是write。
为多租户支持配置持久层的步骤包括:
application.yml
...
multitenancy:
dvdrental:
dataSources:
-
tenantId: readonly
url: jdbc:postgresql://172.16.69.133:5432/db_dvdrental
username: user_dvdrental
password: changeit
driverClassName: org.postgresql.Driver
-
tenantId: write
url: jdbc:postgresql://172.16.69.133:5532/db_dvdrental
username: user_dvdrental
password: changeit
driverClassName: org.postgresql.Driver
...
MultiTenantJpaConfiguration.java
...
@Configuration
@EnableConfigurationProperties({ MultiTenantDvdRentalProperties.class, JpaProperties.class })
@ImportResource(locations = { "classpath:applicationContent.xml" })
@EnableTransactionManagement
public class MultiTenantJpaConfiguration {
@Autowired
private JpaProperties jpaProperties;
@Autowired
private MultiTenantDvdRentalProperties multiTenantDvdRentalProperties;
...
}
MultiTenantDvdRentalProperties.java
...
@Configuration
@ConfigurationProperties(prefix = "multitenancy.dvdrental")
public class MultiTenantDvdRentalProperties {
private List<DataSourceProperties> dataSourcesProps;
// Getters and Setters
public static class DataSourceProperties extends org.springframework.boot.autoconfigure.jdbc.DataSourceProperties {
private String tenantId;
// Getters and Setters
}
}
MultiTenantJpaConfiguration.java
...
public class MultiTenantJpaConfiguration {
...
@Bean(name = "dataSourcesDvdRental" )
public Map<String, DataSource> dataSourcesDvdRental() {
...
}
...
}
MultiTenantJpaConfiguration.java
...
public class MultiTenantJpaConfiguration {
...
@Bean
public MultiTenantConnectionProvider multiTenantConnectionProvider() {
...
}
@Bean
public CurrentTenantIdentifierResolver currentTenantIdentifierResolver() {
...
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(MultiTenantConnectionProvider multiTenantConnectionProvider,
CurrentTenantIdentifierResolver currentTenantIdentifierResolver) {
...
}
...
}
MultiTenantJpaConfiguration.java
...
public class MultiTenantJpaConfiguration {
...
@Bean
public EntityManagerFactory entityManagerFactory(LocalContainerEntityManagerFactoryBean entityManagerFactoryBean) {
...
}
@Bean
public PlatformTransactionManager txManager(EntityManagerFactory entityManagerFactory) {
...
}
...
}
applicationContent.xml
...
<jpa:repositories base-package="com.asimio.dvdrental.dao" transaction-manager-ref="txManager" />
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true" />
...
ActorDao.java
public interface ActorDao extends JpaRepository<Actor, Integer> {
}
根据您的需要,可以这样做:
...
@Autowired
private ActorDao actorDao;
...
// Read feature
...
DvdRentalTenantContext.setTenantId("readonly");
this.actorDao.findOne(...);
...
// Or write
DvdRentalTenantContext.setTenantId("write");
this.actorDao.save(...);
...
可以在 servlet 过滤器/Spring MVC 拦截器/要执行 JPA 操作的线程等中设置tenantId。
有关多租户方法的更多详细信息,请参阅我的博客http://tech.asimio.net/2017/01/17/Multitenant-applications-using-Spring-Boot-JPA-Hibernate-and-Postgres.html