springMVC 多数据源配置切换

未分类 发表评论


为了更方便的切换开发环境或读写分离操作,在应用中需要配置多个数据源,根据环境动态的切换数据库配置地址。

配置jdbc.properties文件

这里用到了三个文件:
jdbc_dev.properties
jdbc_product.properties
jdbc_test.properties
分别对就开发环境、生产环境、测试环境的数据库链接信息。
大体内容如下:

  #开发环境环境标记dev/product/test
  #本地开始环境数据库链接地址
  dev_driver=com.mysql.cj.jdbc.Driver
  dev_url=jdbc:mysql://127.0.0.1:3306/learn?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
  dev_jdbc.username=root
  dev_jdbc.password=111111
  #初始化连接大小
  dev_initialSize=0
  #连接池最大数量
  dev_maxActive=20
  #连接池最大空闲
  dev_maxIdle=20
  #连接池最小空闲
  dev_minIdle=1
  #获取连接最大等待时间
  dev_maxWait=60000

applicationContext.xml文件配置

首先将所有数据源配置文件引入

 <context:property-placeholder location="classpath:jdbc/jdbc_product.properties,classpath:jdbc/jdbc_test.properties,classpath:jdbc/jdbc_dev.properties" />

然后对应到多个dataSource中去,代码如下:

    <!-- 开发环境数据源配置 -->
    <bean id="dataSourceDev" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${dev_driver}" />
    <property name="url" value="${dev_url}" />
    <property name="username" value="${dev_jdbc.username}" />
    <property name="password" value="${dev_jdbc.password}" />
    <!-- 初始化连接大小 -->
    <property name="initialSize" value="${dev_initialSize}"></property>
    <!-- 连接池最大数量 -->
    <property name="maxTotal" value="${dev_maxActive}"></property>
    <!-- 连接池最大空闲 -->
    <property name="maxIdle" value="${dev_maxIdle}"></property>
    <!-- 连接池最小空闲 -->
    <property name="minIdle" value="${dev_minIdle}"></property>
    <!-- 获取连接最大等待时间 -->
    <property name="maxWaitMillis" value="${dev_maxWait}"></property>
  </bean>

    <!-- 正式环境数据源配置 -->
  <bean id="dataSourceProduct" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${product_driver}" />
    <property name="url" value="${product_url}" />
    <property name="username" value="${product_jdbc.username}" />
    <property name="password" value="${product_jdbc.password}" />
    <property name="initialSize" value="${product_initialSize}"></property>
    <property name="maxTotal" value="${product_maxActive}"></property>
    <property name="maxIdle" value="${product_maxIdle}"></property>
    <property name="minIdle" value="${product_minIdle}"></property>
    <property name="maxWaitMillis" value="${product_maxWait}"></property>
  </bean>

    <!-- 测试环境数据源配置 -->
  <bean id="dataSourceTest" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${test_driver}" />
    <property name="url" value="${test_url}" />
    <property name="username" value="${test_jdbc.username}" />
    <property name="password" value="${test_jdbc.password}" />
    <property name="initialSize" value="${test_initialSize}"></property>
    <property name="maxTotal" value="${test_maxActive}"></property>
    <property name="maxIdle" value="${test_maxIdle}"></property>
    <property name="minIdle" value="${test_minIdle}"></property>
    <property name="maxWaitMillis" value="${test_maxWait}"></property>
  </bean>
  <!-- 多数据源配置信息
       这里引入的MultipleDataSource类为自定义类
  -->
  <bean id="multipleDataSource" class="com.springmvc.common.config.datasource.MultipleDataSource">
    <property name="defaultTargetDataSource" ref="dataSourceDev" />
    <property name="targetDataSources">
      <map>
        <entry key="dataSourceDev" value-ref="dataSourceDev" />
        <entry key="dataSourceProduct" value-ref="dataSourceProduct" />
        <entry key="dataSourceTest" value-ref="dataSourceTest" />
      </map>
    </property>
  </bean>

  <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="multipleDataSource" />
    <!-- 自动扫描mapping.xml文件 -->
    <property name="mapperLocations" value="classpath:mappings/**/*.xml"></property>
    <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"></property>
  </bean> 

定义MultipleDataSource类

在类中需要继承AbstractRoutingDataSource类,重写determineCurrentLookupKey方法,代码如下:

  public class MultipleDataSource extends AbstractRoutingDataSource {

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

    public static void setDataSourceKey(String dataSource){
      dataSourceKey.set(dataSource);
    }

    @Override
    protected Object determineCurrentLookupKey() {    
      return dataSourceKey.get();
    }
  }

在Service动态切换数据源地址

代码如下:

    @Service
    public class CourseService {

      @Autowired
      protected CourseDao courseDao;

      /**
       * 查询列表数据
       * 
       * @param entity
       * @return
       */
      public List<Course> findList(Course entity) {
        //动态切换数据源地址    MultipleDataSource.setDataSourceKey("dataSourceTest");
        return courseDao.findList();
      } 
  }     

发表评论

电子邮件地址不会被公开。 必填项已用*标注

昵称 *