在quarkus application.properties
quarkus.datasource.jdbc.url=jdbc:postgresql://192.168.100.110:5432/test
quarkus.datasource.username=root
quarkus.datasource.password=root
quarkus.hibernate-orm.database.generation=update
quarkus.hibernate-orm.multitenant=DATABASE
并使用TenantResolver
解析tenantId
@PersistenceUnitExtension
@RequestScoped
public class CustomTenantResolver implements TenantResolver {
@Override
public String getDefaultTenantId() {
return TenantUtil.NONE.toString();
}
@Override
public String resolveTenantId() {
return TenantUtil.getTenantId().toString();
}
}
然后使用TenantConnectionResolver
解析dataSource
@ApplicationScoped
@PersistenceUnitExtension
public class DataSourceTenantConnectionResolver implements TenantConnectionResolver {
@ConfigProperty(name = "quarkus.datasource.jdbc.url")
String url;
@ConfigProperty(name = "quarkus.datasource.username")
String username;
@ConfigProperty(name = "quarkus.datasource.password")
String password;
private final Map<String, ConnectionProvider> map = new HashMap<>();
@Override
public ConnectionProvider resolve(String tenantId) {
System.out.println("resolve ConnectionProvider " + tenantId);
if (map.containsKey(tenantId)) {
return map.get(tenantId);
}
ConnectionProvider provider;
if (tenantId.equals(TenantUtil.NONE)) {
provider = new QuarkusConnectionProvider(createDataSource(url, "test", username, password));
} else {
provider =
new QuarkusConnectionProvider(
createDataSource(
"jdbc:postgresql://192.168.100.110:5432/tenant"
+ tenantId
+ "?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&createDatabaseIfNotExist=true",
"tenant" + tenantId,
"root",
"root"));
}
map.put(tenantId, provider);
return provider;
}
private AgroalDataSource createDataSource(
String url, String database, String username, String password) {
try {
AgroalDataSourceConfigurationSupplier configurationSupplier =
new AgroalDataSourceConfigurationSupplier();
AgroalConnectionPoolConfigurationSupplier connectionPoolConfig =
configurationSupplier.connectionPoolConfiguration();
connectionPoolConfig.maxSize(1000);
AgroalConnectionFactoryConfigurationSupplier connectionFactoryConfig =
connectionPoolConfig.connectionFactoryConfiguration();
connectionFactoryConfig.jdbcUrl(url);
connectionFactoryConfig.principal(new NamePrincipal(username));
connectionFactoryConfig.credential(new SimplePassword(password));
connectionFactoryConfig.initialSql("CREATE DATABASE IF NOT EXISTS " + database);
return AgroalDataSource.from(configurationSupplier.get());
} catch (SQLException | RuntimeException e) {
throw new IllegalStateException("Exception while creating datasource for " + url, e);
}
}
}
问题1
无法通过createDatabaseIfNotExist=true
的jdbcUrl自动创建数据库。这是预期的行为吗?所以我用connectionFactoryConfig.initialSql("CREATE DATABASE IF NOT EXISTS " + database)
问题二
如何自动创建像quarkus.hibernate-orm.database.generation=update
这样的表?
1条答案
按热度按时间ryevplcw1#
无法通过DatabaseIfNotExist =true的jdbcUrl自动创建数据库。这是预期的行为吗?所以我使用了connectionFactoryConfig.initialSql(“如果不存在则创建数据库“+数据库)
参见https://stackoverflow.com/a/73669197/6692043
如何自动创建类似quarkus. hibernate-database.generation=update的表?
我不确定您是否可以直接调用Hibernate ORM来实现这一点,至少不需要付出很大的努力,因为大多数这些工具都是为单租户而设计的。
我建议您最好在开发应用程序时转储Hibernate ORM的模式初始化脚本,并在连接到新的目录时(并且您检测到它为空)手动应用这些脚本。
理想情况下,您会使用Flyway进行此类操作。但是如果你使用的是动态对象注入,你可能不能依赖Quarkus的
Flyway
对象注入,而必须手动构建Flyway
对象。