Spring+SpringMVC+Mybatis 实现多数据源切换

Spring+SpringMVC+Mybatis 多数据源整合


1、本文采用spring-4.2.3 + springmvc +mybatis-3.3.0 来实现多数据源整合

拷贝对应的jar文件

2.写一个数据库切换的工具类:DataSourceContextHolder,用来切换数据库

public class DataSourceContextHolder {

    public static final String DATA_SOURCE_DEFAULT = "defaultDataSource";
    public static final String DATA_SOURCE_NEW = "newDataSource";

    private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();

    public static void setDbType(String dbType) {
        contextHolder.set(dbType);
    }

    public static String getDbType() {
        return contextHolder.get();
    }

}
3、写一个DynamicDataSource(类名随意) 继承 AbstractRoutingDataSource 并重写 determineCurrentLookupKey()方法来实现动态数据源切换
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class DynamicDataSource extends AbstractRoutingDataSource{

    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDbType();
    }

}

4、修改database.properties如下

default.jdbc.driver = com.mysql.jdbc.Driver
default.jdbc.url = jdbc:mysql://localhost:3306/temp?characterEncoding=UTF-8
default.jdbc.username = root
default.jdbc.password = root

newA.jdbc.driver = com.mysql.jdbc.Driver
newA.jdbc.url = jdbc:mysql://localhost:3306/tempb?characterEncoding=UTF-8
newA.jdbc.username = root
newA.jdbc.password = root

5、创建applicationContext-dao.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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">


    <!--获取数据库配置文件-->
    <context:property-placeholder location="classpath:config/database.properties"/>

    <!--设置数据源c3p0-->
    <bean id="defaultDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="driverClass" value="${default.jdbc.driver}"/>
        <property name="jdbcUrl" value="${default.jdbc.url}"/>
        <property name="user" value="${default.jdbc.username}"/>
        <property name="password" value="${default.jdbc.password}"/>
        <property name="maxPoolSize" value="50"/>
        <property name="minPoolSize" value="2"/>
        <property name="maxIdleTime" value="60"/>
    </bean>

    <bean id="newDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="driverClass" value="${newA.jdbc.driver}"/>
        <property name="jdbcUrl" value="${newA.jdbc.url}"/>
        <property name="user" value="${newA.jdbc.username}"/>
        <property name="password" value="${default.jdbc.password}"/>
        <property name="maxPoolSize" value="50"/>
        <property name="minPoolSize" value="2"/>
        <property name="maxIdleTime" value="60"/>
    </bean>

    <!-- 动态配置数据源 -->
    <bean id="dynamicDataSource" class="com.ssm.config.DynamicDataSource">
        <property name="targetDataSources">
            <map key-type="java.lang.String">
                <entry value-ref="defaultDataSource" key="defaultDataSource" />
                <entry value-ref="newDataSource" key="newDataSource" />
            </map>
        </property>
        <!-- 默认使用defaultDataSource的数据源 -->
        <property name="defaultTargetDataSource" ref="defaultDataSource" />
    </bean>

    <!--sqlsessionFactory bean,配置session工厂 -->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 定义数据源,数据源使用动态的数据源dynamicDataSource -->
        <property name="dataSource" ref="dynamicDataSource" />
        <property name="configLocation" value="classpath:config/mybatis/MybatisConfig.xml"/>
    </bean>


    <!--自动扫描mapper接口,并注入sqlsession-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 自动扫描mapping.xml文件 -->
        <property name="basePackage" value="com.ssm.mapper"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSession"/>
    </bean>

</beans>
6、创建applicationContext-transaction.xml 配置AOP以及事物、事物的传播性
<?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.xsd 
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx.xsd 
       http://www.springframework.org/schema/aop 
       http://www.springframework.org/schema/aop/spring-aop.xsd">


    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dynamicDataSource"/>
    </bean>

    <tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager">
        <tx:attributes>
            <tx:method name="find*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="delete*" propagation="REQUIRED"/>
            <tx:method name="add*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

    <!-- 把事务边界定在service层 -->
    <aop:config>
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.ssm.service.serviceImpl.*.*(..))"/>
    </aop:config>
</beans>
7、在tempb数据库创建一个测试表(TempUser),用generatorConfig生成对应的entity类和映射文件。
public class TempUser {
    private Integer id;

    private String name;

    private Integer age;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name == null ? null : name.trim();
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
    
    @Override
    public String toString() {
        return "TempUser{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

8、在 Controller 里编写对应的方法 . 注意:每次访问数据库时必须切换到对应的数据库,这里的名字(DATA_SOURCE_DEFAULT = "defaultDataSource")一定要和applicationContext-dao.xml里面配置的数据源的名称一样

 @RequestMapping(value = "/test")
    public Map<String, Object> example() {
        //切换数据库(temp) temp数据库是默认数据库,第一次访问可以不用切换
        DataSourceContextHolder.setDbType(DataSourceContextHolder.DATA_SOURCE_DEFAULT);
        User user = userService.selectByUserName("user");
        System.out.println(user);

        //切换数据库(tempb)
        DataSourceContextHolder.setDbType(DataSourceContextHolder.DATA_SOURCE_NEW);
        TempUser t = tempUserServcie.selectByPrimaryKey(1);
        
        return null;
    }

开启服务访问 localhost:8080/test 就可以访问了



猜你喜欢

转载自blog.csdn.net/javareact/article/details/80400663