多数据源的配置

   大型应用为了实现读写分离,便于数据的管理,提高系统的水平伸缩性,往往会用到多数据源。

1,数据源是对应不同数据库的,为了方便操作可以写一个数据库的配置文件

UPDATE_MYSQL.type= mysql
UPDATE_MYSQL.autoCommitOnClose= false
UPDATE_MYSQL.driverClassName= com.mysql.jdbc.Driver
UPDATE_MYSQL.url= jdbc:mysql://192.168.1.139:3306/testdatabase?useUnicode=true&characterEncoding=UTF-8&useOldAliasMetadataBehavior=true
UPDATE_MYSQL.username= xccmysql
UPDATE_MYSQL.password= xccW7W8
UPDATE_MYSQL.initialPoolSize= 5


SELECT_MYSQL.type= mysql
SELECT_MYSQL.autoCommitOnClose= false
SELECT_MYSQL.driverClassName= com.mysql.jdbc.Driver
SELECT_MYSQL.url= jdbc:mysql://192.168.1.139:3306/testmuti?useUnicode=true&characterEncoding=UTF-8&useOldAliasMetadataBehavior=true
SELECT_MYSQL.username= root
SELECT_MYSQL.password= xcc2009081231
SELECT_MYSQL.initialPoolSize= 5

2,然后再spring的配置文件里添加不同的数据源

<!-- 数据源的配置 -->
      < bean id = "update_dataSource" class = "org.apache.commons.dbcp.BasicDataSource" destroy-method = "close" >
           < property name = "driverClassName" value = "${UPDATE_MYSQL.driverClassName}" />
           < property name = "url" value = "${UPDATE_MYSQL.url}" />
           < property name = "username" value = "${UPDATE_MYSQL.username}" />
           < property name = "password" value = "${UPDATE_MYSQL.password}" />
           <!-- data source configuration -->
           < property name = "initialSize" value = "${UPDATE_MYSQL.initialPoolSize}" /> <!-- initial connections -->
           < property name = "maxActive" value = "10" /> <!-- MAX connections -->
           < property name = "maxIdle" value = "10" /> <!-- MAX idle connections -->
           < property name = "minIdle" value = "5" /> <!-- MIN idle connections -->
           <!-- 处理mysql 8小时自动断开连接的问题 -->
           < property name = "testWhileIdle" value = "true" />
           < property name = "testOnBorrow" value = "false" />
           < property name = "testOnReturn" value = "false" />
           < property name = "validationQuery" value = "select 1" />
           < property name = "timeBetweenEvictionRunsMillis" value = "20000" />
           < property name = "numTestsPerEvictionRun" value = "100" />
      </ bean >
     
     
      < bean id = "select_dataSource" class = "org.apache.commons.dbcp.BasicDataSource" destroy-method = "close" >
           < property name = "driverClassName" value = "${UPDATE_MYSQL.driverClassName}" />
           < property name = "url" value = "${SELECT_MYSQL.url}" />
           < property name = "username" value = "${SELECT_MYSQL.username}" />
           < property name = "password" value = "${SELECT_MYSQL.password}" />
           <!-- data source configuration -->
           < property name = "initialSize" value = "${SELECT_MYSQL.initialPoolSize}" /> <!-- initial connections -->
           < property name = "maxActive" value = "10" /> <!-- MAX connections -->
           < property name = "maxIdle" value = "10" /> <!-- MAX idle connections -->
           < property name = "minIdle" value = "5" /> <!-- MIN idle connections -->
           <!-- 处理mysql 8小时自动断开连接的问题 -->
           < property name = "testWhileIdle" value = "true" />
           < property name = "testOnBorrow" value = "false" />
           < property name = "testOnReturn" value = "false" />
           < property name = "validationQuery" value = "select 1" />
           < property name = "timeBetweenEvictionRunsMillis" value = "20000" />
           < property name = "numTestsPerEvictionRun" value = "100" />
      </ bean >

3,数据源准备好之后,基本工作,已完成,先放在一边,我们去java里面写数据源的名称常量类

package org.iwall.muti.datasource;
/**
 *
 * @author Lee
 *
 */
public class DataSourceNames {
      public static final String UPDATE_MYSQL = "update_dataSource" ;
      public static final String SELECT_MYSQL = "select_dataSource" ;
}

4,建立一个类,负责改变数据源的名称(其实可使用spring的注解切换不同的数据源)

package org.iwall.muti.datasource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
 *  获得和设置上下文环境 主要负责改变上下文数据源的名称
 * @author Lee
 *
 */
public class DataSourceContextHolder {
    private static final ThreadLocal contextHandler = new ThreadLocal(); // 线程本地环境
    public static Log log = LogFactory.getLog(DataSourceContextHolder.class);
    // 设置数据源类型
    public static void setDataSourceType(String dataSourceType) {
        log.info("set dataSource:" + dataSourceType);
        contextHandler.set(dataSourceType);
    }

    // 获取数据源类型   
    public static String getDataSourceType() {
        return (String) contextHandler.get();
    }

    // 清除数据源类型
    public static void clearDataSourceType() {
        contextHandler.remove();
    }
}



5,建立动态数据源,主要实现 determineCurrentLookupKey这个方法

package org.iwall.muti.datasource;

import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.jdbc.datasource.lookup.DataSourceLookup;
/**
 *
 * @author Lee
 *
 */
public class DynamicDataSource extends AbstractRoutingDataSource implements InitializingBean {
    private Log log = LogFactory.getLog(DynamicDataSource.class);

    /* 
     * 该方法必须要重写  方法是为了根据数据库标示符取得当前的数据库 既是获得数据源类型
     */ 
    @Override 
    public Object determineCurrentLookupKey() { 
        log.info("starting determineCurrentLookupKey:" + DataSourceContextHolder.getDataSourceType());
        return DataSourceContextHolder.getDataSourceType();
    } 

    @Override 
    public void setDataSourceLookup(DataSourceLookup dataSourceLookup) { 
        log.info("starting setDataSourceLookup:" + DataSourceContextHolder.getDataSourceType());
        super.setDataSourceLookup(dataSourceLookup); 
    } 

    @Override 
    public void setDefaultTargetDataSource(Object defaultTargetDataSource) {
        log.info("starting setDefaultTargetDataSource:" + DataSourceContextHolder.getDataSourceType());
        super.setDefaultTargetDataSource(defaultTargetDataSource); 
    } 

    @Override 
    public void setTargetDataSources(Map targetDataSources) {
        System.out.println("starting setTargetDataSources:" + DataSourceContextHolder.getDataSourceType());
        super.setTargetDataSources(targetDataSources); 
        //重点 
        super.afterPropertiesSet(); 
    }

}



6,数据源配置完了,java对应的类也写完了,就需要写映射关系了,其中key是对应java类里的数据源常量名,value是配置文件里的数据源名

< bean id = "dynamicDataSource" class = "org.iwall.muti.datasource.DynamicDataSource" >
           <!-- 通过key-value的形式来关联数据源 -->
           < property name = "targetDataSources" >
               < map key-type = "java.lang.String" >
                    < entry key = "update_dataSource" value-ref = "update_dataSource" ></ entry >
                    < entry key = "select_dataSource" value-ref = "select_dataSource" ></ entry >
               </ map >
           </ property >
           < property name = "defaultTargetDataSource" ref = "update_dataSource" >
           </ property >
  </ bean >

7,如果没有使用hibernate,mybatis等数据交互的框架,用spring的模板jdbc的话,注入一下就好

< bean id = "jdbcTemplate" class = "org.springframework.jdbc.core.JdbcTemplate" >
           < constructor-arg ref = "dynamicDataSource" />
  </ bean >

8,总结下,这种方式,便于维护,基本只用修改数据库配置文件和spring配置文件即可。但是多个用户访问会争抢datasource,系统性能
会降低,(没测试过)。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值