Spring多数据源的配置

本文介绍了在项目开发中处理多数据源的需求,详细讲解了如何在Spring中配置多数据源,以及如何实现数据源的动态切换。通过配置applicationContext.xml文件,创建上下文环境类和动态数据源类,结合AbstractRoutingDataSource实现数据源的切换,确保在需要时能正确操作特定数据库。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值