在开发中因需求在项目中需要实现多数据源(虽然项目框架是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. 实战build-react(二)-------引入Ant Design(增加)

    https://blog.csdn.net/zhan_lijian/article/details/85271906(copy) 1.肯定参考facebook关于react官网咯 快速搭建 creat ...

  2. 使用webuploader组件实现大文件分片上传,断点续传

    本人在2010年时使用swfupload为核心进行文件的批量上传的解决方案.见文章:WEB版一次选择多个文件进行批量上传(swfupload)的解决方案. 本人在2013年时使用plupload为核心 ...

  3. jQuery_完成复选框的全选与全不选

    别的不多说,直接上代码,用于完成复选框的全选与全不选. <!DOCTYPE html> <html> <head> <meta charset="U ...

  4. go语言系列--输出正弦函数

    实验所用到的标准库和包 库与包之间的理解可以类比成:数据库种的库和表 库名 作用 image 常见图形格式的访问及生成 log 日志记录库 math 数学库 os 操作系统平台不依赖平台操作封装 查看 ...

  5. babel简介——简单介绍与实用(转)

    博客讲解内容如下: 1.babel是什么 2.javascript制作规范 3.babel转译器 4.babel的使用 5.常见的几种babel转译器和插件 6.babel最常见配置选项 7.babe ...

  6. CVE-2019-0708

    本机IP 192.168.1.100 靶机IP 1:windows2003sever  :192.168.1.101 确认3389端口开启 0x01测试windowsxp 切到目录 目标机器确实存在 ...

  7. CodeChef---- February Challenge 2018----Chef and odd queries(复杂度分块计算)

    链接    https://www.codechef.com/FEB18/problems/CHANOQ/ Chef and odd queries Problem Code: CHANOQ Chef ...

  8. Java中String类中常用的方法

    1.字符串与字符数组的转换 用toCharArray()方法将字符串变为字符数组 String str = "abcdef"; char c[] = str.tocharArray ...

  9. Failed to find data source: kafka

    缺少包,在spark-submit 中指定 packages 如下: --packages org.apache.spark:spark-sql-kafka-0-10_2.11:2.1.0

  10. JAVA中对null进行强制类型转换(null可以强转为任意对象,并执行对象的静态方法)

    今天很好奇,对null进行强转会不会抛错.做了如下测试得到的结果是, 如果把null强转给对象,是不会抛异常的,本身对象是可以为null的. 但是如果是基本类型,比如 int i = (Integer ...