引用两个或多个数据库里的数据,项目数据库的配置方法

1、首先配置两个数据源(数据库)以及一个动态数据库:

<!-- 数据源1 spring自带的 -->
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <!-- 这里的driverClassName指的是数据库驱动这里要根据使用的数据库进行更改这里使用的SQLServer数据库 -->
        <property name="driverClassName"
            value="com.microsoft.sqlserver.jdbc.SQLServerDriver"></property>
        <!-- 这里url主要说明的数据库的位置和调用那个数据库其中jdbc后面是位置而DatebaseName所说的是数据库的名称 -->
        <property name="url"
            value="jdbc:sqlserver://数据库ip地址:端口号;DatabaseName=数据库1名称;?useUnicode=true&amp;characterEncoding=UTF-8" />
        <!-- 下面的2行username和password主要是说明的登录的用户名和密码这里根据项目的不同进行修改 -->
        <property name="username" value="数据库连接账号"></property>
        <property name="password" value="数据库连接密码"></property>
    </bean>

    <!-- 数据源2-->
    <bean id="dataSource2"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <!-- 这里的driverClassName指的是数据库驱动这里要根据使用的数据库进行更改这里使用的SQLServer数据库 -->
        <property name="driverClassName"
            value="com.microsoft.sqlserver.jdbc.SQLServerDriver"></property>
        <!-- 这里url主要说明的数据库的位置和调用那个数据库其中jdbc后面是位置而DatebaseName所说的是数据库的名称 -->
        <property name="url"
            value="jdbc:sqlserver://数据库ip地址:端口号;DatabaseName=数据库2名称;?useUnicode=true&amp;characterEncoding=UTF-8" />
        <!-- 下面的2行username和password主要是说明的登录的用户名和密码这里根据项目的不同进行修改 -->
        <property name="username" value="数据库连接账号"></property>
        <property name="password" value="数据库连接密码"></property>
    </bean>
    
    <!--配置动态数据库-->
    <bean id="dynamicDataSource" class="com.datasource.DynamicDataSource" >
        <property name="targetDataSources">
            <map key-type="java.lang.String">
                <entry value-ref="dataSource" key="dataSource"></entry>
                <entry value-ref="dataSource2" key="dataSource2"></entry>
            </map>
        </property>
        <property name="defaultTargetDataSource" ref="dataSource" >
        </property>
    </bean>

2、sqlSessionFactory引用的数据库是动态数据库dynamicDataSource:

<!-- 扫描mybatis的配置结合上面的DataSource,会生成一个sqlFactory。这里一般来说不用改 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dynamicDataSource" />
        <!-- 将mybatis的配置文件引入 -->
        <property name="configLocation" value="classpath:myBatisConfig.xml"></property>
    </bean>

4、事务管理这里要管理的也是上面配置的dynamicDataSource动态数据库:

<!-- 配置了事务的管理。一般来说不用改 -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dynamicDataSource"></property>
    </bean>

5、写两个数据源配置类DataSourceContextHolder.java和DynamicDataSource.java来配置数据源,利用ThreadLocal解决线程安全问题。

DataSourceContextHolder 类:

package com.datasource;

public class DataSourceContextHolder {
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
    public static void setCustomerType(String customerType) {
        contextHolder.set(customerType);
    }
    public static String getCustomerType() {
        return contextHolder.get();
    }
    public static void clearCustomerType() {
        contextHolder.remove();
    }
}

DynamicDataSource 类继承 AbstractRoutingDataSource,并实现determineCurrentLookupKey方法:

package com.datasource;

import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class DynamicDataSource extends AbstractRoutingDataSource {

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        // TODO 自动生成的方法存根
        return null;
    }

    @Override
    protected Object determineCurrentLookupKey() {
        // TODO 自动生成的方法存根
        return DataSourceContextHolder.getCustomerType();
    }

}

6、最后就可以在需要切换数据库的地方使用以下方法来切换数据库了,要切换的数据库名字即之前在配置动态数据库时给引用的数据库赋的名字:

DataSourceContextHolder.setCustomerType("要切换的数据库名字");

7、下面附上我的目录结构:

引用两个或多个数据库里的数据,项目数据库的配置方法


注:每次使用完切换数据库的方法后,系统会自动切换回默认数据库,不过这之间存在一点小延迟,会出现在调用完切换数据库的方法后,立刻去跳转到引用另外一个数据库数据的页面,系统还是使用着切换后的数据库。

解决办法:可以在使用完切换数据库的方法拿到需要的数据后,再次调用 DataSourceContextHolder.setCustomerType() 方法切换回接下来需要用到的数据库。

相关推荐