动态切换数据源AbstractRoutingDataSource

数据源的配置:datasource.xml默认的是datasource1,

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN"
 "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-lazy-init="false">

    <bean id="dataSource1"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>
        <property name="url"><value>jdbc:ORACLE:thin:@10.243.194.74:1521:trustel</value></property> 
        <property name="username"><value>GMCCWX</value></property>
        <property name="password"><value>trustel</value></property>
    </bean>

    <bean id="dataSource2" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
            <value>oracle.jdbc.driver.OracleDriver</value>
        </property>
        <property name="url">
            <value>jdbc:oracle:thin:@10.243.173.236:1521:orcl</value>
        </property>
        <property name="username">
            <value>gd12580wm</value>
        </property>
        <property name="password">
            <value>gd12580wm</value>
        </property>
    </bean>

    <bean id="defaultDataSource" class="com.cdc.sys.util.DynamicDataSource">
        <property name="targetDataSources">
            <map>
                <entry key="0" value-ref="dataSource1" />
                <entry key="1" value-ref="dataSource2" />
            </map>
        </property>
        <property name="defaultTargetDataSource" ref="dataSource1" />
    </bean>


</beans>

数据源切换类:DynamicDataSource.java

package com.cdc.sys.util;

import java.sql.SQLException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class DynamicDataSource extends AbstractRoutingDataSource{

    private static Logger log = LoggerFactory.getLogger(DynamicDataSource.class);
    
    @Override
    protected Object determineCurrentLookupKey() {
        return DbContextHolder.getDbType();
    }
    
    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }
    
    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

}

操作当前线程的局部变量DbContextHolder.java

package com.cdc.sys.util;

public class DbContextHolder {

    private static final ThreadLocal contextHolder = new ThreadLocal();
    
    public static void setDbType(String dbType){
        contextHolder.set(dbType);
    }
    
    public static String getDbType(){
        return (String)contextHolder.get();
    }
    
    public static void clearDbType(){
        contextHolder.remove();
    }
}

在需要切换时调用DbContextHolder.serDbType(String dbType)即可

=======================================分割线============================================

实体类:

Book.java

package com.trustel.entity;

import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table
public class Book {
    private String id;
    private String name;
    private double price;
    private String author;
    private Date pubishDate;
    
    @Id
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public Date getPubishDate() {
        return pubishDate;
    }
    public void setPubishDate(Date pubishDate) {
        this.pubishDate = pubishDate;
    }
    
    
}

dao层:

package com.trustel.dao;

import javax.transaction.Transactional;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.trustel.entity.Book;

@Repository
public class BookDao {
    @Autowired
    private SessionFactory sessionFactory;
    
    @Transactional
    public void saveBook(Book book){
        Session session = sessionFactory.getCurrentSession();
        session.save(book);
    }
    
}

配置文件:datasource.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"  
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
    xmlns:cache="http://www.springframework.org/schema/cache"  
    xsi:schemaLocation="  
    http://www.springframework.org/schema/context  
    http://www.springframework.org/schema/context/spring-context.xsd  
    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/jdbc  
    http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd  
    http://www.springframework.org/schema/cache  
    http://www.springframework.org/schema/cache/spring-cache-3.1.xsd  
    http://www.springframework.org/schema/aop  
    http://www.springframework.org/schema/aop/spring-aop.xsd  
    http://www.springframework.org/schema/util  
    http://www.springframework.org/schema/util/spring-util.xsd">

 <!-- 自动扫描 -->
    <context:component-scan base-package="com.trustel.dao"></context:component-scan>
    
    <bean id="dataSource1"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>
        <property name="url"><value>jdbc:ORACLE:thin:@10.244.159.97:1523:ORCLBXW</value></property> 
        <property name="username"><value>bxw</value></property>
        <property name="password"><value>root</value></property>
    </bean>

    <bean id="dataSource2" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
            <value>oracle.jdbc.driver.OracleDriver</value>
        </property>
        <property name="url">
            <value>jdbc:oracle:thin:@10.244.159.83:1521:ORCL</value>
        </property>
        <property name="username">
            <value>scmp</value>
        </property>
        <property name="password">
            <value>trustel</value>
        </property>
    </bean>

    <bean id="defaultDataSource" class="com.trustel.util.DynamicDataSource">
        <property name="targetDataSources">
            <map>
                <entry key="0" value-ref="dataSource1" />
                <entry key="1" value-ref="dataSource2" />
            </map>
        </property>
        <property name="defaultTargetDataSource" ref="dataSource1" />
    </bean>
    
    <bean id="sessionFactory" 
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="defaultDataSource"></property>
        <property name="packagesToScan" value="com.trustel.entity" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">
                    org.hibernate.dialect.Oracle10gDialect
                </prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>
    
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref bean="sessionFactory" />
        </property>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>

</beans>

test.java

package com.trustel;

import java.util.Date;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.trustel.dao.BookDao;
import com.trustel.entity.Book;
import com.trustel.util.DbContextHolder;

public class Test {
    
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("datasource.xml");
        DbContextHolder.setDbType("1");
        BookDao bookDao = (BookDao) ac.getBean("bookDao");
        Book book = new Book();
        book.setId("1");
        book.setName("123");
        book.setPrice(10);
        book.setAuthor("hahah");
        book.setPubishDate(new Date());
        bookDao.saveBook(book);
    }
}

通过DbContextHolder.setDbType("1")改变数据源。

原文地址:https://www.cnblogs.com/popcornya/p/7646421.html