gpt4 book ai didi

java - 动态设置 hibernate 方言

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:02:22 29 4
gpt4 key购买 nike

我已经实现了 Hibernate's multitenant database architecture ,其中根据租户选择特定的数据库连接。我正在使用 Spring 4.3 和 Hibernate 5.2。

当租户使用相同的 RDBMS 时一切都很好,但是当他们不同时,我必须动态地更改 hibernate 属性中的方言设置,我不知道该怎么做。

我的 hibernate 属性在 dispatcher-servlet.xml 中:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<context:component-scan base-package="com.example"/>
<mvc:annotation-driven/>
<context:property-placeholder location="classpath:application.properties"/>
<tx:annotation-driven transaction-manager="transactionManager"/>

<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" >
<property name="packagesToScan">
<list>
<value>com.example.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<!--<prop key="hibernate.dialect">${hibernate.dialect}</prop>-->
<prop key="hibernate.show_sql">${hibernate.show_sql:false}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql:false}</prop>
<prop key="hibernate.multiTenancy">DATABASE</prop>
<prop key="hibernate.tenant_identifier_resolver">com.example.multitenancy.CurrentTenantIdentifierResolverImpl</prop>
<prop key="hibernate.multi_tenant_connection_provider">com.example.multitenancy.MultiTenantConnectionProviderImpl</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>

下面是 Hibernate 的 CurrentTenantIdentifierResolver 的实现:

public class CurrentTenantIdentifierResolverImpl implements CurrentTenantIdentifierResolver {
@Override
public String resolveCurrentTenantIdentifier() {

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return Helper.getTenantFromAuthentication(authentication);
}
@Override
public boolean validateExistingCurrentSessions() {
return true;
}
}

以及 AbstractDataSourceBasedMultiTenantConnectionProviderImpl 的实现:

public class MultiTenantConnectionProviderImpl extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {

@Override
protected DataSource selectAnyDataSource() {
return getDataSource("tenantId1");
}
@Override
protected DataSource selectDataSource(String tenantIdentifier) {
return getDataSource(tenantIdentifier);
}

private DataSource getDataSource(String prefix) {

Properties properties = new Properties();
try {
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("application.properties"));

} catch (IOException e) {
throw new RuntimeException();
}

DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(properties.getProperty(prefix + ".driverClassName"));
dataSource.setUrl(properties.getProperty(prefix + ".url"));
dataSource.setUsername(properties.getProperty(prefix + ".username"));
dataSource.setPassword(properties.getProperty(prefix + ".password"));
return dataSource;
}
}

application.properties 文件如下所示:

tenantId1.driverClassName = org.postgresql.Driver
tenantId1.url = <...>
tenantId1.username = <...>
tenantId1.password = <...>

tenantId2.driverClassName = com.mysql.jdbc.Driver
tenantId2.url = <...>
tenantId2.username = <...>
tenantId2.password = <...>

有没有办法动态改变 hibernate 方言?

最佳答案

您无法使用单个 hibernate 配置文件来实现。每个数据库都需要不同的配置文件。

比如你有两个数据库MySql和Oracle:

配置mysql数据库

hibernate-mysql.cfg.xml

配置oracle数据库

hibernate-oracle.cfg.xml

创建两个不同的 session ,代码应该是这样的。

private static SessionFactory sessionAnnotationFactory; 

sessionAnnotationFactory = new Configuration().configure("hibernate-mysql.cfg.xml").buildSessionFactory();

Session MySqlSession = sessionAnnotationFactory.openSession();

Oracle 数据库配置

sessionAnnotationFactory = new Configuration().configure("hibernate-oracle.cfg.xml").buildSessionFactory();

Session OracleSession = sessionAnnotationFactory.openSession()

关于java - 动态设置 hibernate 方言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50292775/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com