最近在学习spring boot,发现在jar包依赖方面做很少的工作量就可以了,对于数据库操作,我用的比较多的是mybatis plus,在中央仓库已经有mybatis-plus的插件了,对于单数据源来说直接使用就是了,但我自己的项目经常会有多数据源的情况,自己去试着写数据源的代码,核心的方法参考mp说明文档中多数据源的处理,使用动态数据源,根据需求去切换数据源

新建spring-boot项目

这一步大家去参考其它教程,很简单

定义数据源相关Model

动态数据源

继承了抽像的数据源,并实现了DataSource,归根结底还是数据就是了,在这里面进行扩展,实现determiniCurrentlookupKey,也就是获取当前需要使用数据源的key值,在父类方法中有一个map,用来保存key值与数据源的对应关系,而key值是与当前线程相关的,DbcontextHolder代码见下

  1. package com.zhangshuo.common.dataSource;
    import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
    /**
    * Created by Administrator on 2017/5/31 0031.
    */
    publicclassDynamicDataSourceextendsAbstractRoutingDataSource{
    /**
    * 取得当前使用哪个数据源
    *
    * @return
    */
    @Override
    protectedObject determineCurrentLookupKey(){
    returnDbContextHolder.getDbType();
    }
    }

定义DbContextHolder

里面包含静态方法,用来设置或获取线程相关的数据源别名

  1. publicclassDbContextHolder{
    privatestaticfinalThreadLocal<String> contextHolder =newThreadLocal<>();
    /**
    * 设置数据源
    *
    * @param dbTypeEnum
    */
    publicstaticvoid setDbType(DBTypeEnum dbTypeEnum){
    contextHolder.set(dbTypeEnum.getValue());
    }
    /**
    * 取得当前数据源
    *
    * @return
    */
    publicstaticString getDbType(){
    return contextHolder.get();
    }
    /**
    * 清除上下文数据
    */
    publicstaticvoid clearDbType(){
    contextHolder.remove();
    }
    }

定义数据源枚举类

简化设置线程相关数据源名称的记忆压力;直接从所有的数据源的枚举中去选就可以了~

  1. publicenumDBTypeEnum{
    datasource1("datasource1"), datasource2("datasource2");
    privateString value;
    DBTypeEnum(String value){
    this.value = value;
    }
    publicString getValue(){
    return value;
    }
    }

生成 dataource 对象及 mp需要的对象

resources/application.properties的配置

在这里定义的属性名要与DruidDataSource和 SqlSessionFactory中需要的属性相同,使用ConfigurationProperties注解来减少代码

  1. datasource1:
    username: root
    password: 123456
    filters: mergeStat,wall,logback
    initialSize: 5
    maxActive: 50
    minIdle: 5
    maxWait: 6000
    validationQuery: SELECT 'x'
    testOnBorrow: true
    testOnReturn: true
    testWhileIdle: true
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    removeAbandoned: true
    removeAbandonedTimeout: 1800
    logAbandoned: true
    url: jdbc:mysql://192.168.168.118:3306/test?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&useSSL=false mybatis-plus1:
    # 数据源名称
    datasource: datasource1
    # mapper配置路径
    mapperLocations:
    classpath:/mapper/test1/*.xml
    # mybatis配置路径
    configLocation: classpath:/mybatis-config.xml
    # entity的包
    typeAliasesPackage: com.zhangshuo/test1/entity
    # 全局配置
    globalConfiguration:
    # id生成策略 0 自增 1 用户输入
    idType: 0
    # 灵据数类型
    dbType: mysql
    # 字段是否为下划线格式
    dbColumnUnderline: false datasource2:
    username: root
    password: 123456
    filters: mergeStat,wall,logback
    initialSize: 5
    maxActive: 50
    minIdle: 5
    maxWait: 6000
    validationQuery: SELECT 'x'
    testOnBorrow: true
    testOnReturn: true
    testWhileIdle: true
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    removeAbandoned: true
    removeAbandonedTimeout: 1800
    logAbandoned: true
    url: jdbc:mysql://192.168.168.118:3306/sms?useUnicode=true&characterEncoding=utf-8 mybatis-plus2:
    # 数据源名称
    datasource: datasource2
    # mapper配置路径
    mapperLocations:
    classpath:/mapper/test2/*.xml
    # mybatis配置路径
    configLocation:
    # entity的包
    typeAliasesPackage: com.zhangshuo/test2/entity
    # 全局配置
    globalConfiguration:
    # id生成策略 0 自增 1 用户输入
    idType: 0
    # 灵据数类型
    dbType: mysql
    # 字段是否为下划线格式
    dbColumnUnderline: false

生成相应对象

  1. import com.alibaba.druid.pool.DruidDataSource;
    import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
    import com.zhangshuo.common.dataSource.DynamicDataSource;
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.boot.context.properties.ConfigurationPropertiesBinding;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    import javax.sql.DataSource;
    import java.util.Map;
    import java.sql.SQLException;
    import java.util.HashMap;
    /**
    * Created by Administrator on 2017/5/31 0031.
    */
    @Configuration
    @MapperScan(value ={"com.zhangshuo.test1.mapper","com.zhangshuo.test2.mapper"})
    publicclassDataSourceConfig{
    @ConfigurationProperties(prefix ="datasource1")
    @Bean(name ="datasource1")
    // @Primary
    /**
    * 在方法上注解configurationProperties时,将会把属性注入到返回结果的bean中
    */
    publicDruidDataSource dataSource1()throwsSQLException{
    returnnewDruidDataSource();
    }
    @ConfigurationProperties(prefix ="datasource2")
    @Bean(name ="datasource2")
    /**
    * 在方法上注解configurationProperties时,将会把属性注入到返回结果的bean中
    */
    publicDruidDataSource dataSource2()throwsSQLException{
    returnnewDruidDataSource();
    }
    @Bean(name ="datasource")
    @Primary
    publicDynamicDataSource dynamicDataSource(@Qualifier(value ="datasource1")DataSource dataSource1,@Qualifier(value ="datasource2")DataSource dataSource2){
    DynamicDataSource bean =newDynamicDataSource();
    Map<Object,Object> targetDataSources =newHashMap<>();
    targetDataSources.put("datasource1",dataSource1);
    targetDataSources.put("datasource2", dataSource2);
    bean.setTargetDataSources(targetDataSources);
    bean.setDefaultTargetDataSource(dataSource1);
    return bean;
    }
    @Bean(name ="sessionFactory1")
    @ConfigurationProperties(prefix ="mybatis-plus1")
    @ConfigurationPropertiesBinding()
    @Primary
    publicMybatisSqlSessionFactoryBean sqlSessionFactory1(@Qualifier(value ="datasource")DataSource dataSource){
    MybatisSqlSessionFactoryBean bean =newMybatisSqlSessionFactoryBean();
    bean.setDataSource(dataSource);
    return bean;
    }
    @Bean(name ="sessionFactory2")
    @ConfigurationProperties(prefix ="mybatis-plus2")
    @ConfigurationPropertiesBinding()
    publicMybatisSqlSessionFactoryBean sqlSessionFactory2(@Qualifier(value ="datasource")DataSource dataSource){
    MybatisSqlSessionFactoryBean bean =newMybatisSqlSessionFactoryBean();
    bean.setDataSource(dataSource);
    return bean;
    }
    }

设置AOP用来自动切换数据源

在这里说明下我的目录结构:
com.zhangshuo.test1.controller/service/mapper
com.zhangshuo.test2.controller/service/mapper

设置AOP

在dao层进行切换

  1. import com.zhangshuo.common.dataSource.DBTypeEnum;
    import com.zhangshuo.common.dataSource.DbContextHolder;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    /**
    * Created by Administrator on 2017/5/31 0031.
    * 以dao层进行切换
    */
    @Component
    @Aspect
    publicclassDataSourceInterceptor{
    Logger logger =LoggerFactory.getLogger(DataSourceInterceptor.class);
    @Pointcut(value ="execution(public * com.zhangshuo.test1.mapper.**.*(..))")
    privatevoid datasource1ServicePointcut(){};
    @Pointcut(value ="execution(public * com.zhangshuo.test2.mapper.**.*(..))")
    privatevoid datasource2ServicePointcut(){};
    /**
    * 切换数据源1
    */
    @Before("datasource1ServicePointcut()")
    publicvoid dataSource1Interceptor(){
    logger.debug("切换到数据源{}..............................","datasource1");
    DbContextHolder.setDbType(DBTypeEnum.datasource1);
    }
    /**
    * 切换数据源2
    */
    @Before("datasource2ServicePointcut()")
    publicvoid dataSource2Interceptor(){
    logger.debug("切换到数据源{}.......................","datasource2");
    DbContextHolder.setDbType(DBTypeEnum.datasource2);
    }
    }

到这里就可以进行测试了;
顺带贴下mybatis-plus的分页插件,我是定义到了mybatis-config.xml中,也可以手动在sqlSessionfacotry中的setPlugins中()定义;

  1. <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration
    PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN"
    "http://ibatis.apache.org/dtd/ibatis-3-config.dtd"> <configuration>
    <settings>
    <setting name="cacheEnabled" value="false"/>
    <setting name="lazyLoadingEnabled" value="false"/>
    <setting name="aggressiveLazyLoading" value="true"/>
    <setting name="logImpl" value="slf4j"/>
    </settings>
    <plugins>
    <plugin interceptor="com.baomidou.mybatisplus.plugins.PaginationInterceptor">
    <property name="dialectType" value="mysql" />
    <property name="optimizeType" value="aliDruid" />
    </plugin>
    </plugins>
    </configuration>

spring boot 中 Mybatis plus 多数据源的配置方法的更多相关文章

  1. 【spring boot】【mybatis】spring boot中mybatis打印sql语句

    spring boot中mybatis打印sql语句,怎么打印出来?[参考:https://www.cnblogs.com/sxdcgaq8080/p/9100178.html] 在applicati ...

  2. Spring Boot 实战 —— MyBatis(注解版)使用方法

    原文链接: Spring Boot 实战 -- MyBatis(注解版)使用方法 简介 MyBatis 官网 是这么介绍它自己的: MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过 ...

  3. spring boot + druid + mybatis + atomikos 多数据源配置 并支持分布式事务

    文章目录 一.综述 1.1 项目说明 1.2 项目结构 二.配置多数据源并支持分布式事务 2.1 导入基本依赖 2.2 在yml中配置多数据源信息 2.3 进行多数据源的配置 三.整合结果测试 3.1 ...

  4. Spring Boot中的Mongodb多数据源扩展

    在日常工作中,我们通过Spring Data Mongodb来操作Mongodb数据库,在Spring Boot中只需要引入spring-boot-starter-data-mongodb即可. 然后 ...

  5. 太妙了!Spring boot 整合 Mybatis Druid,还能配置监控?

    Spring boot 整合 Mybatis Druid并配置监控 添加依赖 <!--druid--> <dependency> <groupId>com.alib ...

  6. 徒手撸一个 Spring Boot 中的 Starter ,解密自动化配置黑魔法!

    我们使用 Spring Boot,基本上都是沉醉在它 Stater 的方便之中.Starter 为我们带来了众多的自动化配置,有了这些自动化配置,我们可以不费吹灰之力就能搭建一个生产级开发环境,有的小 ...

  7. Spring Boot中实现logback多环境日志配置

    在Spring Boot中,可以在logback.xml中的springProfile标签中定义多个环境logback.xml: <springProfile name="produc ...

  8. 利用 Spring Boot 中的 @ConfigurationProperties,优雅绑定配置参数

    使用 @Value("${property}") 注释注入配置属性有时会很麻烦,尤其是当你使用多个属性或你的数据是分层的时候. Spring Boot 引入了一个可替换的方案 -- ...

  9. Spring Boot 集成 Mybatis 实现双数据源

    这里用到了Spring Boot + Mybatis + DynamicDataSource配置动态双数据源,可以动态切换数据源实现数据库的读写分离. 添加依赖 加入Mybatis启动器,这里添加了D ...

随机推荐

  1. Javascript 面向对象编程—继承和封装

      前  言 Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象.但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class(类) ...

  2. C语言第一次实验报告————PTA实验1.2.3内容

    一.PTA实验作业 题目1.温度转换 本题要求编写程序,计算华氏温度100°F对应的摄氏温度.计算公式:C=5×(F−32)/9,式中:C表示摄氏温度,F表示华氏温度,输出数据要求为整型. 1.实验代 ...

  3. win10 uwp 弹起键盘不隐藏界面元素

    本文主要讲,在我们使用手机输入的时候,会因为手机的虚拟键盘隐藏了一些界面的元素.我们有一个简单的方法让虚拟键盘不隐藏界面元素. 我们需要的界面元素是在显示了虚拟键盘后的空间能全部显示,如果不能的话,还 ...

  4. HTML之事件处理程序

    HTML事件 <body> <input type="button" value="按钮1" id="but1" oncl ...

  5. IntelliJ IDEA 2016.2激活

    激活码 43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0M0I0QTczWVlKIiwibGljZW5zZWVOYW1lIjoibGFuIHl1IiwiYXNzaWduZWVOYW1lI ...

  6. 基于webuploader.js的单图片上传封装

    HTML代码 <div class="manageImgUp">点击图片上传</div> <div class="manageImgUpLc ...

  7. JS框架设计读书笔记之-异步

    setTimeout/setInterval 1. 如果回调执行时间大于间隔时间,真正的间隔时间会大一些. 2. 存在一个最小的时间间隔,即使seTimeout(fn,0),在IE6-IE8中大概为1 ...

  8. Java调用C++类库--JNI

    JNI是Java平台中的一个重要的功能,这里我把我做的Demo总结一下,分享一下,我会把每个步骤尽量的详细的展现出来. 这里我就不讲解JNI的原理了,google,百度一下,到处都是 好了,直接来讲步 ...

  9. 操作系统--进程管理1--单个CPU情况

    1.进程概念 进程:一个正在执行的程序:操作系统提出进程概念目的:是为了跟踪程序在执行期间的状态.而程序只是一段代码,是一个静态的概念 无法准确描述程序执行时候发生的一切.程序代码被加载进内存后就以进 ...

  10. webservice wsdl语法基础

    XML-WSDL基础知识 WSDL 1.1. WSDL 简介 1.1.1.    概述 WSDL 指网络服务描述语言 (Web Services Description Language) WSDL ...