spring mybatis 多数据源配置 jeesite 多数据源配置
spring mybatis 多数据源配置 jeesite 多数据源配置
一、情景描述
在系统数据达到一定的访问量时,遇到单个数据库瓶颈,所以需要扩展数据库,启用第二个数据源资源,项目架构变成 一个服务对应多个数据源的形式。
二、步骤
1、原理:org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource,实现动态数据源的切换。
2、创建 DynamicDataSource 继承 AbstractRoutingDataSource , 重写 determineCurrentLookupKey 方法,配置数据源切换
3、创建 DataSourceEnum 定义数据源类型
4、创建 DataSourceHolder ,提供数据源切换
5、创建多个数据源 JK , SEC
6、配置到 DynamicDataSource 中
7、同步调 配置文件中数据源改为: dynamicDataSource
- org.mybatis.spring.SqlSessionFactoryBean (spring-context.xml 文件中)
- org.springframework.jdbc.datasource.DataSourceTransactionManager (spring-context.xml 文件中)
- org.activiti.spring.SpringProcessEngineConfiguration (spring-context-activiti.xml)
8、在Controller中,使用: DataSourceHolder.setDataSource(DataSourceEnum.SEC); 可实现数据源的切换。
9、实现数据源动态切换:
- 定义 DataSource 注解
- 配置AOP切面: DataSourceAspect
- 在 Controller方法上,使用 @DataSource(DataSourceEnum.SEC) 注解,实现数据源的切换
10、遗留问题:在Service层,切换数据源无效,经过日志打印发现,在从 Controller 进入到Service时,会调用数据源 , 之后可以进行切换,但是遇到切换无效 ... 个人推测,是因为 Service 继承的 Dao层的缘故 ... 问题有待确认!
三、代码实现
1、创建 DynamicDataSource 类
import java.util.Map;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;/*** description: 动态数据源切换* @version v1.0* @author w* @date 2021年5月7日下午2:56:09**/
public class DynamicDataSource extends AbstractRoutingDataSource {private static final Logger logger = LoggerFactory.getLogger(DynamicDataSource.class);public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {super.setDefaultTargetDataSource(defaultTargetDataSource);super.setTargetDataSources(targetDataSources);super.afterPropertiesSet();}public DynamicDataSource() {}@Overrideprotected Object determineCurrentLookupKey() {logger.info("use dataSource , {}" , DataSourceHolder.getDataSource());return DataSourceHolder.getDataSource();}
}
2、创建 DataSourceEnum 定义数据源类型
/*** description: 数据源类型* @version v1.0* @author w* @date 2021年5月10日下午3:40:07**/
public enum DataSourceEnum {/*** 默认数据源JK*/JK ,/*** 第二个数据源*/SEC ;
}
3、创建 DataSourceHolder ,提供数据源切换
import com.thinkgem.jeesite.common.persistence.enums.DataSourceEnum;/*** description: 数据源提供* @version v1.0* @author w* @date 2021年5月10日下午2:44:22**/
public class DataSourceHolder {private static final ThreadLocal<String> CONTAINER = new ThreadLocal<String>();public static String getDataSource() {return CONTAINER.get();}public static void setDataSource(String type) {CONTAINER.set(type);}public static void setDataSource(DataSourceEnum dataSourceEnum) {CONTAINER.set(dataSourceEnum.name());}public static void clearDataSource() {CONTAINER.remove();}}
4、创建多个数据源 JK , SEC
<bean id="secDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <property name="driverClassName" value="${jdbc.driver}" />... 略 ...
5、配置到 DynamicDataSource 中
<bean id="dynamicDataSource" class="com.thinkgem.jeesite.common.persistence.DynamicDataSource"><property name="targetDataSources"><map key-type="java.lang.String"><description>build dataSource key value mapping</description><entry key="JK" value-ref="jkDataSource"></entry><entry key="SEC" value-ref="secDataSource"></entry></map></property><property name="defaultTargetDataSource" ref="jkDataSource"></property>
</bean>
6、同步调整:spring-context.xml 中,原 dataSource 调整为 dynamicDataSource , spring-context-activiti.xml 原 dataSource 调整为 dynamicDataSource 。
7、创建 DataSource 注解
*** description: 切换数据源的注解* @version v1.0* @author w* @date 2021年5月10日下午3:42:14**/
@Target(value = { ElementType.METHOD , ElementType.TYPE })
@Retention(value = RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface DataSource {/*** description: 实现数据源的切换* @return DataSourceEnum* @version v1.0* @author w* @date 2021年5月10日 下午3:45:40*/DataSourceEnum value() default DataSourceEnum.JK ;
}
8、创建 DataSourceAspect 类,配置AOP切面 (需要在 spring-mvc.xml 文件中,配置启用注解 <aop:aspectj-autoproxy/> )
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import com.thinkgem.jeesite.common.persistence.DataSourceHolder;
import com.thinkgem.jeesite.common.persistence.annotation.DataSource;/*** description: 数据源的切面 配置* @version v1.0* @author w* @date 2021年5月10日下午4:09:17**/
@Component
@Order(10)
@Aspect
public class DataSourceAspect {private static final Logger logger = LoggerFactory.getLogger(DataSourceAspect.class);/*** description: 配置切点* @return void* @version v1.0* @author w* @date 2021年5月10日 下午4:13:32*/@Pointcut(value = "@annotation(com.thinkgem.jeesite.common.persistence.annotation.DataSource)"+"|| @within(com.thinkgem.jeesite.common.persistence.annotation.DataSource)")public void pointCut() {}/*** description: 配置环绕 * @param point* @throws Throwable* @return Object* @version v1.0* @author w* @date 2021年5月10日 下午4:25:51*/@Around("pointCut()")public Object around(ProceedingJoinPoint point) throws Throwable {MethodSignature methodSignature = (MethodSignature)point.getSignature();DataSource annotation = methodSignature.getMethod().getAnnotation(DataSource.class);if(null != annotation) {DataSourceHolder.setDataSource(annotation.value().name());logger.info("数据源切换成功~~ use dataSource , {}" , annotation.value());}else {// 尝试从类上获取DataSource findAnnotation = AnnotationUtils.findAnnotation(methodSignature.getDeclaringType(), DataSource.class);if(null != findAnnotation) {DataSourceHolder.setDataSource(findAnnotation.value().name());logger.info("数据源切换成功~~ use dataSource findAnnotation , {}" , findAnnotation.value());}}try {return point.proceed();} finally {DataSourceHolder.clearDataSource();}}}
9、在Controller中的方法上,使用 @DataSource(DataSourceEnum.SEC) 注解,即可实现数据源切换。
@DataSource(DataSourceEnum.SEC)@RequestMapping(value = {"list", ""})@ResponseBodypublic ResultVO list(args...) {return ResultVO.success(page);}
四、总结
1、使用Spring提供的 AbstractRoutingDataSource 类,实现数据源的切换。
2、使用Spring AOP 实现,动态数据源切换,避免在Controller中硬编码。
参考资料:Spring, MyBatis 多数据源的配置和管理
【Mybatis】MyBatis之配置多数据源(十)
ThreadLocal作用理解
spring mybatis 多数据源配置 jeesite 多数据源配置相关推荐
- [转载]spring+mybatis加载属性文件设置数据源失败原因及解决方案 - 泡在网上的日子
spring+mybatis加载属性文件设置数据源失败原因及解决方案 - 泡在网上的日子 http://www.jcodecraeer.com/a/chengxusheji/java/2013/062 ...
- java spring mysql配置_java相关:mysql+spring+mybatis实现数据库读写分离的代码配置
java相关:mysql+spring+mybatis实现数据库读写分离的代码配置 发布于 2020-4-4| 复制链接 分享一篇关于关于mysql+spring+mybatis实现数据库读写分离的代 ...
- Eclipse+Maven+Struts2+Spring+Mybatis完整搭建
一.前言 公司框架是SSH,hibernate用的越来越少,做了几年后,也懒得用了,springjdbc玩到现在,maven,mybatis没用到一直都没去接触,感慨现在技术真是发展越来越快,有点落伍 ...
- Spring+MyBatis 多数据源配置和切换
两台 MySQL 数据库(属于 master-slave 主从关系),基于 Java8,Spring4,MyBatis3.2 环境. maven 依赖配置 <dependencies>&l ...
- Spring+Mybatis多数据源配置(一)——MySQL与Oracle通过配置切换
欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...
- Spring, MyBatis 多数据源的配置和管理
同一个项目有时会涉及到多个数据库,也就是多数据源.多数据源又可以分为两种情况: 1)两个或多个数据库没有相关性,各自独立,其实这种可以作为两个项目来开发.比如在游戏开发中一个数据库是平台数据库,其它还 ...
- Spring 学习系列 -- Spring + Mybatis 从零开始配置多数据源访问
目的: 项目中以前有整合mybatis + spring操作数据库,但是以前都是单数据库,现需要实现mybatis访问多数据源,依旧使用spring调用mybatis. 通过注解的方式整合 sprin ...
- Spring+MyBatis多数据源配置实现
最近用到了MyBatis配置多数据源,原以为简单配置下就行了,实际操作后发现还是要费些事的,这里记录下,以作备忘 不多废话,直接上代码,后面会有简单的实现介绍 jdbc和log4j的配置 #定义输出格 ...
- 【教程】Spring+Mybatis环境配置多数据源
做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 文章目录 一.简要概述 二.代码详解 2.1 `DataSourceConstants` 数据源常量类 2.2 `Data ...
最新文章
- 第十三周项目4-数组的排序:冒泡排序
- 强交变磁场下的AD转换数值的变化
- 解决SVN 每次操作都需要重输入用户名密码问题
- 03构建之法阅读笔记之三
- 倒数日怎么显示在桌面_深圳暴风谷滑梯皮带提升机怎么选
- 2.3.6 操作系统之进程同步与互斥经典问题(生产者-消费者问题、多生产者-多消费者问题、吸烟者问题、读者-写者问题、哲学家进餐问题)
- 【连载】如何掌握openGauss数据库核心技术?秘诀五:拿捏数据库安全(4)
- python主函数入口_python类 + mian()函数
- 阿里云网盘内测_叫板百度网盘?阿里云网盘内测中,下载速度是亮点
- sv信道模型是什么_信道模型(信道模型分类)
- 怎样黑网吧的万象系统_5636小编教你如何进入万象网管系统
- Js 获取浏览器高度
- AttributeError:partially initialized module ''has no attribute''(most likely dueto a circular import
- Aifred、Wox免费开源的效率启动器
- 【QA单】柿饼派及柿饼M3模块相关QA(持续更新....)
- python数据标准_python-StandardScaler数据标准化
- UVa12325 宝藏
- [CQOI2005]三角形面积并
- 浅谈:智能化变电站在线监测系统
- Windows本地连接正常,上不去网的解决办法
热门文章
- 代理模式与三种方式实现SpringAOP!
- Java检测IP地址输入是否正确
- attr()和prop()的区别
- 新计算机的windows要不要不断更新,win10一直出现无法完成更新正在撤销更改请不要关闭你的计算机,怎么办?...
- 如何取消掉计算机更新图标,本文演示win10电脑更新图标怎么去掉的具体操作方式...
- 指纹图像方向图matlab,基于Matlab实现的指纹图像细节特征提取
- 【转载】那个裸辞的程序员,后来怎么样了?
- Studio 3T的使用
- 桌面便利贴软件下载 电脑桌面便签小工具软件下载
- python midi_Python | 读取 midi 文件