diff --git a/pictures/multi-console.png b/pictures/multi-console.png
new file mode 100644
index 0000000..876c645
Binary files /dev/null and b/pictures/multi-console.png differ
diff --git a/pictures/multi-db-show.png b/pictures/multi-db-show.png
new file mode 100644
index 0000000..384d34c
Binary files /dev/null and b/pictures/multi-db-show.png differ
diff --git a/pictures/multi-db1-show.png b/pictures/multi-db1-show.png
new file mode 100644
index 0000000..2c70db1
Binary files /dev/null and b/pictures/multi-db1-show.png differ
diff --git a/pictures/multi-db1.png b/pictures/multi-db1.png
new file mode 100644
index 0000000..7953ceb
Binary files /dev/null and b/pictures/multi-db1.png differ
diff --git a/pictures/multi-db2-show.png b/pictures/multi-db2-show.png
new file mode 100644
index 0000000..3ec044d
Binary files /dev/null and b/pictures/multi-db2-show.png differ
diff --git a/pictures/multi-db2.png b/pictures/multi-db2.png
new file mode 100644
index 0000000..312bbc4
Binary files /dev/null and b/pictures/multi-db2.png differ
diff --git a/pictures/multi-tran-fail.png b/pictures/multi-tran-fail.png
new file mode 100644
index 0000000..47dcb9f
Binary files /dev/null and b/pictures/multi-tran-fail.png differ
diff --git a/spring-boot/springboot-druid-mybatis-multi/pom.xml b/spring-boot/springboot-druid-mybatis-multi/pom.xml
new file mode 100644
index 0000000..cc44259
--- /dev/null
+++ b/spring-boot/springboot-druid-mybatis-multi/pom.xml
@@ -0,0 +1,91 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.2.RELEASE
+
+
+ com.heibaiying
+ springboot-druid-mybatis-multi
+ 0.0.1-SNAPSHOT
+ springBoot-druid-mybatis-multi
+ Demo project for Spring Boot
+
+
+ 1.8
+
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 1.3.2
+
+
+
+
+ mysql
+ mysql-connector-java
+ 6.0.6
+
+
+
+ com.alibaba
+ druid-spring-boot-starter
+ 1.1.10
+
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-jta-atomikos
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/spring-boot/springboot-druid-mybatis-multi/src/main/java/com/heibaiying/springboot/DruidMybatisMultiApplication.java b/spring-boot/springboot-druid-mybatis-multi/src/main/java/com/heibaiying/springboot/DruidMybatisMultiApplication.java
new file mode 100644
index 0000000..078e1d0
--- /dev/null
+++ b/spring-boot/springboot-druid-mybatis-multi/src/main/java/com/heibaiying/springboot/DruidMybatisMultiApplication.java
@@ -0,0 +1,15 @@
+package com.heibaiying.springboot;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+
+@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
+public class DruidMybatisMultiApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(DruidMybatisMultiApplication.class, args);
+ }
+
+}
+
diff --git a/spring-boot/springboot-druid-mybatis-multi/src/main/java/com/heibaiying/springboot/aop/DynamicDataSourceAspect.java b/spring-boot/springboot-druid-mybatis-multi/src/main/java/com/heibaiying/springboot/aop/DynamicDataSourceAspect.java
new file mode 100644
index 0000000..a7f9f14
--- /dev/null
+++ b/spring-boot/springboot-druid-mybatis-multi/src/main/java/com/heibaiying/springboot/aop/DynamicDataSourceAspect.java
@@ -0,0 +1,40 @@
+package com.heibaiying.springboot.aop;
+
+import com.heibaiying.springboot.config.DataSourceContextHolder;
+import com.heibaiying.springboot.constant.Data;
+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.annotation.Pointcut;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author : heibaiying
+ * @description : 动态方式去切换数据源
+ */
+@Aspect
+@Component
+public class DynamicDataSourceAspect {
+
+ @Pointcut(value = "execution(* com.heibaiying.springboot.dao.*.*(..))")
+ public void dataSourcePointCut() {
+ }
+
+ @Before(value = "dataSourcePointCut()")
+ public void beforeSwitchDS(JoinPoint point) {
+
+ Object[] args = point.getArgs();
+
+ if (args == null || args.length < 1 || !Data.DATASOURCE2.equals(args[0])) {
+ DataSourceContextHolder.setDataKey(Data.DATASOURCE1);
+ } else {
+ DataSourceContextHolder.setDataKey(Data.DATASOURCE2);
+ }
+ }
+
+ @After(value = "dataSourcePointCut()")
+ public void afterSwitchDS(JoinPoint point) {
+ DataSourceContextHolder.clearDataKey();
+ }
+}
diff --git a/spring-boot/springboot-druid-mybatis-multi/src/main/java/com/heibaiying/springboot/bean/Programmer.java b/spring-boot/springboot-druid-mybatis-multi/src/main/java/com/heibaiying/springboot/bean/Programmer.java
new file mode 100644
index 0000000..f5fb33e
--- /dev/null
+++ b/spring-boot/springboot-druid-mybatis-multi/src/main/java/com/heibaiying/springboot/bean/Programmer.java
@@ -0,0 +1,34 @@
+package com.heibaiying.springboot.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * @author : heibaiying
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class Programmer {
+
+ private int id;
+
+ private String name;
+
+ private int age;
+
+ private float salary;
+
+ private Date birthday;
+
+ public Programmer(String name, int age, float salary, Date birthday) {
+ this.name = name;
+ this.age = age;
+ this.salary = salary;
+ this.birthday = birthday;
+ }
+
+}
diff --git a/spring-boot/springboot-druid-mybatis-multi/src/main/java/com/heibaiying/springboot/config/AbstractDataSourceConfig.java b/spring-boot/springboot-druid-mybatis-multi/src/main/java/com/heibaiying/springboot/config/AbstractDataSourceConfig.java
new file mode 100644
index 0000000..62f3cb7
--- /dev/null
+++ b/spring-boot/springboot-druid-mybatis-multi/src/main/java/com/heibaiying/springboot/config/AbstractDataSourceConfig.java
@@ -0,0 +1,47 @@
+package com.heibaiying.springboot.config;
+
+import com.atomikos.jdbc.AtomikosDataSourceBean;
+import org.springframework.core.env.Environment;
+
+import javax.sql.DataSource;
+import java.util.Properties;
+
+/**
+ * @author : heibaiying
+ * @description :
+ */
+public class AbstractDataSourceConfig {
+
+ public DataSource getDataSource(Environment env, String prefix, String dataSourceName){
+ Properties prop = build(env,prefix);
+ AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
+ ds.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
+ ds.setUniqueResourceName(dataSourceName);
+ ds.setXaProperties(prop);
+ return ds;
+ }
+
+ public Properties build(Environment env, String prefix) {
+ Properties prop = new Properties();
+ prop.put("url", env.getProperty(prefix + "url"));
+ prop.put("username", env.getProperty(prefix + "username"));
+ prop.put("password", env.getProperty(prefix + "password"));
+ prop.put("driverClassName", env.getProperty(prefix + "driver-class-name", ""));
+ prop.put("initialSize", env.getProperty(prefix + "initialSize", Integer.class));
+ prop.put("maxActive", env.getProperty(prefix + "maxActive", Integer.class));
+ prop.put("minIdle", env.getProperty(prefix + "minIdle", Integer.class));
+ prop.put("maxWait", env.getProperty(prefix + "maxWait", Integer.class));
+ //prop.put("poolPreparedStatements", env.getProperty(prefix + "poolPreparedStatements", Boolean.class));
+ //prop.put("maxPoolPreparedStatementPerConnectionSize",env.getProperty(prefix + "maxPoolPreparedStatementPerConnectionSize", Integer.class));
+ prop.put("validationQuery", env.getProperty(prefix + "validationQuery"));
+ //prop.put("validationQueryTimeout", env.getProperty(prefix + "validationQueryTimeout", Integer.class));
+ prop.put("testOnBorrow", env.getProperty(prefix + "testOnBorrow", Boolean.class));
+ prop.put("testOnReturn", env.getProperty(prefix + "testOnReturn", Boolean.class));
+ prop.put("testWhileIdle", env.getProperty(prefix + "testWhileIdle", Boolean.class));
+ prop.put("timeBetweenEvictionRunsMillis", env.getProperty(prefix + "timeBetweenEvictionRunsMillis", Integer.class));
+ prop.put("minEvictableIdleTimeMillis", env.getProperty(prefix + "minEvictableIdleTimeMillis", Integer.class));
+ //prop.put("useGlobalDataSourceStat",env.getProperty(prefix + "useGlobalDataSourceStat", Boolean.class));
+ //prop.put("filters", env.getProperty(prefix + "filters"));
+ return prop;
+ }
+}
diff --git a/spring-boot/springboot-druid-mybatis-multi/src/main/java/com/heibaiying/springboot/config/CustomSqlSessionTemplate.java b/spring-boot/springboot-druid-mybatis-multi/src/main/java/com/heibaiying/springboot/config/CustomSqlSessionTemplate.java
new file mode 100644
index 0000000..759c552
--- /dev/null
+++ b/spring-boot/springboot-druid-mybatis-multi/src/main/java/com/heibaiying/springboot/config/CustomSqlSessionTemplate.java
@@ -0,0 +1,739 @@
+package com.heibaiying.springboot.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.exceptions.PersistenceException;
+import org.apache.ibatis.executor.BatchResult;
+import org.apache.ibatis.session.*;
+import org.mybatis.spring.MyBatisExceptionTranslator;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.springframework.dao.support.PersistenceExceptionTranslator;
+import org.springframework.util.Assert;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.sql.Connection;
+import java.util.List;
+import java.util.Map;
+
+import static java.lang.reflect.Proxy.newProxyInstance;
+import static org.apache.ibatis.reflection.ExceptionUtil.unwrapThrowable;
+import static org.mybatis.spring.SqlSessionUtils.*;
+
+/***
+ * @description: 自定义 sqlSessionTemplate 实现
+ * 这个方法继承自sqlSessionTemplate,主要是重写了getSqlSessionFactory方法,并在getSqlSession时候传入我们用此方法得到的SqlSessionFactory
+ */
+
+@Slf4j
+public class CustomSqlSessionTemplate extends SqlSessionTemplate {
+/*
+
+
+ private final SqlSessionFactory sqlSessionFactory;
+ private final ExecutorType executorType;
+ private final SqlSession sqlSessionProxy;
+ private final PersistenceExceptionTranslator exceptionTranslator;
+
+ private Map