首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >动态设置hibernate方言

动态设置hibernate方言
EN

Stack Overflow用户
提问于 2018-05-11 20:51:45
回答 2查看 7.3K关注 0票数 10

我已经实现了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方言?

EN

回答 2

Stack Overflow用户

发布于 2018-05-28 20:18:05

我不明白为什么您不能使用纯粹基于注释的配置来实现这一点。我这样设置我的方言:

properties.put("hibernate.dialect", "org.hibernate.dialect.SQLServerDialect");

如果配置文件中的某个值设置为ON,我实际上有一些代码可以完全重建数据库以及一些测试数据。您应该能够通过切换到完全基于java的配置来执行相同的操作。

票数 0
EN

Stack Overflow用户

发布于 2021-09-22 07:59:55

如果您没有设置显式方言,hibenrate将使用DialectResolver实现类自动解析它。

您可以编写自己的autoresolver。OwnDialectResolver example

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50292775

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档