Hibernate配置多个数据源和多个会话工厂

时间:2013-12-12 11:02:55

标签: spring hibernate

我使用的是Spring和Hibernate弹簧配置如下。如何配置两个数据源,会话工厂。使用注释管理事务。请指教

<!-- we can use annotations -->
<context:annotation-config/>

<!-- package to look for annotated classes -->
<context:component-scan base-package="com.XXX.XXX.service.impl"/>

<!-- we will manage transactions with annotations -->
<tx:annotation-driven/>


<bean id="transactionManager"   class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

<!-- configure hibernate session factory -->

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close" p:driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
    p:url="jdbc:sqlserver://DB_NAME\DB_INSTANCE:DB_PORT;databaseName=DB_NAME;username=DB_USER;password=DB_PASSWORD;" />

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
   <property name="dataSource" ref="dataSource" />
    <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
            <prop key="hibernate.current_session_context_class">thread</prop>
            <prop key="show_sql">false</prop>
        </props>
    </property>

</bean>

4 个答案:

答案 0 :(得分:15)

<!-- configure hibernate session factory for FirstDB -->

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close" p:driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
    p:url="jdbc:sqlserver://${FirstDB_DB_HosName}\${FirstDB_DB_instanceName}:${FirstDB_DB_PortNumber};databaseName=${FirstDB_DB_DatabaseName};username=${FirstDB_DB_UserName};password=${FirstDB_DB_Password};" />

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
   <property name="dataSource" ref="dataSource" />
    <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
            <prop key="hibernate.current_session_context_class">thread</prop>
            <prop key="show_sql">false</prop>
        </props>
    </property>

</bean>


 <!-- configure hibernate session factory for SecondDB database -->

<bean id="SecondDBdataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close" p:driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
    p:url="jdbc:sqlserver://${SecondDB_DB_HOST}\${SecondDB_DB_INSTANCE}:${SecondDB_DB_PORT};databaseName=${SecondDB_DB_DATABASENAME};username=${SecondDB_DB_USERNAME};password=${SecondDB_DB_PASSWORD};" />


 <bean id="secondDBSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
   <property name="dataSource" ref="SecondDBdataSource" />
    <property name="configLocation">
            <value>classpath:hibernate-SecondDB.cfg.xml</value>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
            <prop key="hibernate.current_session_context_class">thread</prop>
            <prop key="show_sql">false</prop>
        </props>
    </property> 

</bean>

在Hibernate DAO中,我们可以使用@Qualifier注释来连接2个会话工厂

/**
 * Basic DAO operations dependent with Hibernate's specific classes
 * @see SessionFactory
 */
@Transactional(propagation= Propagation.REQUIRED, readOnly=false)
public class HibernateDao<E, K extends Serializable> implements GenericDao<E, K> {

  @Autowired
  @Qualifier(value="sessionFactory")
  private SessionFactory sessionFactory;

  @Autowired
  @Qualifier(value="secondDBSessionFactory")
  private SessionFactory secondDBSessionFactory;


  protected Class<? extends E> daoType;

  public HibernateDao() {
    daoType = (Class<E>) ((ParameterizedType) getClass().getGenericSuperclass())
                    .getActualTypeArguments()[0];
  }

  //Remaining Code
}

答案 1 :(得分:2)

您可以在我的项目中显示简单配置

 <context:component-scan base-package="it.dommy.portmaga" />

<context:property-placeholder location="default.properties" />

<!-- Enable annotation style of managing transactions -->
<tx:annotation-driven />

<context:annotation-config/>


<bean id="dataSource"class="com.mchange.v2.c3p0.ComboPooledDataSource"
      destroy-method="close" >
    <property name="driverClass" value="${db.driverClassName}" />
    <property name="jdbcUrl" value="${db.url}" />
    <property name="user" value="${db.username}" />
    <property name="password" value="${db.password}" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${hibernate.dialect}</prop>
            <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
            <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
            <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
            <prop key="hibernate.hbm2ddl.auto">create-drop</prop>
            <!--<prop key="hibernate.use_sql_comments">${hibernate.use_sql_comments}</prop>-->
            <!--<prop key="hibernate.validator.apply_to_ddl">${hibernate.validator.apply_to_ddl}</prop>-->
            <!--<prop key="hibernate.max_fetch_depth">${hibernate.max_fetch_depth}</prop>-->
            <!--<prop key="hibernate.default_batch_fetch_size">${hibernate.default_batch_fetch_size}</prop>-->
            <!--<prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop>-->
            <!--<prop key="hibernate.validator.autoregister_listeners">true</prop>-->
            <!-- This will drop our existing database and re-create a new one. -->

        </props>
    </property>
    <property name="packagesToScan">
        <list>
            <value>it.dommy.portmaga.model.mysql</value>
        </list>
    </property>
</bean>

<bean id="secondDBdataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
      destroy-method="close">
<property name="driverClass" value="${dba.driverClassName}" />
<property name="jdbcUrl" value="${dba.url}" />
<property name="user" value="${dba.username}" />
<property name="password" value="${dba.password}" />
</bean>

<bean id="secondSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="secondDBdataSource" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${hibernate.a.dialect}</prop>
            <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
        </props>
    </property>
    <property name="packagesToScan">
        <list>
            <value>it.dommy.portmaga.model.access</value>
        </list>
    </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="secondSessionFactory" />

</bean>

如果您不显示所有项目,请转到此处:https://bitbucket.org/dgabriele/portmaga

答案 2 :(得分:1)

  

调度-servlet.xml中

ORDER BY Category, Brand, Price
  

Web.xml中

                <bean id="full-license-db-dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                    <property name="driverClassName" value="${db.driver}" />
                    <property name="url" value="${db.full.url}" />
                    <property name="username" value="${db.full.username}" />
                    <property name="password" value="${db.full.password}" />
                </bean>

                <bean id="sessionFactoryFull"
                      class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
                    <property name="packagesToScan"       value="ci.xyz.license.model.entity.full"/>  
                    <property name="dataSource" ref="full-license-db-dataSource" />
                    <property name="hibernateProperties">
                        <props>
                            <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}    </prop>
                            <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                            <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                        </props>
                    </property>
                </bean>



                <bean id="trial-license-db-dataSource"
                    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                    <property name="driverClassName" value="${db.driver}" />
                    <property name="url" value="${db.trial.url}" />
                    <property name="username" value="${db.trial.username}" />
                    <property name="password" value="${db.trial.password}" />
                </bean>

                <bean id="sessionFactoryTrial"
                      class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
                    <property name="dataSource" ref="trial-license-db-dataSource" />
                    <property name="packagesToScan" value="ci.xyz.license.model.entity.trial"/>
                    <property name="hibernateProperties">
                        <props>
                            <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
                            <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                            <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                        </props>
                    </property>
                </bean>

                <bean id="transactionManagerTrial"
                       class="org.springframework.orm.hibernate4.HibernateTransactionManager">
                    <property name="sessionFactory" ref="sessionFactoryTrial" />
                </bean>
                <bean id="transactionManagerFull"         class="org.springframework.orm.hibernate4.HibernateTransactionManager">
                    <property name="sessionFactory" ref="sessionFactoryFull" />
                </bean>
                <tx:annotation-driven transaction-manager="transactionManagerFull" />
                <tx:annotation-driven transaction-manager="transactionManagerTrial" />
  

Dao的Java代码供快速参考

<filter> <filter-name>hibernateFilterTrial</filter-name> <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class> <init-param> <param-name>sessionFactoryBeanName</param-name> <param-value>sessionFactoryTrial</param-value> </init-param> </filter> <filter-mapping> <filter-name>hibernateFilterTrial</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping> <filter> <filter-name>hibernateFilterFull</filter-name> <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class> <init-param> <param-name>sessionFactoryBeanName</param-name> <param-value>sessionFactoryFull</param-value> </init-param> </filter> <filter-mapping> <filter-name>hibernateFilterFull</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping>

@Repository @Scope(BeanDefinition.SCOPE_PROTOTYPE) public abstract class AbstractHibernateDao implements IBaseDao { private static final Log logger = LogFactory.getLog(AbstractHibernateDao.class);

      @Autowired
      protected SessionFactory sessionFactoryFull;

      @Autowired
      protected SessionFactory sessionFactoryTrial;



      protected Class<T> persistentClass;

答案 3 :(得分:0)

新版本Hibernate的更新答案
从hibernate 5版本开始,您必须为每个数据源定义事务管理器,但是如果您在源代码中使用常规的@Transaction批注,这将使事务管理器感到困惑,默认情况下,休眠将采用您的第一个定义事务管理器xml文件,并在任何代码上用于所有@Transaction注释。为避免此问题,您需要为代码上的每个@Transaction手动定义事务管理器。示例:

  <!-- Step 1: Define First Database DataSource / connection pool -->
<bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
      destroy-method="close">
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    <property name="jdbcUrl"
              value="jdbc:mysql://localhost:3306/spring_security_custom_user_demo?allowPublicKeyRetrieval=true&amp;useSSL=false&amp;serverTimezone=UTC"/>
    <property name="user" value="{user}"/>
    <property name="password" value="{password}"/>

    <!-- these are connection pool properties for C3P0 -->
    <property name="minPoolSize" value="4"/>
    <property name="maxPoolSize" value="20"/>
    <property name="maxIdleTime" value="30000"/>
    <property name="initialPoolSize" value="5"/>
</bean>

<!-- Step 2: Setup Hibernate session factory -->
<bean id="sessionFactory"
      class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <property name="dataSource" ref="myDataSource"/>
    <property name="packagesToScan" value="com.springdemo.entity"/>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>

<!-- Step 3: Setup Hibernate transaction manager -->
<bean id="myTransactionManager"
      class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>


<!-- end -->

<!-- Step 1: Define Second Database DataSource / connection pool -->
<bean id="myDataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource"
      destroy-method="close">
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    <property name="jdbcUrl"
              value="jdbc:mysql://localhost:3306/web_customer_tracker?allowPublicKeyRetrieval=true&amp;useSSL=false&amp;serverTimezone=UTC"/>
    <property name="user" value="{user}"/>
    <property name="password" value="{password}"/>

    <!-- these are connection pool properties for C3P0 -->
    <property name="minPoolSize" value="4"/>
    <property name="maxPoolSize" value="20"/>
    <property name="maxIdleTime" value="30000"/>
    <property name="initialPoolSize" value="5"/>
</bean>

<!-- Step 2: Setup Hibernate session factory -->
<bean id="sessionFactory2"
      class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <property name="dataSource" ref="myDataSource2"/>
    <property name="packagesToScan" value="com.springdemo.entity"/>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
        </props>
    </property>
</bean>

<!-- Step 3: Setup Hibernate transaction manager -->
<bean id="myTransactionManager2"
      class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory2"/>
</bean>

<!-- Step 4: Enable configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="myTransactionManager"/>
<tx:annotation-driven  transaction-manager="myTransactionManager2"/>

这是@Transaction注释示例。

    @Transactional("myTransactionManager")
    public User findByUsername(String username) {
          return userDao.findByUsername(username);

  }

如果需要引用使用另一个数据源的另一个事务管理器。

    @Transactional("myTransactionManager2")
    public User findByUsername(String username) {
          return userDao.findByUsername(username);

  }