素材巴巴 > 程序开发 >

快速Mybatis配置动态多数据源(基于XML)

程序开发 2023-09-19 16:58:52

上级文章:

IDEA快速Mybatis+Oracle:https://blog.csdn.net/qq_28033719/article/details/103423608


根据原有的框架,配置mybatis动态多数据源,相对来说改的文件很多,同样是把下面代码复制粘贴,快速搭建就好


1、pom.xml配置好相应的依赖,mybatis3.4以上需要和mybatis-spring1.3.0以上搭配,否则会出现一些cglib或者mapper扫描错误

    mysqlmysql-connector-java5.1.40org.springframeworkspring-jdbc5.2.2.RELEASEcglibcglib3.1org.mybatismybatis3.4.4org.mybatismybatis-spring1.3.3
 

2、jdbc.properties 加入新的数据源,实体类表格和Phone一样,自己建立

#mysql数据库com.mysql.jdbc.Driver
 jdbc.mysql.springboottest.driver=com.mysql.jdbc.Driver
 jdbc.mysql.springboottest.url=jdbc:mysql://localhost:3306/springboot_test
 jdbc.mysql.springboottest.username=root
 jdbc.mysql.springboottest.password=root

3、spring-dataSource.xml,按照之前项目的和这个修改一下

    

4、applicationContext.xml,增加AOP配置

    
 

5、增加动态数据源

package org.angular.test.conf;import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;/*** Created by Tanjw on 2019/12/11.*/
 public class DynamicDataSource extends AbstractRoutingDataSource {/*** 动态策略,决定选择哪个数据库* @return targetDataSources.getDeclaredField(" targetDataSources ");*/@Overrideprotected Object determineCurrentLookupKey() {String dbType = DbContextHolder.getDbType();return dbType;}
 }
 

6、DbContextHolder.java

package org.angular.test.conf;import org.angular.test.enums.DBTypeEnum;public class DbContextHolder {private static final ThreadLocal contextHolder = new ThreadLocal<>();/*** 设置数据源* @param dbTypeEnum*/public static void setDbType(DBTypeEnum dbTypeEnum) {contextHolder.set(dbTypeEnum.getValue());}/*** 取得当前数据源* @return*/public static String getDbType() {return (String) contextHolder.get();}/*** 清除上下文数据*/public static void clearDbType() {contextHolder.remove();}
 }
 

7、DBTypeEnum

package org.angular.test.enums;public enum DBTypeEnum {DEFAULT_DS("orcl"),ORCL("orcl"),SPRINGBOOTTEST("springboottest");private String value;DBTypeEnum(String value) {this.value = value;}public String getValue() {return value;}public static DBTypeEnum getEnumByValue(String value){for(DBTypeEnum dBTypeEnum:DBTypeEnum.values()){if(value.equals(dBTypeEnum.getValue())){return dBTypeEnum;}}return null;}
 }

8、增加AOP切面,拦截service的方法切换数据源

package org.angular.test.aspect;import org.angular.test.annotation.DBSource;
 import org.angular.test.conf.DbContextHolder;
 import org.angular.test.enums.DBTypeEnum;
 import org.aspectj.lang.JoinPoint;
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.*;
 import org.aspectj.lang.reflect.MethodSignature;
 import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;import java.lang.reflect.Method;/*** Created by Tanjw on 2019/12/11.*/
 @Component
 @Aspect
 @Order(-100) //这是为了保证AOP在事务注解之前生效,Order的值越小,优先级越高
 public class DataSourceAspect {private static final org.slf4j.Logger LOGGER = org.slf4j.LoggerFactory.getLogger(DataSourceAspect.class);/*** Around拦截,并需要返回结果集合* @param point* @return*/@Around(value = "@annotation(org.angular.test.annotation.DBSource)")public Object SensorsSourceAround(ProceedingJoinPoint point) {// classClass className = point.getTarget().getClass();// methodString methodName = point.getSignature().getName();// paramsClass[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();DBTypeEnum dataSource = DBTypeEnum.DEFAULT_DS;try {// get objectMethod method = className.getMethod(methodName, argClass);// @DBSource exist?String annotationV = "";if (method.isAnnotationPresent(DBSource.class)) {annotationV = method.getAnnotation(DBSource.class).value();// DataSourceNamedataSource = DBTypeEnum.getEnumByValue(annotationV);}// proceedLOGGER.info("change to >>>> " + annotationV + " <<<< Source...");DbContextHolder.setDbType(dataSource);return point.proceed();} catch (Throwable throwable) {throwable.printStackTrace();}return null;}@After("@annotation(org.angular.test.annotation.DBSource)")public void afterSwitchDS(JoinPoint point){DbContextHolder.clearDbType();}}
 

9、添加注解

package org.angular.test.annotation;import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;/*** 动态数据源注解* 根据DBTypeEnum里面的枚举定义相应的数据源* 可以直接在 >>> *Service <<< 上进行注解获取相应数据源* 新增数据源要四步* 1 - jdbc.properties找到datasource写上新的配置(全小写字母,lowwercase,之后改springboot只读小写)* 2 - spring-dataSource.xml配置新的bean* 3 - dynamicDataSource,targetDataSources添加新的数据源* 4 - DBTypeEnum添加新的Enum*/
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.METHOD
 })
 public @interface DBSource {String value() default "orcl";
 }
 

以上就定义好了,使用注解给service指定何种数据源,然后AOP进行切面拦截,根据注解的数据源,进行切换

再完成controller等三层

1、把controller的代码改为

@RequestMapping("/getOrclList")public List getOrclList() {List list = phoneService.getOrclList();return list;}@RequestMapping("/getMysqlList")public List getMysqlList() {List list = phoneService.getMysqlList();return list;}

2、service代码修改

@DBSource("orcl")public List getOrclList() {return phoneMapper.getOrclList();}@DBSource("springboottest")public List getMysqlList() {return phoneMapper.getMysqlList();}
 

3、mapper代码修改

    List getOrclList();List getMysqlList();

4、mapper.xml修改


然后是打包,如果出现配置文件找不到事情,可以把target删除,或者重新找方法打包,target下面有可能没有把配置文件打包进去

 

然后访问两个接口连接

http://localhost:8088/angularTest/phone/getMysqlList

http://localhost:8088/angularTest/phone/getOrclList

出现两种不同数据就是配置成功了


下级文章:

快速Mybatis动态数据源(基于java类):https://blog.csdn.net/qq_28033719/article/details/103609120


标签:

素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。