在开发中因需求在项目中需要实现多数据源(虽然项目框架是SpringCloud,但是因其中只是单独的查询操作,觉得没必要开发一个项目,所以采用多数据源来进行实现)

1.在配置文件中创建多个数据连接配置

spring.datasource.primary.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.primary.url=jdbc:mysql://127.0.0.1:3306/test1?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false&autoReconnect=true&failOverReadOnly=false
spring.datasource.primary.username=root
spring.datasource.primary.password=root
spring.datasource.primary.driverClassName = com.mysql.jdbc.Driver
spring.datasource.primary.max-wait=10000
spring.datasource.primary.max-idle=8
spring.datasource.primary.min-idle=8
spring.datasource.primary.initial-size=10
spring.datasource.primary.max-active=20
spring.datasource.primary.test-on-borrow=true
spring.datasource.primary.test-while-idle=true
spring.datasource.primary.validation-query=SELECT 1 FROM DUAL
spring.datasource.primary.time-between-eviction-runs-millis=300000
spring.datasource.primary.min-evictable-idle-time-millis=1800000 spring.datasource.second.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.second.url=jdbc:mysql://127.0.0.1:3306/test2?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false&autoReconnect=true&failOverReadOnly=false
spring.datasource.second.username=root
spring.datasource.second.password=root
spring.datasource.second.driverClassName = com.mysql.jdbc.Driver
spring.datasource.second.max-wait=10000
spring.datasource.second.max-idle=8
spring.datasource.second.min-idle=8
spring.datasource.second.initial-size=10
spring.datasource.second.max-active=20
spring.datasource.second.test-on-borrow=true
spring.datasource.second.test-while-idle=true
spring.datasource.second.validation-query=SELECT 1 FROM DUAL
spring.datasource.second.time-between-eviction-runs-millis=300000
spring.datasource.second.min-evictable-idle-time-millis=1800000

2.配置完成后需要创建数据源的连接工厂

 2.1第一个数据源连接配置

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver; @Configuration
//配置mybatis的接口类放的地方
@MapperScan(basePackages = "com.cloud.demo.dao.primary", sqlSessionFactoryRef = "primarySqlSessionFactory")
public class DataSourceFirstConfig {
// 将这个对象放入Spring容器中
@Bean(name = "primaryDataSource")
// 表示这个数据源是默认数据源
@Primary
// 读取application.properties中的配置参数映射成为一个对象
// prefix表示参数的前缀
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource getDateSource1() {
return DataSourceBuilder.create().build();
}
@Bean(name = "primarySqlSessionFactory")
// 表示这个数据源是默认数据源
@Primary
// @Qualifier表示查找Spring容器中名字为test1DataSource的对象
public SqlSessionFactory test1SqlSessionFactory(@Qualifier("primaryDataSource") DataSource datasource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(datasource);
bean.setMapperLocations(
// 设置mybatis的xml所在位置
new PathMatchingResourcePatternResolver().getResources("classpath*:com/cloud/demo/mapping/primary/*.xml"));
return bean.getObject();
}
@Bean("primarySqlSessionTemplate")
// 表示这个数据源是默认数据源
@Primary
public SqlSessionTemplate test1sqlsessiontemplate(
@Qualifier("primarySqlSessionFactory") SqlSessionFactory sessionfactory) {
return new SqlSessionTemplate(sessionfactory);
}
}

  2.2第二个数据源配连接配置

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver; @Configuration
@MapperScan(basePackages = "com.cloud.demo.dao.second", sqlSessionFactoryRef = "secondSqlSessionFactory")
public class DataSourceSecondConfig {
@Bean(name = "secondDataSource")
@ConfigurationProperties(prefix = "spring.datasource.second")
public DataSource getDateSource2() {
return DataSourceBuilder.create().build();
}
@Bean(name = "secondSqlSessionFactory")
public SqlSessionFactory test2SqlSessionFactory(@Qualifier("secondDataSource") DataSource datasource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(datasource);
bean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath*:com/cloud/demo/mapping/second/*.xml"));
return bean.getObject();
}
@Bean("secondSqlSessionTemplate")
public SqlSessionTemplate test2sqlsessiontemplate(
@Qualifier("secondSqlSessionFactory") SqlSessionFactory sessionfactory) {
return new SqlSessionTemplate(sessionfactory);
}
}

PS: @Primary注解一定要配置,否则不知道哪个是默认数据源配置

3.保存切换数据源

public class DataSourceContextHolder {

    //默认数据源
public static final String DEFAULT_DS = "primaryDataSource"; private static final ThreadLocal<String> contextHolder = new ThreadLocal<>(); // 设置数据源名
public static void setDB(String dbType) {
System.out.println("切换到{"+dbType+"}数据源");
contextHolder.set(dbType);
} // 获取数据源名
public static String getDB() {
return (contextHolder.get());
} // 清除数据源名
public static void clearDB() {
contextHolder.remove();
}
}

4.当前数据源

public class DynamicDataSource extends AbstractRoutingDataSource {

    @Override
protected Object determineCurrentLookupKey() {
System.out.println("数据源为"+DataSourceContextHolder.getDB());
return DataSourceContextHolder.getDB();
} }

5.创建自定义注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface DataSource {
String value() default "primaryDataSource";
}

6.使用AOP创建切点

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component; @Aspect
@Component
public class DynamicDataSourceAspect {
@Before("@annotation(DataSource)")
public void beforeSwitchDS(JoinPoint point){
//获得当前访问的class
Class<?> className = point.getTarget().getClass();
//获得访问的方法名
String methodName = point.getSignature().getName();
//得到方法的参数的类型
Class[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();
String dataSource = DataSourceContextHolder.DEFAULT_DS;
try {
// 得到访问的方法对象
Method method = className.getMethod(methodName, argClass);
// 判断是否存在@DS注解
if (method.isAnnotationPresent(DataSource.class)) {
DataSource annotation = method.getAnnotation(DataSource.class);
// 取出注解中的数据源名
dataSource = annotation.value();
}
} catch (Exception e) {
e.printStackTrace();
}
// 切换数据源
DataSourceContextHolder.setDB(dataSource);
} @After("@annotation(DataSource)")
public void afterSwitchDS(JoinPoint point){
DataSourceContextHolder.clearDB();
}
}

7.启动类修改:

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@MapperScan(basePackages = {"com.cloud.demo.*.dao"})public class TrusteeInterfaceApplication { public static void main(String[] args) {
SpringApplication.run(TrusteeInterfaceApplication.class, args);
} }

8.使用方式

只需要在service的实现类中的方法上方使用注解即可

@Override
@DataSource("primaryDataSource")
public void saveTGLsbrkjg(TgLsbrkjg tgLsbrkjg) {
tableMapper.saveTg(tgLsbrkjg);
}

Springboot+Mybatis AOP注解动态切换数据源的更多相关文章

  1. springmvc+mybatis多数据源配置,AOP注解动态切换数据源

    springmvc与springboot没多大区别,springboot一个jar包配置几乎包含了所有springmvc,也不需要繁琐的xml配置,springmvc需要配置多种jar包,需要繁琐的x ...

  2. Spring + Mybatis 项目实现动态切换数据源

    项目背景:项目开发中数据库使用了读写分离,所有查询语句走从库,除此之外走主库. 最简单的办法其实就是建两个包,把之前数据源那一套配置copy一份,指向另外的包,但是这样扩展很有限,所有采用下面的办法. ...

  3. springboot集成mongodb实现动态切换数据源

    主要实现原理,利用spring的aop 在切入点执行db操作之前 将数据库切换: 本例子采用aop在controller进行拦截 拦截到MongoTemplate.class 切换数据源后重新放回去 ...

  4. AOP获取方法注解实现动态切换数据源

    AOP获取方法注解实现动态切换数据源(以下方式尚未经过测试,仅提供思路) ------ 自定义一个用于切换数据源的注解: package com.xxx.annotation; import org. ...

  5. 在使用 Spring Boot 和 MyBatis 动态切换数据源时遇到的问题以及解决方法

    相关项目地址:https://github.com/helloworlde/SpringBoot-DynamicDataSource 1. org.apache.ibatis.binding.Bind ...

  6. Spring+Mybatis动态切换数据源

    功能需求是公司要做一个大的运营平台: 1.运营平台有自身的数据库,维护用户.角色.菜单.部分以及权限等基本功能. 2.运营平台还需要提供其他不同服务(服务A,服务B)的后台运营,服务A.服务B的数据库 ...

  7. Spring AOP动态切换数据源

    现在稍微复杂一点的项目,一个数据库也可能搞不定,可能还涉及分布式事务什么的,不过由于现在我只是做一个接口集成的项目,所以分布式就先不用了,用Spring AOP来达到切换数据源,查询不同的数据库就可以 ...

  8. Spring学习总结(16)——Spring AOP实现执行数据库操作前根据业务来动态切换数据源

    深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写 ...

  9. Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法

    一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基 ...

随机推荐

  1. VMware NAT模式下,公司代理下上网 续

    这是在非公司环境下,VMware NAT 静态IP模式下上网 由于公司的限制,可能需要通过proxy上网. 下面是我在公司的配置(参考其他) 1. 修改 /etc/environment http_p ...

  2. pymysql 处理数据的几种方式

    1.表中提取数据 sql = "SELECT * FROM table WHERE name='%s'AND time='%s'" % (name,time)多个选择条件用AND连 ...

  3. java后台转json、转对象、转list集合

    前台数据传递到后台转json 1.普通格式转换成对象 String data=request.getParameter("data"); //单数据的时候转换方式 JSONObje ...

  4. linux可用的跨平台C# .net standard2.0 写的高性能socket框架

    能在window(IOCP)/linux(epoll)运行,基于C# .net standard2.0 写的socket框架,可使用于.net Framework/dotnet core程序集,.使用 ...

  5. ffplay播放YUV数据

    播放器YUV系列的格式用ffplay很方便 免费的 播放NV21 ffplay -i d:/cap.yuv -pix_fmt nv21 -s 640x480 播放YUV420P ffplay -i d ...

  6. Android NDK的生命周期JNI_OnLoad与JNI_OnUnload(转)

    摘要 NDK的生命周期 //当动态库被加载时这个函数被系统调用 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { LOGI ...

  7. webpack插件之htmlWebpackPlugin

    webpack插件之htmlWebpackPlugin webpack插件 自动化 htmlWebpackPlugin  由于webpack已经帮我们处理好js之间的依赖关系,现在我们可以忽略js的加 ...

  8. Flask 中的蓝图

    相当与django中的App 基础模板 1.初识Flask蓝图(blueprint) 创建一个项目然后将目录结构做成: s_view.py 文件中的内容   from flask import Blu ...

  9. Vue知识整理8:条件、URL、点击

    1.通过v-if实现对条件的判断和执行: 2.通过v-bind:href实现对url地址的绑定,其中url写在data中: 3.通过@click="click1"实现点击事件,其中 ...

  10. nacos 发布配置

    server 保留 2 份配置文件,一份在 mysql,一份在本地磁盘,同时在内存中缓存配置文件的 md5 值.当客户端获取配置时,server 直接返回本地磁盘文件,使用的是 sendFile ap ...