博客引用处(以下内容在原有博客基础上进行补充或更改,谢谢这些大牛的博客指导):
spring+druid多数据源配置

druid多数据源配置

一、druid简介
Druid首先是一个数据库连接池,但它不仅仅是一个数据库连接池,它还包含一个ProxyDriver,一系列内置的JDBC组件库,一个SQL Parser。

Druid是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包括DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。

Druid 是目前比较流行的高性能的,分布式列存储的OLAP框架(具体来说是MOLAP)。它有如下几个特点:

一. 亚秒级查询

druid提供了快速的聚合能力以及亚秒级的OLAP查询能力,多租户的设计,是面向用户分析应用的理想方式。

二.实时数据注入

druid支持流数据的注入,并提供了数据的事件驱动,保证在实时和离线环境下事件的实效性和统一性

三.可扩展的PB级存储

druid集群可以很方便的扩容到PB的数据量,每秒百万级别的数据注入。即便在加大数据规模的情况下,也能保证时其效性

四.多环境部署

druid既可以运行在商业的硬件上,也可以运行在云上。它可以从多种数据系统中注入数据,包括hadoop,spark,kafka,storm和samza等

五.丰富的社区

二、druid多数据源使用
1.直接配置

配置两个 dataSource,两个sqlSessionFactory,两个transactionManager,以及关键的地方在于MapperScannerConfigurer 的配置——使用sqlSessionFactoryBeanName属性,注入不同的sqlSessionFactory的名称,这样就为不同的数据库对应的 mapper 接口注入了对应的 sql于master-slave类型的多数据源配置而言不太适应,不支持分布式事务

2.基于AbstractRoutingDataSource和AOP的多数据源配置

我们自己定义一个DataSource类ThreadLocalRountingDataSource,来继承AbstractRoutingDataSource,然后在配置文件中向ThreadLocalRountingDataSource注入 master 和 slave 的数据源,然后通过 AOP 来灵活配置。

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd><!-- 启动spring注解 --><context:annotation-config/><!-- 扫描注解所在的包 --><context:component-scan base-package="com.example"/><!-- 启动aop注解 --><aop:aspectj-autoproxy proxy-target-class="true"/> <!-- 引入属性文件 --><context:property-placeholder location="classpath:jdbc.properties"/><!--   <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="${driver}"/><property name="url" value="${url}"/></bean> --><!-- 配置数据源master --><bean id="dataSourceMaster" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">   <property name="driverClassName" value="${driver}"/><property name="url" value="${url}" />  <!-- 初始化连接大小 --><property name="initialSize" value="0" />  <!-- 连接池最大使用连接数量 --><property name="maxActive" value="20" />  <!-- 连接池最小空闲 --><property name="minIdle" value="1" />  <!-- 连接池最大空闲 --><property name="maxIdle" value="20" />  <!-- 获取连接最大等待时间 --><property name="maxWait" value="60000" />  </bean>  <!-- 配置数据源master --><bean id="dataSourceSlave" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">   <property name="driverClassName" value="${driver}"/><property name="url" value="${url_slave}" />  <!-- 初始化连接大小 --><property name="initialSize" value="0" />  <!-- 连接池最大使用连接数量 --><property name="maxActive" value="20" />  <!-- 连接池最小空闲 --><property name="minIdle" value="0" />  <!-- 连接池最大空闲 --><property name="maxIdle" value="20" />  <!-- 获取连接最大等待时间 --><property name="maxWait" value="60000" />  </bean>  <bean id="dataSource" class="com.example.util.ThreadLocalRountingDataSource"><property name="targetDataSources"><map key-type="com.example.enums.DataSources"><entry key="MASTER" value-ref="dataSourceMaster" /><entry key="SLAVE" value-ref="dataSourceSlave"/></map></property><property name="defaultTargetDataSource" ref="dataSourceMaster"></property></bean> <!-- 配置SQLSessionFactory --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource"/>  <property name="configLocation" value="classpath:mybatis-config.xml"></property> <!-- 加载映射文件 --><property name="mapperLocations" value="classpath*:/com/example/dao/*Mapper.xml"></property>  </bean><!-- 接口方式 --><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.example.dao"></property><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property></bean> </beans>

1.定义一个DataSource枚举类

//定义一个enum来表示不同的数据源
public enum DataSources {MASTER,SLAVE
}

2.ThreadLocalRountingDataSource,继承AbstractRoutingDataSource

public class ThreadLocalRountingDataSource extends AbstractRoutingDataSource{@Overrideprotected Object determineCurrentLookupKey() {// TODO Auto-generated method stubreturn DataSourceTypeManager.get();}}

3.DataSourceTypeManager

//通过 TheadLocal 来保存每个线程选择哪个数据源的标志(key)public class DataSourceTypeManager {private static final ThreadLocal<DataSources> dataSourceTypes=new ThreadLocal<>();public static DataSources get(){return dataSourceTypes.get();}public static void set(DataSources dataSourceType){dataSourceTypes.set(dataSourceType);}public static void reset(){dataSourceTypes.set(DataSources.MASTER);}
}

4.aop管理

@Aspect
@Component
public class DataSourceInterceptor {@Pointcut("execution(public * com.example.service..*.selectByPrimaryKey(..))")public void dataSourceMaster(){};@Before("dataSourceMaster()")public void before(JoinPoint jp){DataSourceTypeManager.set(DataSources.MASTER);}//.../*这里我们定义了一个 Aspect 类,我们使用 @Before 来在符合*  @Pointcut("execution(public * net.aazj.service..*.selectByPrimaryKey(..))") 中的方法被调用之前,*  调用 DataSourceTypeManager.set(DataSources.SLAVE) 设置了 key 的类型为 DataSources.MASTER,*  所以 dataSource 会根据key=DataSources.MASTER 选择 dataSourceSlave 这个dataSource。*  所以该方法对于的sql语句会在slave数据库上执行.*  我们可以不断的扩充 DataSourceInterceptor这个 Aspect,在中进行各种各样的定义,*  来为某个service的某个方法指定合适的数据源对应的dataSource。*  这样我们就可以使用 Spring AOP 的强大功能来,十分灵活进行配置了。*/
}

当调用selectByPrimaryKey方法的时候会进入切面类中切换数据源,方法调用完毕会把数据源切换回来

三、AbstractRoutingDataSource原理
源码:

public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean
void afterPropertiesSet() throws Exception; @Overridepublic void afterPropertiesSet() {if (this.targetDataSources == null) {throw new IllegalArgumentException("Property 'targetDataSources' is required");}this.resolvedDataSources = new HashMap<Object, DataSource>(this.targetDataSources.size());for (Map.Entry<Object, Object> entry : this.targetDataSources.entrySet()) {Object lookupKey = resolveSpecifiedLookupKey(entry.getKey());DataSource dataSource = resolveSpecifiedDataSource(entry.getValue());this.resolvedDataSources.put(lookupKey, dataSource);}if (this.defaultTargetDataSource != null) {this.resolvedDefaultDataSource = resolveSpecifiedDataSource(this.defaultTargetDataSource);}}

targetDataSources 是我们在xml配置文件中注入的 dataSourceMaster 和 dataSourceSlave. afterPropertiesSet方法就是使用注入的dataSourceMaster 和 dataSourceSlave来构造一个HashMap——resolvedDataSources。方便后面根据 key 从该map 中取得对应的dataSource。

protected DataSource determineTargetDataSource() {Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");Object lookupKey = determineCurrentLookupKey();DataSource dataSource = this.resolvedDataSources.get(lookupKey);if (dataSource == null && (this.lenientFallback || lookupKey == null)) {dataSource = this.resolvedDefaultDataSource;}if (dataSource == null) {throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");}return dataSource;
}

Object lookupKey = determineCurrentLookupKey(); 该方法是我们实现的,在其中获取ThreadLocal中保存的 key 值。(见上述步骤2)获得了key之后,在从afterPropertiesSet()(InitializingBean中实现的方法)中初始化好了的resolvedDataSources这个map中获得key对应的dataSource。而ThreadLocal中保存 key 值。

spring+druid多数据源配置相关推荐

  1. spring mybatis 多数据源配置 jeesite 多数据源配置

    spring mybatis 多数据源配置 jeesite 多数据源配置 一.情景描述 在系统数据达到一定的访问量时,遇到单个数据库瓶颈,所以需要扩展数据库,启用第二个数据源资源,项目架构变成 一个服 ...

  2. spring boot多数据源配置示例

    spring boot多数据源配置 1.application.properties spring.datasource.url = jdbc\:oracle\:thin\:@192.168.3.88 ...

  3. druid多数据源配置

    druid多数据源配置 一.配置yml 二.数据源配置类 三.使SpringBoot不创建默认的DataSource 一.配置yml spring:#1.JDBC数据源datasource:druid ...

  4. Spring实现多数据源配置

    一.前言 对于小型项目,服务器与数据库是可以在同一台机子上的,但随着业务的庞大与负责,数据库和服务器就会分离开来.同时随着数据量的增大,数据库也要分开部署到多台机子上. 二.Spring配置文件修改 ...

  5. spring boot +spring data jpa +druid 多数据源配置

    一.首先pom.xml新增如下依赖 <dependencies><dependency><groupId>org.springframework.boot</ ...

  6. Spring Boot多数据源配置并通过注解实现动态切换数据源

    文章目录 1. AbstractRoutingDataSource类介绍 2. ThreadLocal类介绍 3. 环境准备 3.1 数据库准备 3.2 项目创建 4. 具体实现 4.1 定义数据源枚 ...

  7. 企业分布式微服务云SpringCloud SpringBoot mybatis (九)Spring Boot多数据源配置与使用(JdbcTemplate支持)...

    之前在介绍使用JdbcTemplate和Spring-data-jpa时,都使用了单数据源.在单数据源的情况下,Spring Boot的配置非常简单,只需要在application.propertie ...

  8. spring boot多数据源配置(mysql,redis,mongodb)实战

    使用Spring Boot Starter提升效率 虽然不同的starter实现起来各有差异,但是他们基本上都会使用到两个相同的内容:ConfigurationProperties和AutoConfi ...

  9. Spring+Mybatis多数据源配置(三)——Spring如何获取Properties文件的信息

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

最新文章

  1. 哥们,你侵权了,哥有权告你去!
  2. 【半译】扩展shutdown超时设置以保证IHostedService正常关闭
  3. jQuery:从零开始,DIY一个jQuery(2)
  4. CVPR2020|无需3D运动数据训练,最新SOTA人体姿势估计方法
  5. iOS 将16进制字符串转换成UIColor
  6. mvc 调用其他控制器方法session丢失_Java从入门到放弃;MVC 模式
  7. jq获取下拉列表_jQuery下拉框操作系列$(option:selected,this) (锋利的jQuery)
  8. SAP License:税-你知道多少?
  9. Java开发笔记(一百二十七)Swing的标签
  10. 猿创征文|工具百宝箱-数据库连接工具-接口调试与测试工具-抓包工具
  11. 天涯社区脱水机(TianyaTool) - 实现天涯社区宝箱的只看楼主功能
  12. 卡尔曼滤波 KF | 扩展卡尔曼滤波 EKF (思路流程和计算公式)
  13. 【CentOS 7 】密码破解与防破解
  14. XBOX360游戏目录
  15. ubuntu邮件客户端_在Ubuntu中将Gmail设置为默认邮件客户端
  16. 华硕主板无盘启动bios设置_华硕主板开机怎么进入bios_华硕主板bios设置U盘启动方法...
  17. sql server关系代数练习--进阶
  18. Pycharm专业版安装详细教程!
  19. python计算器基础知识_Python基础知识+计算器练习
  20. 大脑是如何编码外界各种信息的?

热门文章

  1. httprunner3、pytest、allure资料整理合集
  2. 2010年五道口考研心得
  3. 不明觉厉!Gitee大神们的算法/数学相关开源项目推荐
  4. 天龙八部张家界聚贤庄服务器维护,【4月18日】4组服务器合服公告
  5. 华为服务器清除系统日志,清除服务器日志
  6. MySQL数据库入门-新手常见问题答疑
  7. html中把视频作为背景音乐,短视频配音乐怎么做?视频配乐详细方法及技巧干货分享...
  8. 序言 工欲善其事必先利其器
  9. 终端运行Java程序
  10. pdf转换成ppt的软件下载