我在Sping Boot (Data JPA)应用程序中使用AbstractRoutingDataSource
,根据请求参数访问不同的数据库(Mariadb、SQL Server)。
public class DataSourceRouter extends AbstractRoutingDataSource {
public DataSourceRouter(Map<Object, Object> targetDataSources, DataSource defautDataSource) {
setTargetDataSources(targetDataSources);
setDefaultTargetDataSource(defautDataSource);
}
@Override
protected Object determineCurrentLookupKey() {
return SelectedDataSourceContextHolder.getSelectedDataSource();
}
}
该数据源(routingDatasource)配置到LocalContainerEntityManagerFactoryBean
中。
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
final EntityManagerFactoryBuilder builder) {
return buildEntityManagerFactory(builder, routingDatasource());
}
protected LocalContainerEntityManagerFactoryBean buildEntityManagerFactory(final EntityManagerFactoryBuilder builder, DataSource dataSource) {
return builder.dataSource(dataSource)
.packages(SomeEntity.class.getPackageName()).properties(
Map.of("hibernate.dialect_resolvers", "xxx.DynamicDialectResolver")
)
.build();
}
这种方法的问题是我们只能配置一种Hibernate方言,它应该是动态的,取决于底层所选的数据源。
public class DynamicDialectResolver implements DialectResolver {
@Override
public Dialect resolveDialect(DialectResolutionInfo info) {
Dialect dialect;
switch (info.getDatabaseName()) {
case "MariaDB":
dialect = new org.hibernate.dialect.MySQL5Dialect();
break;
case "SQL Server":
dialect = new org.hibernate.dialect.SQLServer2012Dialect();
break;
default:
dialect = null;
break;
}
return dialect;
}
}
然而,这个解析器只被调用一次,所以所选的方言被固定为它第一次选择的方言。
有没有办法在运行时动态地设置方言?
1条答案
按热度按时间pftdvrlh1#
这是不可能的。Hibernate在 Bootstrap 上生成特定于方言的SQL,然后缓存。如果需要支持多个数据库,则需要多个会话工厂或持久化单元。