Spring多数据源的配置

来源:互联网 发布:uboot源码详解 编辑:程序博客网 时间:2024/05/22 14:07

1.业务需求

在项目开发中,经常会遇到需要操作多个数据源的情况,比如数据同步,在数据库A中增加数据的同时写入数据库B。这就需要做到可以配置多个数据源,并做到动态切换数据源。

2.多数据源配置

首先是多数据源的配置,在applicationContext.xml文件中。
主要配置代码如下:

    <!-- 定义数据源的信息 -->      <bean id="parentDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"          destroy-method="close">          <property name="driverClass">              <value>com.mysql.jdbc.Driver</value>          </property>        <property name="maxPoolSize">              <value>80</value>          </property>          <property name="minPoolSize">              <value>1</value>          </property>          <property name="initialPoolSize">              <value>1</value>          </property>          <property name="maxIdleTime">              <value>20</value>          </property>      </bean>       <bean id="dataSource_local" parent="parentDataSource">        <property name="jdbcUrl">              <value>jdbcUrl_local</value>          </property>          <property name="user">              <value>root</value>          </property>          <property name="password">              <value>password</value>        </property>       </bean>    <bean id="dataSource_remote" parent="parentDataSource">           <property name="jdbcUrl">              <value>jdbcUrl_remote</value>          </property>          <property name="user">              <value>root</value>          </property>          <property name="password">              <value>password</value>          </property>      </bean>     <!-- 动态DataSource配置 -->      <bean id="dynamicDataSource" class="gov.pbc.util.DynamicDataSource">          <property name="targetDataSources">              <map key-type="java.lang.String">                  <entry key="dataSource_local" value-ref="dataSource_local"/>                  <entry key="dataSource_remote" value-ref="dataSource_remote"/>              </map>          </property>          <property name="defaultTargetDataSource" ref="dataSource_local"/>      </bean>    <!--定义Hibernate的SessionFactory -->      <!-- SessionFactory使用的数据源为上面的数据源 -->      <!-- 指定了Hibernate的映射文件和配置信息 -->      <bean id="sessionFactory"          class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">          <property name="dataSource" ref="dynamicDataSource" />        <!-- 设置自动扫描,这样就不用一一注册model的ORM映射了  -->        <property name="packagesToScan">            <list>                <value>com.test.model</value>            </list>        </property>          <!-- 设置Hibernate的相关属性 -->        <property name="hibernateProperties">            <props>                <!-- 设置Hibernate的数据库方言 -->                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>                <!-- 设置Hibernate是否在控制台输出SOL语句,开发调试阶段通常设置为true -->                <prop key="hibernate.show_sql">true</prop>                <prop key="hibernate.format_sql">true</prop>                <prop key="hibernate.current_session_context_class">thread</prop>                <prop key="hbm2ddl.auto">update</prop>                <prop key="hibernate.connection.release_mode">after_statement</prop>            </props>        </property>     </bean>    <bean id="hbnTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">        <property name="sessionFactory" ref="sessionFactory"></property>    </bean>    <bean id="txManager"          class="org.springframework.orm.hibernate3.HibernateTransactionManager">          <property name="sessionFactory" ref="sessionFactory" />      </bean>    <!-- 开启基于@Transactional注解方式的事务管理 -->    <tx:annotation-driven transaction-manager="txManager"/>

3.数据源动态切换

首先,建立一个获得和设置上下文环境的类,主要负责改变上下文数据源的名称。代码如下:

public class CustomContextHolder {    private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();      public static final String DATA_SOURCE_LOCAL = "dataSource_local";//对应动态数据源配置中的key      public static final String DATA_SOURCE_REMOTE = "dataSource_remote";      public static void setCustomerType(String customerType) {           contextHolder.set(customerType);      }      public static String getCustomerType() {          return contextHolder.get();      }      public static void clearCustomerType() {          contextHolder.remove();      }}

然后,建立动态数据源类,注意,这个类必须继承AbstractRoutingDataSource,且实现方法determineCurrentLookupKey。代码如下:

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class DynamicDataSource extends AbstractRoutingDataSource{    @Override      protected Object determineCurrentLookupKey() {          String sourceType = CustomContextHolder.getCustomerType();          //System.out.println("DataSourceType: "+sourceType);          return sourceType;      } }

4.执行数据源的切换

在需要对某个数据库进行操作前,执行切换数据源的代码,个人习惯在service类中执行切换。示例代码如下:

import javax.annotation.Resource;import com.test.dao.LoTeacherDAO;import com.test.dao.ReTeacherDAO;import com.test.model.LoTeacher;import com.test.model.ReTeacher;import com.test.util.CustomContextHolder;public class TeacherServiceImpl implements TeacherService{    @Resource    private LoTeacherDAO loTeacherDAO;    @Resource    private ReTeacherDAO reTeacherDAO;    public void addLoTeacher(LoTeacher loTea){        CustomContextHolder.setCustomerType(CustomContextHolder.DATA_SOURCE_LOCAL);        loTeacherDAO.save(loTea);    }    public void addReTeacher(ReTeacher reTea){        CustomContextHolder.setCustomerType(CustomContextHolder.DATA_SOURCE_REMOTE);        reTeacherDAO.save(reTea);    }}
原创粉丝点击