欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

spring boot多数据源动态切换代码实例

程序员文章站 2022-05-20 17:45:52
这篇文章主要介绍了spring boot多数据源动态切换代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 当项目中存在多数据...

这篇文章主要介绍了spring boot多数据源动态切换代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

当项目中存在多数据源时,就涉及到数据源的动态切换,通过研究,特此记录一下。

1、maven依赖

<!--数据库连接-->
<dependency>
      <groupid>com.oracle</groupid>
      <artifactid>ojdbc6</artifactid>
      <version>11.2.0.4</version>
      <scope>runtime</scope>
    </dependency>
<!--数据库连接池->
<dependency>
      <groupid>com.alibaba</groupid>
      <artifactid>druid-spring-boot-starter</artifactid>
      <version>1.1.10</version>
    </dependency>
    <dependency>
      <groupid>org.springframework.boot</groupid>
      <artifactid>spring-boot-starter-jdbc</artifactid>
    </dependency>
<!--aop->
<dependency>
      <groupid>org.springframework.boot</groupid>
      <artifactid>spring-boot-starter-aop</artifactid>
    </dependency>

2、多数据源信息配置

#多数据源测试
spring:
 datasource:
  druid:
   master:
    driver-class-name: oracle.jdbc.driver.oracledriver
    username: test
    password: test
    url: jdbc:oracle:thin:@//ip1:1521/orcl
   slave:
    driver-class-name: oracle.jdbc.driver.oracledriver
    username: test
    password: test
    url: jdbc:oracle:thin:@//ip2:1521/orcl

3、数据源配置信息转换成实体类

@configurationproperties(prefix = "spring.datasource.druid")
@data
@component
public class datasourceproperties {
  private map<string,string>master;
  private map<string,string>slave;
}

4、动态数据源切换类

public class dynamicdatasource extends abstractroutingdatasource {

  private static final threadlocal<string> contextholder = new threadlocal<>();

  public dynamicdatasource(datasource defaulttargetdatasource, map<object, object> targetdatasources) {
    super.setdefaulttargetdatasource(defaulttargetdatasource);
    super.settargetdatasources(targetdatasources);
    super.afterpropertiesset();
  }


  @override
  protected object determinecurrentlookupkey() {
    return getdatasource();
  }

  public static void setdatasource(string datasource) {
    contextholder.set(datasource);
  }

  public static string getdatasource() {
    return contextholder.get();
  }

  public static void cleardatasource() {
    contextholder.remove();
  }
}

5、多数据源配置类

@configuration
public class dynamicdatasourceconfig {

  @bean
  public datasource master(@autowired datasourceproperties datasourceproperties){
    druiddatasource druiddatasource = new druiddatasource();
    map<string, string> master = datasourceproperties.getmaster();
    druiddatasource.setusername(master.get("username"));
    druiddatasource.setpassword(master.get("password"));
    druiddatasource.seturl(master.get("url"));
    //其他参数配置 省略
    return druiddatasource;
  }

  @bean
  public datasource slave(@autowired datasourceproperties datasourceproperties){
    druiddatasource druiddatasource = new druiddatasource();
    map<string, string> slave = datasourceproperties.getslave();
    druiddatasource.setusername(slave.get("username"));
    druiddatasource.setpassword(slave.get("password"));
    druiddatasource.seturl(slave.get("url"));
    //其他参数配置 省略
    return druiddatasource;
  }

  @bean
  @primary
  public dynamicdatasource datasource(datasource master,datasource slave){
    map<object,object>map = new hashmap<>(4);
    map.put("master",master);
    map.put("slave",slave);
    return new dynamicdatasource(master,map);
  }
}

6、自定义@datasource注解

@target(elementtype.method)
@retention(retentionpolicy.runtime)
public @interface datasource {

  string name() default "master";
}

7、aop切面类配置

@component
@aspect
public class datasourceaspect {

  @pointcut("@annotation(com.zxgeo.sso.muiltdatasource.anons.datasource)")
  public void datasourcepointcut(){}

  @around(value = "datasourcepointcut()")
  public object around(proceedingjoinpoint point) throws throwable {
    methodsignature signature = (methodsignature) point.getsignature();
    method method = signature.getmethod();

    datasource datasource = method.getannotation(datasource.class);
    if(datasource == null){
      dynamicdatasource.setdatasource("master");
    }else {
      dynamicdatasource.setdatasource(datasource.name());
    }
    try {
      return point.proceed();
    } finally {
      dynamicdatasource.cleardatasource();
    }
  }
}

8、启动配置注解信息,重要(不然运行会报错)

@springbootapplication(exclude= {datasourceautoconfiguration.class})

9、测试

(1)、service层(此处没有使用mybatis)

@service
public class testservice {

  @autowired
  private javax.sql.datasource datasource;

  @datasource
  public map<string,object> getmasterdatasource() throws sqlexception {
    connection connection = datasource.getconnection();
    map<string,object> map;
    try (preparedstatement preparedstatement
           = connection.preparestatement("select * from aa where a=10001")) {
      resultset resultset = preparedstatement.executequery();
      map = new hashmap<>();
      while (resultset.next()){
        map.put("a",resultset.getstring("a"));
        map.put("b",resultset.getstring("b"));
        map.put("c",resultset.getstring("c"));
      }
    }
    return map;
  }
  @datasource(name = "slave")
  public map<string,object> getslavedatasource() throws sqlexception {
    connection connection = datasource.getconnection();
    map<string,object> map;
    try (preparedstatement preparedstatement
           = connection.preparestatement("select * from aa where a=10002")) {
      resultset resultset = preparedstatement.executequery();
      map = new hashmap<>();
      while (resultset.next()){
        map.put("a",resultset.getstring("a"));
        map.put("b",resultset.getstring("b"));
        map.put("c",resultset.getstring("c"));
      }
    }
    return map;
  }
}

(2)、单元测试

@springboottest
@runwith(springrunner.class)
class ssoapplicationtests {

  @autowired
  private testservice testservice;

  @test
  public void mulidatasorce() throws sqlexception {
    map<string, object> masterdatasourceurl = testservice.getmasterdatasource();
    system.out.println(masterdatasourceurl);
    map<string, object> slavedatasourceurl = testservice.getslavedatasource();
    system.out.println(slavedatasourceurl);
  }
}

(3)、结果:

spring boot多数据源动态切换代码实例

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。