快速Mybatis配置动态多数据源(基于XML)
上级文章:
IDEA快速Mybatis+Oracle:https://blog.csdn.net/qq_28033719/article/details/103423608
根据原有的框架,配置mybatis动态多数据源,相对来说改的文件很多,同样是把下面代码复制粘贴,快速搭建就好
1、pom.xml配置好相应的依赖,mybatis3.4以上需要和mybatis-spring1.3.0以上搭配,否则会出现一些cglib或者mapper扫描错误
mysql mysql-connector-java 5.1.40 org.springframework spring-jdbc 5.2.2.RELEASE cglib cglib 3.1 org.mybatis mybatis 3.4.4 org.mybatis mybatis-spring 1.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
标签:
相关文章
-
无相关信息