这是可以用于公司项目上的双数据源代码,我从加载阶段讲解整个双数据源的运行原理。相关的代码我会上传到资源上面,可以免费下载。
-
准备用到的类
//该类实现设置数据源以及取得当前数据源的功能 public class XDbContextHolder { private static final ThreadLocal contextHolder = new ThreadLocal<>(); /** * 设置数据源 * * @param XDBTypeEnum */ public static void setDbType(XDBTypeEnum XDBTypeEnum) { contextHolder.set(XDBTypeEnum.getValue()); } /** * 取得当前数据源 * * @return */ public static String getDbType() { return (String) contextHolder.get(); } /** * 清除上下文数据 */ public static void clearDbType() { contextHolder.remove(); } }
//Spring boot提供了AbstractRoutingDataSource 根据用户定义的规则选择当前的数据源,为下面使用打基础 public class XDynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return XDbContextHolder.getDbType(); } }
//简单的枚举类 public enum XDBTypeEnum { db1("db1"), db2("db2"); private String value; XDBTypeEnum(String value) { this.value = value; } public String getValue() { return value; } }
-
java编译阶段bean类加载
/** * @Author: 想要飞翔的企鹅 * @Date: 2021/4/14 17:26 * @Version 1.0 */ //带有该注解的类中的方法可以放入到bean容器中 @Configuration public class XMybatisPlusConfig { //加上这个注解放入到bean容器中 @Bean(name = "db1") //这个注解是给DataSource里边的属性赋值的,属性值所在位置是比较深的底层原理 @ConfigurationProperties(prefix = "spring.datasource.druid.db1") public DataSource db1() { return DruidDataSourceBuilder.create().build(); } @Bean(name = "db2") @ConfigurationProperties(prefix = "spring.datasource.druid.db2") public DataSource db2() { return DruidDataSourceBuilder.create().build(); } /** * 动态数据源配置 * * * @return */ @Bean //@Primary自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者 //@Qualifier当有多个DataSource的bean时,使用这个来明确注入DataSource的bean,例如给患者给User的name一个命名为张三,另一个命名为李四,要使用哪一个就需要明确指出来了 @Primary public DataSource multipleDataSource(@Qualifier("db1") DataSource db1, @Qualifier("db2") DataSource db2) { //这个类可以动态的设定使用那个数据源 XDynamicDataSource dynamicDataSource = new XDynamicDataSource(); //将数据源1和数据源2放到map中 Map<Object, Object> targetDataSources = new HashMap<>(); targetDataSources.put(XDBTypeEnum.db1.getValue(), db1); targetDataSources.put(XDBTypeEnum.db2.getValue(), db2); //将两个数据源放入到该动态源中以供使用 dynamicDataSource.setTargetDataSources(targetDataSources); dynamicDataSource.setDefaultTargetDataSource(db2); // 设置默认数据源 return dynamicDataSource; } }
XMybatisPlusConfig 这个类就是将有不同加载信息的数据源放入到bean中,并将这两个bean放入到一个位置供继承AbstractRoutingDataSource 的类调用。
-
调用dao中的方法时用到的类
@Component //aop的切面 @Aspect public class XDataSourceSwitchAspect { @Pointcut("execution(* com.atguigu.dao.db1..*.*(..))") //连接点 private void db1Aspect() { } @Pointcut("execution(* com.atguigu.dao.db2..*.*(..))") private void db2Aspect() { } @Before("db1Aspect()") //在执行连接点之前执行的东西 public void db1() { XDbContextHolder.setDbType(XDBTypeEnum.db1); } @Before("db2Aspect()") public void db2() { XDbContextHolder.setDbType(XDBTypeEnum.db2); } }
该类就是作用就是调用不同的dao方法之前,使用AOP切换成不同的数据源。
这是我java代码放置的位置
https://download.csdn.net/download/PhilsphyPrgram/16680594