Hibernate使用多个数据库

ric*_*ell 15 orm spring dao hibernate

有人知道如何在hibernate配置中添加另一个数据源,以及如何在我自己的DAO中将Spring配置为该数据源的自动注入?

这是我的代码,有一个数据源,运行完美,但我不知道如何添加另一个数据源.我想添加另一个数据源,它是一个数据库,其表格与实际数据库不同.

HIBERNATE CONF

 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
            <value>com.mysql.jdbc.Driver</value>
        </property>
        <property name="url" value="jdbc:mysql://localhost/personal"/>
        <property name="username" value="root"/>
        <property name="password" value="mysql"/>
    </bean>


    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource">
            <ref local="dataSource"/>
        </property>
        <property name="packagesToScan">
            <list>
                <value>com.app.personal.model</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">false</prop>
            </props>
        </property>
    </bean>

    <tx:annotation-driven/>
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref local="sessionFactory"/>
        </property>
    </bean>
Run Code Online (Sandbox Code Playgroud)

DAO示例

@Repository
public class ModuloDAOHibernate extends HibernateTemplate implements ModuloDAO {

    @Autowired
    public ModuloDAOHibernate(SessionFactory sessionFactory) {
        super(sessionFactory);
    }

    public List<Modulo> getAllGrupoModuloDAO() {
        Criteria criteriaList = this.getSession().createCriteria(Modulo.class);
        criteriaList.addOrder(Order.asc("orden"));
        return criteriaList.list();
    }
Run Code Online (Sandbox Code Playgroud)

Tom*_*icz 13

我假设你有一组应该使用dataSource1和适当的DAO sessionFactory1,而其他人应该使用不同的dataSouce2sessionFactory2基于dataSource2.当然,您需要声明您的第二个dataSource和其他bean:只需复制您已有的配置并更改bean ID以便它们不会发生冲突.一切都应该被镜像,除了<tx:annotation-driven/>:

<bean id="dataSource1" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <!-- ... -->
</bean>

<bean id="sessionFactory1" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource1"/>
    <!-- ... -->
</bean>

<bean id="transactionManager1" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory1"/>
    <!-- ... -->
</bean>


<bean id="dataSource2" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <!-- ... -->
</bean>

<bean id="sessionFactory2" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource2"/>
    <!-- ... -->
</bean>

<bean id="transactionManager2" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory2"/>
    <!-- ... -->
</bean>

<tx:annotation-driven transaction-manager="transactionManager1"/>
Run Code Online (Sandbox Code Playgroud)

这里出现了一个真正的问题:您现在有两个事务管理器绑定到不同的会话工厂,这些会话工厂又被路由到不同的数据源.但是@Transactional注释总是只使用一个事务管理器 - transactionManager默认命名的事务管理器(注意我明确指出transactionManager1.这意味着使用第二个数据源的DAO将参与在第一个数据源中启动的事务 - 这显然不是预期的.

有一些解决方法,比如在@Transactional注释中明确定义事务管理器名称(从未尝试过)或使用TransactionTemplate,但正如您所看到的,应该仔细考虑问题.

至于自动装配 - 如果您按名称自动装配,请将您的字段命名为会话工厂或数据源ID,它应该有效 - 但实际上是您最小的问题.

  • Spring 3增加了使用多个事务管理器的功能,允许您为每个事务管理器命名.详细信息可以在这里找到:http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#tx-multiple-tx-mgrs-with-attransactional (4认同)

ric*_*ell 9

好.我找到另一种解决方案,就是使用相同的方法:添加另一个dataSource和SessionFactory,接下来在DAO的方法中,使用sessionFactory来添加@Qualifier anottation,并使用sessionFactory所需的属性,如下所示:

  @Autowired 
    public ProgramaSgteDAOHibernate(@Qualifier("sessionFactory3") SessionFactory sessionFactory) { 
     super(sessionFactory); 
    }
Run Code Online (Sandbox Code Playgroud)


Vic*_*125 5

我有同样的问题。我通过创建解决了这个问题:applicationContext.xml

<!-- dataSource properies -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="classpath:dataSource.properties" />
</bean>

<!-- MySQL -->
<bean id="mySQLdataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${mySql.driverClassName}" />
    <property name="url" value="${mySql.url}" />
    <property name="username" value="${mySql.username}" />
    <property name="password" value="${mySql.password}" />
</bean>
<bean id="mySQLsessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="mySQLdataSource" />
    <property name="packagesToScan" value="com.victor.entity" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${mySql.dialect}</prop>
        </props>
    </property>
    <property name="configLocation">
        <value>classpath:hibernate.cfg.xml</value>
    </property>
</bean>

<bean id="mySQLtransactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="mySQLsessionFactory" />
</bean>
<tx:annotation-driven proxy-target-class="true"
    transaction-manager="mySQLtransactionManager" />

<!-- ORACLE -->
<bean id="oracleDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${oracle.driverClassName}" />
    <property name="url" value="${oracle.url}" />
    <property name="username" value="${oracle.username}" />
    <property name="password" value="${oracle.password}" />
</bean>
<bean id="oracleSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="oracleDataSource" />
    <property name="packagesToScan" value="com.victor.entity" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${oracle.dialect}</prop>
        </props>
    </property>
    <property name="configLocation">
        <value>classpath:hibernate.cfg.xml</value>
    </property>
</bean>
<tx:annotation-driven proxy-target-class="true"
    transaction-manager="oracleTransactionManager" />
<bean id="oracleTransactionManager"
    class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="oracleSessionFactory" />
</bean>
Run Code Online (Sandbox Code Playgroud)

在 Dao 中注入了带有 Qualifier 注释的 sessionFactory。就我而言,我有通用的 BaseEnity:

public abstract class BaseEntityDAOImpl<T extends BaseEntity> implements BaseEntityDAO<T> {

private Class<T> persistentClass;
@Autowired
@Qualifier("oracleSessionFactory")
SessionFactory sessionFactory;
}
Run Code Online (Sandbox Code Playgroud)

并在服务 bean 中使用注释:

@Service
@Transactional(propagation = Propagation.REQUIRED, readOnly = true, value = "oracleTransactionManager")
public class UserService {

@Autowired
private UserDAO dao;
}
Run Code Online (Sandbox Code Playgroud)

一切都很好。