Spring+MybatisPlus实现多数据源
2019独角兽企业重金招聘Python工程师标准>>>
DatasourceConfig
package com.tonytaotao.dtsc.common.configuration.datasouce.normal; import com.alibaba.druid.pool.DruidDataSource; import com.tonytaotao.dtsc.common.configuration.datasouce.DBTypeEnum; import com.tonytaotao.dtsc.common.configuration.datasouce.DynamicDataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Primary; import javax.sql.DataSource; import java.util.HashMap; import java.util.Map; @Configuration public class DatasourceConfig { /*------------------------------------------------- 普通多数据源----------------------------------------------*/ @Bean("multipleDataSource") @Primary public DataSource multipleDataSource() { DynamicDataSource dynamicDataSource = new DynamicDataSource(); Map< Object, Object > targetDataSources = new HashMap<>(); targetDataSources.put(DBTypeEnum.ONE.getCode(), createDataSourceOne()); targetDataSources.put(DBTypeEnum.TWO.getCode(), createDataSourceTwo()); dynamicDataSource.setTargetDataSources(targetDataSources); dynamicDataSource.setDefaultTargetDataSource(createDataSourceOne()); return dynamicDataSource; } private DataSource createDataSourceOne() { DruidDataSource druidDataSource = createDataSourceBase(); druidDataSource.setUrl("jdbc:mysql://localhost:3306/dtsc?useSSL=false&useUnicode=true&allowPublicKeyRetrieval=true&characterEncoding=UTF8&serverTimezone=GMT"); druidDataSource.setUsername("root"); druidDataSource.setPassword("123456"); return druidDataSource; } private DataSource createDataSourceTwo() { DruidDataSource druidDataSource = createDataSourceBase(); druidDataSource.setUrl("jdbc:mysql://localhost:3306/dtsc_1?useSSL=false&useUnicode=true&allowPublicKeyRetrieval=true&characterEncoding=UTF8&serverTimezone=GMT"); druidDataSource.setUsername("root"); druidDataSource.setPassword("123456"); return druidDataSource; } private DruidDataSource createDataSourceBase() { DruidDataSource druidDataSource = new DruidDataSource(); druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); druidDataSource.setInitialSize(50); druidDataSource.setMaxActive(100); druidDataSource.setMinIdle(5); druidDataSource.setMaxWait(1000); druidDataSource.setPoolPreparedStatements(false); druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(-1); druidDataSource.setValidationQuery("SELECT 1"); druidDataSource.setValidationQueryTimeout(1); druidDataSource.setTestOnBorrow(false); druidDataSource.setTestOnReturn(false); druidDataSource.setTestWhileIdle(true); druidDataSource.setTimeBetweenEvictionRunsMillis(60000); druidDataSource.setMinEvictableIdleTimeMillis(30000); return druidDataSource; } }
MybatisPlusConfig
package com.tonytaotao.dtsc.common.configuration.datasouce.normal; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.annotation.FieldStrategy; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.core.MybatisConfiguration; import com.baomidou.mybatisplus.core.config.GlobalConfig; import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector; import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor; import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Profile; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import javax.sql.DataSource; import java.io.IOException; @Configuration @MapperScan({"com.tonytaotao.dtsc.*.mapper"}) public class MybatisPlusConfig { /** * 性能分析插件 * @return */ @Bean @Profile({"dev","sit"}) public PerformanceInterceptor performanceInterceptor() { return new PerformanceInterceptor(); } /** * 分页插件 * @return */ @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); } /** * * @return */ @Bean("sqlSessionFactory") public MybatisSqlSessionFactoryBean sqlSessionFactory(@Qualifier("multipleDataSource") DataSource multipleDataSource) { try { MybatisSqlSessionFactoryBean sqlSessionFactoryBean = mybatisSqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(multipleDataSource); return sqlSessionFactoryBean; } catch (IOException e) { e.printStackTrace(); return null; } } private MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean() throws IOException{ MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean(); mybatisSqlSessionFactoryBean.setGlobalConfig(globalConfig()); mybatisSqlSessionFactoryBean.setConfiguration(mybatisConfiguration()); mybatisSqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:com/tonytaotao/dtsc/*/mapper/xml/*Mapper.xml")); mybatisSqlSessionFactoryBean.setTypeAliasesPackage("com.tonytaotao.dtsc.*.entity"); return mybatisSqlSessionFactoryBean; } private GlobalConfig globalConfig() { GlobalConfig globalConfig = new GlobalConfig(); GlobalConfig.DbConfig dbConfig = new GlobalConfig.DbConfig(); dbConfig.setIdType(IdType.AUTO); dbConfig.setDbType(DbType.MYSQL); dbConfig.setFieldStrategy(FieldStrategy.NOT_EMPTY); dbConfig.setTableUnderline(true); dbConfig.setLogicDeleteValue("0"); dbConfig.setLogicNotDeleteValue("1"); globalConfig.setDbConfig(dbConfig); LogicSqlInjector logicSqlInjector = new LogicSqlInjector(); globalConfig.setSqlInjector(logicSqlInjector); return globalConfig; } private MybatisConfiguration mybatisConfiguration() { MybatisConfiguration mybatisConfiguration = new MybatisConfiguration(); // 源码里面如果有configuration, 不会注入BaseMapper 里面的方法, 所以这里要这样写 mybatisConfiguration.init(globalConfig()); mybatisConfiguration.setMapUnderscoreToCamelCase(true); mybatisConfiguration.setCacheEnabled(false); return mybatisConfiguration; } }
TransationConfig
package com.tonytaotao.dtsc.common.configuration.datasouce.normal; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; /** * @author wujintao * * Configuration 类似于spring 配置文件,负责注册bean * ComponentScan 注解类查找规则定义 <context:component-scan/> * EnableAspectJAutoProxy 激活Aspect 自动代理 <aop:aspectj-autoproxy/> * proxy-target-class : 默认为false 表示使用JDK 动态代理。如果实现了至少一个接口,Spring 会优先选择使用JDK 动态代理,若果没有实现任何接口,则spring 会选择CGLIB 动态代理,强制使用CGLIB 动态代理,使用以下配置 * exposeProxy : springAOP 只会拦截public 方法,不会拦截provided 和private 方法,并且不会拦截public 方法内部调用的其他方法,也就是说只会拦截代理对象的方法,即增强的是代理对象,而不是原对象, 设置就可以暴露出代理对象,拦截器会获取代理对象,并且将代理对象转换成原对象。从而对内部调用的方法进行增强 * EnableTransactionManagement 启用注解式事务管理 <tx:annotation-driven /> */ @Configuration @EnableTransactionManagement @EnableAspectJAutoProxy(exposeProxy = true) public class TransationConfig { //@Bean public DataSourceTransactionManager dataSourceTransactionManager(@Qualifier("multipleDataSource") DataSource multipleDataSource) { DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(); transactionManager.setDataSource(multipleDataSource); return transactionManager; } }
DBTypeEnum
package com.tonytaotao.dtsc.common.configuration.datasouce; import lombok.Getter; public enum DBTypeEnum { ONE("ONE", "db one"), TWO("TWO", "db two"); DBTypeEnum(String code, String msg) { this.code = code; this.msg = msg; } @Getter private String code; private String msg; }
DBAnnotation
package com.tonytaotao.dtsc.common.configuration.datasouce; 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 DBAnnotation { DBTypeEnum dbSource() default DBTypeEnum.ONE; }
DBAspect
package com.tonytaotao.dtsc.common.configuration.datasouce; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import java.lang.reflect.Method; @Component @Aspect @Order(-100) @Slf4j public class DBAspect { @Pointcut("execution(* com.tonytaotao.dtsc.*.service..*.*(..))") private void pointcut() { } @Before("pointcut()") public void before(JoinPoint joinPoint) { Object target = joinPoint.getTarget(); String methodName = joinPoint.getSignature().getName(); Class<?> clazz = target.getClass(); log.info("before [ class = {}, method = {} ] execute", clazz.getName(), methodName); Class<?>[] parameterTypes = ((MethodSignature)joinPoint.getSignature()).getMethod().getParameterTypes(); try { Method method = clazz.getMethod(methodName, parameterTypes); if (method != null) { if (method.getDeclaringClass().isAnnotationPresent(DBAnnotation.class) && !method.isAnnotationPresent(DBAnnotation.class)) { DBAnnotation dbAnnotation = method.getDeclaringClass().getAnnotation(DBAnnotation.class); DBContextHolder.setDbType(dbAnnotation.dbSource()); log.info("[class = {}, method = {} ] 切换类级数据源 [ {} ] 成功", clazz.getName(), methodName, dbAnnotation.dbSource()); } else if ( method.isAnnotationPresent(DBAnnotation.class)) { DBAnnotation dbAnnotation = method.getAnnotation(DBAnnotation.class); DBContextHolder.setDbType(dbAnnotation.dbSource()); log.info("[class = {}, method = {} ] 切换方法级数据源 [ {} ] 成功", clazz.getName(), methodName, dbAnnotation.dbSource()); } else { DBContextHolder.setDbType(DBTypeEnum.ONE); log.info("[class = {}, method = {} ] 切换默认数据源 [ {} ] 成功", clazz.getName(), methodName, DBTypeEnum.ONE); } } } catch (Exception e) { log.error(" 数据源切换异常", e); } } }
DBContextHolder
package com.tonytaotao.dtsc.common.configuration.datasouce; public class DBContextHolder { private static final ThreadLocal contextHolder = new ThreadLocal<>(); /** * 设置数据源 * @param dbTypeEnum */ public static void setDbType(DBTypeEnum dbTypeEnum) { contextHolder.set(dbTypeEnum.getCode()); } /** * 取得当前数据源 * @return */ public static String getDbType() { return (String) contextHolder.get(); } /** * 清除上下文数据 */ public static void clearDbType() { contextHolder.remove(); } }
DynamicDataSource
package com.tonytaotao.dtsc.common.configuration.datasouce; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DBContextHolder.getDbType(); } }
使用方式
只要在 service 实现类的方法上或者类上加上 @DBAnnotation 指定数据源,就能实现自动切换数据源
转载于:https://my.oschina.net/TonyTaotao/blog/2980518
Spring+MybatisPlus实现多数据源相关推荐
- spring boot项目自定义数据源,mybatisplus分页、逻辑删除无效解决方法
Spring Boot项目中数据源的配置可以通过两种方式实现: 1.application.yml或者application.properties配置 2.注入DataSource及SqlSessio ...
- Mybatis | Mybatis-plus配置多数据源,连接多数据库
文章目录 前言 业务逻辑 使用Mybatis实现 使用Mybatis-plus实现 前言 工作的时候,遇到了需要将一个数据库的一些数据插入或更新到另一个数据库.一开始使用insert into T ...
- SpringBoot整合:Druid、MyBatis、MyBatis-Plus、多数据源、knife4j、日志、Redis,Redis的Java操作工具类、封装发送电子邮件等等
SpringBoot笔记 一.SpringBoot 介绍 1.1.SpringBoot简介 SpringBoot 是一个快速开发的框架, 封装了Maven常用依赖.能够快速的整合第三方框架:简化XML ...
- Spring中配置DataSource数据源的几种选择
Spring中配置DataSource数据源的几种选择 在Spring框架中有如下3种获得DataSource对象的方法: 从JNDI获得DataSource. 从第三方的连接池获得DataSourc ...
- Spring(AbstractRoutingDataSource)实现动态数据源切换
参考:http://linhongyu.blog.51cto.com/6373370/1615895 一.前言 近期一项目A需实现数据同步到另一项目B数据库中,在不改变B项目的情况下,只好选择项目A中 ...
- Spring(AbstractRoutingDataSource)实现动态数据源切换--转载
原始出处:http://linhongyu.blog.51cto.com/6373370/1615895 一.前言 近期一项目A需实现数据同步到另一项目B数据库中,在不改变B项目的情况下,只好选择项目 ...
- java多个数据库数据进行访问_通过Spring Boot配置动态数据源访问多个数据库的实现代码...
之前写过一篇博客<Spring+Mybatis+Mysql搭建分布式数据库访问框架>描述如何通过Spring+Mybatis配置动态数据源访问多个数据库.但是之前的方案有一些限制(原博客中 ...
- Spring+Hibernate配置多数据源
Spring+Hibernate配置多数据源 转载于:https://www.cnblogs.com/zhujiabin/p/4816453.html
- 【Spring学习】spring动态配置多数据源
这段时间在做智能导航的管理系统--运维系统,涉及到连接多个数据库的问题.因为运维系统要用到智能导航的一些功能,我们目前只是简单的将智能导航整合到运维系统中:运维系统有一个自己的数据库,导航也有自己的数 ...
最新文章
- 【第一组】第十次冲刺例会纪要
- 一个由印度人编写的VC串口类
- ubuntu下eclipse的svn插件使用javahl
- RecyclerView的优化:RecycledViewPool
- 知识图谱基础知识(一): 概念和构建
- 计算机合并键功能,Word组合(功能键与Ctrl等组合) -电脑资料
- SQL中Case和convert()
- 谱聚类、Chameleon聚类、PCCA、SOM、Affinity Propagation
- react-json渲染
- CentOS 6.X启动流程
- iQOO骑士黑版本四月亮相:搭载骁龙855+12G运存
- C11头文件threads.h声明了创建和管理线程,信号,条件变量的函数
- Redis开发与运维之第八章理解内存(五)
- arcgis 循环模型批量处理_科学网-ArcGIS模型构建器批处理操作-张凌的博文
- volatile原理:happen before
- 关于中国电信天翼开放平台短信接口的一些使用
- 怎么解c语言逆向编码,逆向还原C语言代码 练习1
- Dolby技术汇总(二) --- Dolby Mobile
- HR是这样筛选简历的,不知道就完蛋!
- python二进制的位运算符
热门文章
- docker centos 无法用systemctl 启动服务的问题
- SHELL-命令解释程序
- PowerPC VxWorks BSP分析7——image压缩
- mysql hy000 1005,mysql – ERROR 1005(HY000):无法创建表(errno:150)
- 小白兔写话_聪明的小白兔看图写话
- python中的tuple_python 数据类型 - tuple
- python urlretrieve登录下载_使用python urlretrieve下载文件
- 两个点 定位_深圳Mark点定位的一般原理与步骤
- 操作系统中进程并发运行的过程_三种电磁流量计运行过程中常见故障解决详情!...
- python 返回字符串长度,当使用特殊字符时,Python返回错误的字符串长度