我正在评估为每个租户提供一个数据库解决方案的方法。按照 https://github.com/spring-projects/spring-data-examples/tree/main/jpa/multitenant/db ,我最终得到了一个使用
AbstractRoutingDataSource
的原型,当没有租户时,需要一个默认数据库尚未选择。
看起来这只是为了允许 Spring Boot (Data Jpa) 启动并初始化实体管理器。
@Component
public class TenantRoutingDatasource extends AbstractRoutingDataSource {
@Autowired private TenantIdentifierResolver tenantIdentifierResolver;
TenantRoutingDatasource() {
setDefaultTargetDataSource(createEmbeddedDatabase("default"));
HashMap<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put("VMWARE", createEmbeddedDatabase("VMWARE"));
targetDataSources.put("PIVOTAL", createEmbeddedDatabase("PIVOTAL"));
setTargetDataSources(targetDataSources);
}
@Override
protected String determineCurrentLookupKey() {
return tenantIdentifierResolver.resolveCurrentTenantIdentifier();
}
private EmbeddedDatabase createEmbeddedDatabase(String name) {
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).setName(name).addScript("manual-schema.sql")
.build();
}
}
有人有避免使用默认数据源的解决方案吗?有没有办法让 Spring Boot 推迟任何实体管理器的创建,直到它被存储库等使用?
看起来默认数据库是可选的,但我没有测试过。
您可以使用 LazyConnectionDataSourceProxy 推迟第一个语句上的数据源连接。它是数据源的代理,将延迟初始化底层 JDBC 连接(从而推迟依赖于它的所有内容)。
这篇文章有不同的用例,但他们将
AbstractRoutingDataSource
与LazyConnectionDataSourceProxy
结合起来,我相信这就是您正在寻找的。
另一种选择是使用 JPA 引导模式,但在这种情况下,您必须等待池中的每个 JDBC 连接被解析并且 EntityManagerFactory 被初始化。