SSM 配置两个数据源

SSM配置多个数据源

在项目中,难免会用到多个数据源,此篇文章以两个数据源为例

一、思路及实践步骤

1.确定需要使用的数据源

在datasource.properties文件配置数据源信息

jdbc.driverClassName = com.mysqL.jdbc.Driver
jdbc.urL = jdbc:mysqL://localhost:3306/one
jdbc.username = test1
jdbc.password = 123

jdbc.driverClassName2 = com.mysqL.jdbc.Driver
jdbc.urL2 = jdbc:mysqL://localhost:3307/one
jdbc.username2 = test2
jdbc.password2 = 123

2. SSM项目需要在XML里面进行相关配置

代码如下(示例):

<!--第一个数据库-->
<bean id="One_dataSource" class= "org.apache.commons.dbcp.BasicDataSource" destroy -method="close">
<property name= "driverClassName" value=" ${jdbc.driverCLassName}" />
<property name="urL"  value="${jdbc.urL}" />
<property name="username"  value="${jdbc.username}" />
<property name="password"  value="${jdbc.password}" />
<property name= "maxActive"  value= "30"/>
<property name="maxIdle" value="20" />
<property name="maxWait" value="60000" />
</bean>

<!--第二个数据库-->
<bean id="Two_dataSource" class= "org.apache.common.dbcp.BasicDataSource" destroy -method="close">
<property name= "driverClassName" value=" ${jdbc.driverCLassName2}" />
<property name="urL" value="${jdbc.urL2}" />
<property name="username"  value="${jdbc.username2}" />
<property name="password"  value="${jdbc.password2}" />
<property name= "maxActive" value= "30"/>
<property name="maxIdle" value="20" />
<property name="maxWait" value="60000" />>
</bean>

3.对两个数据源进行相关配置

<!--配置指定的类-->
<bean id="dataSource" class= "com.yjy.util.DynamicDataSource">
<property name ="targetDataSources">
<map key-type="java.Lang.String">
<--指定LookupKey和与之对应的数据源,这里的key可以自行定义,要切换数据库的时候以key为标识,不要写错- ->
<entry key= "One_dataSource"  value-ref= "One_dataSource "></entry>
<entry key= "Two_dataSource"  value-ref= "Two_dataSource "></ entry>
</map>
</property>
<--这里可以指定默认的数据源->
<property name= "defauttTargetDataSource" ref= "One_dataSource "></property>
</bean>

4.程序中如何调用所需要的数据库

在SSM框架中,我们在applicationContext.xml配置文件中添加数据源就可以实现数据库增删改查,但是只能连接一个数据库,这个时候我们就要从spring提供的源码下手看看有没有相关数据源切换的方法,找到关键源码 AbstractRoutingDataSource类,该类就相当于一个dataSource的调度者,用于根据key值来进行切换对应的dataSource。
AbstractRoutingDataSource类:

@Override
    public Connection getConnection() throws SQLException {
        return determineTargetDataSource().getConnection();
    }
 
    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return determineTargetDataSource().getConnection(username, password);
    }
 
    /**
     * Retrieve the current target DataSource. Determines the
     * {@link #determineCurrentLookupKey() current lookup key}, performs
     * a lookup in the {@link #setTargetDataSources targetDataSources} map,
     * falls back to the specified
     * {@link #setDefaultTargetDataSource default target DataSource} if necessary.
     * @see #determineCurrentLookupKey()
     */
    protected DataSource determineTargetDataSource() {
        Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");
        Object lookupKey = determineCurrentLookupKey();
        DataSource dataSource = this.resolvedDataSources.get(lookupKey);
        if (dataSource == null && (this.lenientFallback || lookupKey == null)) {
            dataSource = this.resolvedDefaultDataSource;
        }
        if (dataSource == null) {
            throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");
        }
        return dataSource;
    }
 
    /**
     * Determine the current lookup key. This will typically be
     * implemented to check a thread-bound transaction context.
     * <p>Allows for arbitrary keys. The returned key needs
     * to match the stored lookup key type, as resolved by the
     * {@link #resolveSpecifiedLookupKey} method.
     */
    protected abstract Object determineCurrentLookupKey();

可以看出方法getConnection()调用的 determineTargetDataSource则是关键方法,这个方法返回了具体使用的是哪个数据库;而 determineCurrentLookupKey( ) 方法来返回当前数据源的key值。
将返回的key值在resolvedDataSources这个map中找到对应的value(当前使用的数据源)。
源码:

@Override
    public void afterPropertiesSet() {
        if (this.targetDataSources == null) {
            throw new IllegalArgumentException("Property 'targetDataSources' is required");
        }
        this.resolvedDataSources = new HashMap<Object, DataSource>(this.targetDataSources.size());
        for (Map.Entry<Object, Object> entry : this.targetDataSources.entrySet()) {
            Object lookupKey = resolveSpecifiedLookupKey(entry.getKey());
            DataSource dataSource = resolveSpecifiedDataSource(entry.getValue());
            this.resolvedDataSources.put(lookupKey, dataSource);
        }
        if (this.defaultTargetDataSource != null) {
            this.resolvedDefaultDataSource = resolveSpecifiedDataSource(this.defaultTargetDataSource);
        }
    }

这个方法是通过targetDataSources对resolvedDataSources进行赋值的。targetDataSources我们可以用过配置文件进行配置,这样就可以设置当前使用哪个数据库了。

4.1新建DynamicDataSource类

我们先要重写上面的determineCurrentLookupKey方法,我们新建一个创建一个DynamicDataSource的类,用来获取自定义获取数据源的标识(和当前线程中使用的数据源):

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
 
public class DynamicDataSource extends AbstractRoutingDataSource {
 
    @Override
    protected Object determineCurrentLookupKey() {
        // 从自定义的位置获取数据源标识
        return DynamicDataSourceHolder.getDataSource();
    }
    
}

4.2 创建DynamicDataSourceHolder类

切换数据源


public class DynamicDataSourceHolder{

  private static final ThreadLocal<String> THREAD_DATA_SOURCE = new ThreadLocal();
  
  public static String getDataSource(){
  
    return (String)THREAD_DATA_SOURCE.get();
    
  }
  
  public static void setDataSource(String dataSource){
  
    THREAD_DATA_SOURCE.set(dataSource);
    
  }
  
  public static void clearDataSource(){
  
    THREAD_DATA_SOURCE.remove();
    
  }
  
}

以上,需要的配置完成。

4.3 调用

public void data() {

        JSONObject jsonObject = new JSONObject();
        List<Map<String ,Object>> list = testmapper.selectAllColor();
        jsonObject.put("AllColor",list);
        //切换数据源 
        DynamicDataSourceHolder.setDataSource( "Two_dataSource") ;
        testmapper.addAllColor();
    }

注意:因为配置了默认数据源,所以默认为第一个数据源,需要切换数据源的时候再进行切换。
建议:如果切换了数据源,需要在继续操作默认数据源的时候,建议切换回默认数据源。

本文参考 http://t.zoukankan.com/MagicAsa-p-11089329.html,感谢!

欢迎讨论,欢迎指正。

PS:第一篇文章,小激动哇~ 希望可以帮助到有需要的人~

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
SSM 项目中配置两个数据库连接的话,需要在 `src/main/resources` 目录下创建两个不同的配置文件,例如:`jdbc.properties` 和 `jdbc2.properties`。 在 `jdbc.properties` 文件中配置一个数据库连接信息,例如: ``` jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/db1 jdbc.username=root jdbc.password=123456 ``` 在 `jdbc2.properties` 文件中配置第二个数据库连接信息,例如: ``` jdbc2.driver=com.mysql.jdbc.Driver jdbc2.url=jdbc:mysql://localhost:3306/db2 jdbc2.username=root jdbc2.password=123456 ``` 然后在 Spring 的配置文件(如 applicationContext.xml)中,使用 `PropertyPlaceholderConfigurer` 读取这两个配置文件,并将其中的属性值注入到数据源中。 例如,在 applicationContext.xml 中添加以下配置: ```xml <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:jdbc.properties</value> <value>classpath:jdbc2.properties</value> </list> </property> </bean> ``` 接着,在配置数据源的 bean 中分别引用这两个配置文件中的属性值,例如: ```xml <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <bean id="dataSource2" class="org.apache.commons.dbcp2.BasicDataSource"> <property name="driverClassName" value="${jdbc2.driver}" /> <property name="url" value="${jdbc2.url}" /> <property name="username" value="${jdbc2.username}" /> <property name="password" value="${jdbc2.password}" /> </bean> ``` 这样就可以在 SSM 项目中配置两个数据库连接了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值