通过spring配置两个数据源的实现方法(一)

在项目中遇到要求从第三方供应商那边拉取数据来进行查询显示,在原有项目结构完整的前提下,需要配置新的数据源
这里写图片描述
通过在网上的搜索,找到两种方法。
第一种是直接新建一个sessionfactory注入所需要的DataSource
这里写图片描述
第二种是在同一个sessionfactory中动态的切换DataSource
这里写图片描述
本文采取第一种方式来完成 第二种方式在下一篇文章中完成

1.需求数据库是SqlServer数据库 所以在数据库属性文件database.properties中添加需要配置的数据库属性

//oracle数据库配置
database.driverClassName=oracle.jdbc.driver.OracleDriver
database.url=jdbc:oracle:thin:@171.***.**.21:****:BRUCE
database.username=MES_V1
database.password=*****

//SqlServer数据库配置
SqlServer.driverClass=com.microsoft.sqlserver.jdbc.SQLServerDriver
SqlServer.url=jdbc:sqlserver://171.188.96.***;databasename=producedemo
SqlServer.username=qgmes
SqlServer.password=*****

hibernate.show_sql=true
hibernate.format_sql=true
hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext

注意在此处的hibernate.current_session_context_class不要设置成thread会导致no session found for current thread

2.在spring配置文件中进行配置,本文配置文件是spring-database.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
      xmlns:aop="http://www.springframework.org/schema/aop"
      xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
">

       <!-- 配置oracle数据源DataSource --> 
     <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
            init-method="init" destroy-method="close">
            <!-- 基本属性 url、user、password -->
            <property name="driverClassName" value="${database.driverClassName}" />
            <property name="url" value="${database.url}" />
            <property name="username" value="${database.username}" />
            <property name="password" value="${database.password}" />
     </bean>
          <!-- 配置SqlServer数据源DataSource2 -->   
     <bean id="dataSource2" class="com.alibaba.druid.pool.DruidDataSource"
            init-method="init" destroy-method="close">
            <!-- 基本属性 url、user、password -->
            <property name="driverClassName" value="${SqlServer.driverClass}" />
            <property name="url" value="${SqlServer.url}" />
            <property name="username" value="${SqlServer.username}" />
            <property name="password" value="${SqlServer.password}" />
          </bean>
          <!--新建sessionfactory注入DataSource数据源-->
      <bean id="sessionFactory" class="com.jfly.commons.web.spring.LocalSessionFactoryBeanExt">
            <property name="dataSource" ref="dataSource" />
            <property name="hibernateProperties">
                  <props>
                        <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                        <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                        <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
                        <prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>
                        <prop key="hibernate.current_session_context_class">
                        ${hibernate.current_session_context_class}</prop>
                  </props>
            </property>
            <!-- 自动扫描注解方式配置的hibernate类文件 -->
            <property name="packagesToScan">
                  <list>
                        <value>com.jfly.apps.sysmanager.entity</value>
                        <value>com.jfly.commons.taskserver.entity</value>
                  </list>
            </property>
      </bean>
<!--新建sessionfactory2注入DataSource2数据源-->
     <bean id="sessionFactory2" class="com.jfly.commons.web.spring.LocalSessionFactoryBeanExt">
     <property name="dataSource" ref="dataSource2" />
     <property name="hibernateProperties">
          <props>
               <prop key="hibernate.dialect">${hibernate.dialect}</prop>
               <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
               <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
               <prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>
<prop key="hibernate.current_session_context_class">${hibernate.current_session_context_class}</prop>

           </props>
      </property>   
      <!-- 自动扫描注解方式配置的hibernate类文件 -->
      <property name="packagesToScan">
             <list>
                  <value>com.jfly.apps.sysmanager.entity</value>
                  <value>com.jfly.commons.taskserver.entity</value>
             </list>
       </property>
      </bean>
      <!-- 配置sessionfactory的事务处理,把sessionfactory注入TransactionManager --> 
      <bean id="transactionManager"
            class="org.springframework.orm.hibernate4.HibernateTransactionManager">
            <property name="sessionFactory">
                  <ref local="sessionFactory" />
            </property>
      </bean>
       <!-- 配置sessionfactory2的事务处理,把sessionfactory2注入TransactionManager2 --> 
      <bean id="transactionManager2"
            class="org.springframework.orm.hibernate4.HibernateTransactionManager">
            <property name="sessionFactory">
                  <ref local="sessionFactory2" />
            </property>
      </bean>
       <!-- 使用tx标签配置的拦截器--> 
      <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                  <tx:method name="add*" propagation="REQUIRED" />
                  <tx:method name="insert*" propagation="REQUIRED" />
                  <tx:method name="save*" propagation="REQUIRED" />
            </tx:attributes>
      </tx:advice>
      <tx:advice id="transactionAdvice2" transaction-manager="transactionManager2">
            <tx:attributes>
                  <tx:method name="add*" propagation="REQUIRED" />
                  <tx:method name="insert*" propagation="REQUIRED" />
                  <tx:method name="save*" propagation="REQUIRED" />
            </tx:attributes>
      </tx:advice>   
       <!-- 配置aop设置注入点 -->   
      <aop:config>
            <aop:pointcut id="transactionPointcut"
                  expression="execution(* com.jfly.commons.op.BaseHibernateDao.*(..))
                  || execution(* com.jfly.commons.service.*Service.*(..))
                  || execution(* com.jfly.commons.version.*Service.*(..))  " />
            <aop:advisor pointcut-ref="transactionPointcut"
                  advice-ref="transactionAdvice" />
            <aop:advisor pointcut-ref="transactionPointcut"
                  advice-ref="transactionAdvice2" />
      </aop:config>
</beans>

这个配置文件是最重要的部分,决定着最后session的获取,主要有一下几点需要注意

  1. hibernate属性设置时,一定要注意hibernate.current_session_context_class的设置,不然会出现no session found for current thread异常需要设置成org.springframework.orm.hibernate4.SpringSessionContext
  2. 不同的sessionfactory需要设置不同的transactionmanager
  3. 不同的transactionmanager需要配置不同的tx标签配置的拦截器
  4. aop:pointcut可以共用

3.在配置完sessionfactory后,需要在dao层进行配置,再这个项目中只需要进行查询操作。在action层中调用query方法,session的注入是在dao层的所以需要重写dao层,不能在原有的dao层进行操作。

protected SessionFactory sessionFactory;

    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }
    //采用注解的方式进行注入
    @Resource(name = "sessionFactory")
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    // 事务必须是开启的,否则获取不到
    public Session getSession() {
        return sessionFactory.getCurrentSession();
    }
protected SessionFactory sessionFactory;

    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }
    //采用注解的方式进行注入
    @Resource(name = "sessionFactory2")
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    // 必须重新创建一个新的session来满足
    public Session getSession() {
        Session session = sessionFactory.openSession();
        return session;
    }

在这里很容产生 no session found for current thread的异常
注意第二个session的获取需要通过openSession的方法进行获得,因为getSession()的方法是从线程中获取session的,当线程中已有session就直接获取,如果没有则才会新建。在这里因为需要获得两个session,所以第二个就需要通过opensession的方式进行获得
关于 no session found for current thread这个异常在另一篇文章在进行详细的介绍

4.dao层调用方法,完成两个数据源的配置

猜你喜欢

转载自blog.csdn.net/sinat_29774479/article/details/75642932
今日推荐