【问题标题】:Multiple Schema Configuration On Spring MVC + Hibernate + JPASpring MVC + Hibernate + JPA 上的多模式配置
【发布时间】:2017-03-19 15:26:48
【问题描述】:

我目前在数据库中为应用程序中的所有事务使用 1 个架构(称为 SCHEMAADMIN),每个表都在这 1 个架构中。

然后我的公司正在重组数据库管理,并要求每个应用程序有 1 个读/写方案,并且只允许只读/选择主模式,这是我当前正在使用的模式 (SCHEMAADMIN)。

这是我的 data.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:tx="http://www.springframework.org/schema/tx"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/jdbc
    http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
    http://www.springframework.org/schema/data/jpa
    http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

<jpa:repositories base-package="org.portal.data.repository" />

<tx:annotation-driven />

<bean id="transactionManager"
    class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="database" value="${database.database}"/>
            <property name="databasePlatform" value="${database.databasePlatform}"/>
            <property name="showSql" value="${database.showSql}"/>
            <property name="generateDdl" value="${database.generateDdl}"/>
        </bean>
    </property>
    <property name="packagesToScan" value="org.portal.entity"/>
</bean>

<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
    <property name="driverClassName" value="${database.driverClassName}" />
    <property name="url" value="${database.url}" />
    <property name="username" value="${database.username}" />
    <property name="password" value="${database.password}" />
    <property name="testOnBorrow" value="true" />
    <property name="testOnReturn" value="true" />
    <property name="testWhileIdle" value="true" />
    <property name="timeBetweenEvictionRunsMillis" value="1800000" />
    <property name="numTestsPerEvictionRun" value="3" />
    <property name="minEvictableIdleTimeMillis" value="1800000" />
    <property name="initialSize" value="1" />
    <property name="maxActive" value="50" />
    <property name="maxIdle" value="20" />
</bean>

那么这是config.properties文件,

# database general setting
database.database=ORACLE
database.databasePlatform=org.hibernate.dialect.Oracle10gDialect
database.showSql=false
database.generateDdl=false
database.driverClassName=oracle.jdbc.driver.OracleDriver

# DEVELOPMENT local
http://localhost:8080
database.url=jdbc:oracle:thin:@192.168.1.1/orcl
database.username=schemaadmin
database.password=password
security.login.callbackUrl=http://localhost:8080/security/callback

新架构位于相同的数据库/url 中,但用户名和密码不同。我对在哪里/如何在这个文件中连接另一个感到困惑。通过谷歌阅读一些信息,但我现在实际上很困惑。

请指教。谢谢。

【问题讨论】:

    标签: hibernate spring-mvc jpa oracle11g


    【解决方案1】:

    新架构位于相同的数据库/url,但用户名不同 和密码。我

    对于 Oracle,Schema 和 User 紧密相关。

    我建议使用无 JTA 解决方案,因为您的配置不依赖于 Java EE 数据源。
    要解决此更改,您应该考虑拥有两组 datasources/entityManagerfactory/transactionmanager :一组用于只读用户/模式,另一组用于读写用户/模式。 当然,通用配置也可以考虑到属性中。

    为了给你一个想法,我修改了你的 xml conf 并开始了工作(我没有考虑属性重复,但你应该这样做):

    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/jdbc
        http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
        http://www.springframework.org/schema/data/jpa
        http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
    
    <jpa:repositories base-package="org.portal.data.repository" />
    
    <!-- The original declaration is no longer valid --!>
    <tx:annotation-driven  transaction-manager="transactionManagerRead" />
    
    <bean id="transactionManagerRead"
        class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactoryRead"/>
    </bean>
    
    <bean id="transactionManagerReadWrite"
        class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactoryReadWrite"/>
    </bean>
    
    <bean id="entityManagerFactoryRead"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSourceRead" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="database" value="${database.database}"/>
                <property name="databasePlatform" value="${database.databasePlatform}"/>
                <property name="showSql" value="${database.showSql}"/>
                <property name="generateDdl" value="${database.generateDdl}"/>
            </bean>
        </property>
        <property name="packagesToScan" value="org.portal.entity"/>
    </bean>
    <bean id="entityManagerFactoryReadWrite"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSourceReadWrite" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="database" value="${database.database}"/>
                <property name="databasePlatform" value="${database.databasePlatform}"/>
                <property name="showSql" value="${database.showSql}"/>
                <property name="generateDdl" value="${database.generateDdl}"/>
            </bean>
        </property>
        <property name="packagesToScan" value="org.portal.entity"/>
    </bean>    
    

    所以……

    但是在 spring 配置中有一个棘手的问题:

    <tx:annotation-driven/>
    

    它默认使用名为transactionManager 的事务管理器bean。因此,您应该像我一样使用其中一个事务管理器对其进行配置:

    <tx:annotation-driven  transaction-manager="transactionManagerRead" />
    

    然后,要在您的处理中应用合适的事务管理器,您应该在 Spring 服务中指定要使用的 transactionManager(读取或读写)。您还可以定义默认使用的主要transactionManager。安全起见,应该是transactionManager,限制最多。

    例如,在您只进行读取的 Spring Service Bean 中,您可以声明该类以使用只读事务管理器:

    @Transactional(transactionManager="TransactionManagerRead")
    public class CustomerSearchService(){
    ...
    

    当然,您可以在方法级别定义事务管理器。
    但理想情况下,如果您的写作和阅读方法几乎一样多,您应该检查是否可以重新设计或重新排列您的类以收集只读和写入方法。它将更易于维护且不易出错。

    【讨论】:

      猜你喜欢
      • 2011-09-02
      • 2015-06-25
      • 2013-04-22
      • 1970-01-01
      • 2016-06-12
      • 1970-01-01
      • 2019-06-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多