博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用Spring实现多数据源操作
阅读量:6992 次
发布时间:2019-06-27

本文共 3013 字,大约阅读时间需要 10 分钟。

Spring提供了抽象类AbstractRoutingDataSource,允许动态设置数据源,从而实现对多数据源进行数据读写操作。

 

1、首先需要定义一个类继承抽象类AbstractRoutingDataSource,并实现相应的方法determineCurrentLookupKey:

protected Object determineCurrentLookupKey() { }

决定使用哪个LookupKey作为目前的数据源key。

 

2、写一个辅助类,用于实现数据源的选择、切换,由于数据源是多线程共享的,需要确保线程安全,可以使用ThreadLocal来保存每个线程的数据源key。

public class DataSourceSelector{

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

  public static void setDataSource1() { dataSourceHolder.set(“dataSource1”);  }

  public static void setDataSource2() { dataSourceHolder.set(“dataSource1”);  }

}

3、在spring配置文件中配置多个数据源信息:

    <bean id="dataSource1">

        <property name="driverClass" value="" />

        <property name="jdbcUrl" value="" />

        <property name="user" value="" />

        <property name="password" value="" />

    </bean>

    <bean id="dataSource2">

        <property name="driverClass" value="" />

        <property name="jdbcUrl" value="" />

        <property name="user" value="" />

        <property name="password" value="" />

    </bean>

    <bean id="dataSource" class="com.xx.dao.DynamicDataSource">

        <property name="targetDataSources">

            <map key-type="java.lang.String">

                <entry key="dataSource1" value-ref="dataSource1" />

       <entry key="dataSource2" value-ref="dataSource2" />

            </map>

        </property>

        <property name="defaultTargetDataSource" ref="dataSource2" />

    </bean>

DynamicDataSource即为第一步中实现抽象类AbstractRoutingDataSource的具体选择数据源的类。

4、在需要切换数据源的时候,调用DataSourceSelector类的方法设置需要的数据源就可以了。

 

在此基础上,还可以结合spring AOP实现mysql等数据库的读写分离,为此需要定义一个类实现MethodBeforeAdvice,AfterReturningAdvice,ThrowsAdvice,如下:

public class DataSourceAdvice implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice {

  public void before(Method method, Object[] args, Object target) throws Throwable {

    // 方法执行之前,设置数据源    
    String methodName = method.getName();
      if (methodName.startsWith("get") || method.getName().startsWith("select")) 
          DataSourceSelector.setSlave();
      else
          DataSourceSelector.setMaster();    
  }

  public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable { }

  public void afterThrowing(Method method, Object[] args, Object target, Exception ex) throws Throwable {DataSourceSelector.setSlave();}

}

需要在Spring配置文件里增加通知的配置项:

<!-- 切换数据源拦截器,拦截com.xx.dao.impl下的所有类的所有方法 -->

<bean id="dataSourceAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
  <property name="advice">
    <bean class="com.xx.dao.dynamic.DataSourceAdvice"/>
  </property>
  <property name="patterns">
    <list>
      <value>.*</value>
    </list>
  </property>
</bean>

<!-- 所有以DaoImpl结尾的bean都拦截以自动选择数据库 -->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
  <property name="beanNames" value="*DaoImpl" />
  <property name="interceptorNames">
    <list>
      <value>dataSourceAdvisor</value>
    </list>
  </property>
</bean>

DaoImpl里的所有以get或者select开头的方法都会从slave数据库读取数据,而其他方法,例如以insert、update开头的方法都会往master数据库里存数据,从而实现读写分离。

转载于:https://www.cnblogs.com/7mile/archive/2013/05/27/3101362.html

你可能感兴趣的文章
machinekey生成工具 v1.0 官方最新版
查看>>
http server v0.1_mime.c
查看>>
open files
查看>>
MVC ——RouteTable.Routes的使用
查看>>
玩转X-CTR100 | STM32F4 l X-Assistant串口助手控制功能
查看>>
TCP/IP学习笔记1--概述,分组交换协议
查看>>
深入百度外链工具引发的思考
查看>>
DataBindings 与 INotifyPropertyChanged 实现自动刷新 WinForm 界面
查看>>
VB中数据占几个字节
查看>>
交通压力主动感知系统
查看>>
对于技术服务和业务的思考
查看>>
数据链路层
查看>>
Memcached 客户端使用
查看>>
【193】◀▶ PowerShell 官方资料索引
查看>>
linux 学习
查看>>
JDK安装和环境变量配置
查看>>
GO环境配置
查看>>
Android ocr识别文字介绍(文字识别)
查看>>
hdoj 2199 Can you solve this equation? 【二分枚举】
查看>>
2014互联网百强企业出炉 八爪鱼排名99
查看>>