springboot2+mybatis多种方式实现多数据配置方法

业务系统复杂程度增加,为了解决数据库I/O瓶颈,很自然会进行拆库拆表分服务来应对。这就会出现一个系统中可能会访问多处数据库,需要配置多个数据源。

第一种场景:项目服务从其它多处数据库取基础数据进行业务处理,因此各库之间不会出现重表等情况。

第二种场景:为了减轻写入压力进行读写分库,读走从库,写为主库。此种表名等信息皆为一致。

第三种场景:以上两种皆有。对于某些业务需要大数据量的汇总统计,希望不影响正常业务必须走从库(表信息一致),某些配置信息不存在读写压力,出现不分库(表信息不一致)

项目源代码:

https://github.com/zzsong/springboot-multiple-datasource.git

有三个目录:

one:
    直接使用多@Bean配置,@MapperScan来路径区分读何库

two:
    使用注解的方式来标识走何dataSource,AOP拦截注入动态数据源

third:
    使用spring的Bean命名策略进行区分数据来源

项目技术选型: springBoot2.2.5 + mybatis + druid + mysql

先看主要的pom包

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.5.RELEASE</version>
    <relativePath/>
  </parent>

        <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jdbc</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jdbc</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    <dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>2.1.2</version>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.19</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid-spring-boot-starter</artifactId>
      <version>1.1.21</version>
    </dependency>

application.yml

spring:
 datasource:
  druid:
   core:
    url: jdbc:mysql:///kc_core?characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
   schedule:
    url: jdbc:mysql:///kc_schedule?characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

mysql新版本必须带有serverTimezone,不然会报连接异常。

第一种:通过@MapperScans 扫描匹配相关的数据源

@Configuration
@MapperScans({
    @MapperScan(basePackages = "com.zss.one.mapper.core", sqlSessionTemplateRef = "coreSqlSessionTemplate",sqlSessionFactoryRef = "coreSqlSessionFactory"),
    @MapperScan(basePackages = "com.zss.one.mapper.schedule", sqlSessionTemplateRef = "scheduleSqlSessionTemplate",sqlSessionFactoryRef = "scheduleSqlSessionFactory")
})
public class MybatisOneConfig {

  @Bean
  @ConfigurationProperties(prefix = "spring.datasource.druid.core")
  public DataSource coreDataSource(){
    return DruidDataSourceBuilder.create().build();
  }

  @Bean
  public SqlSessionFactory coreSqlSessionFactory(@Qualifier("coreDataSource") DataSource coreDataSource) throws Exception {
    SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
    sessionFactory.setDataSource(coreDataSource);
    sessionFactory.getObject().getConfiguration().setJdbcTypeForNull(null);
    sessionFactory.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
    return sessionFactory.getObject();
  }

  @Bean
  public SqlSessionTemplate coreSqlSessionTemplate(@Qualifier("coreSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
    return new SqlSessionTemplate(sqlSessionFactory);
  }

  //======schedule========
  @Bean
  @ConfigurationProperties(prefix = "spring.datasource.druid.schedule")
  public DataSource scheduleDataSource(){
    return DruidDataSourceBuilder.create().build();
  }

  @Bean
  public SqlSessionFactory scheduleSqlSessionFactory(@Qualifier("scheduleDataSource") DataSource coreDataSource) throws Exception {
    SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
    sessionFactory.setDataSource(coreDataSource);
    sessionFactory.getObject().getConfiguration().setJdbcTypeForNull(null);
    sessionFactory.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
    return sessionFactory.getObject();
  }

  @Bean
  public SqlSessionTemplate scheduleSqlSessionTemplate(@Qualifier("scheduleSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
    return new SqlSessionTemplate(sqlSessionFactory);
  }
}

第二种是动态数据源模式,通过AOP切入注解引导使用何数据源。用自定义注解@interface来标识方法走对应的数据源。

注意事项:类中的方法再调用带数据源的方法,不能被AOP切入

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TargetDataSource {
  String value();
}

extends spring的动态DataSource路由来匹配

public class DynamicDataSource extends AbstractRoutingDataSource {

  @Override
  protected Object determineCurrentLookupKey() {
    return DataSourceContextRouting.getDataSourceName();
  }
}
@Configuration
//@EnableConfigurationProperties(MybatisProperties.class)//不要使用此公共配置,Configuration会破坏相关dataSource的配置
@MapperScan("com.zss.two.mapper")
public class MybatisConfig {

  @Bean
  @ConfigurationProperties(prefix = "spring.datasource.druid.core")
  public DataSource coreDataSource() {
    return DruidDataSourceBuilder.create().build();
  }

  @Bean
  @ConfigurationProperties(prefix = "spring.datasource.druid.schedule")
  public DataSource scheduleDataSource() {
    return DruidDataSourceBuilder.create().build();
  }

  @Autowired
  @Qualifier("coreDataSource")
  private DataSource coreDataSource;

  @Autowired
  @Qualifier("scheduleDataSource")
  private DataSource scheduleDataSource;

  @Bean
  public DynamicDataSource dataSource() {
    Map<Object, Object> targetDataSources = new HashMap<>();
    targetDataSources.put(DataSourceConstants.CORE_DATA_SOURCE, coreDataSource);
    targetDataSources.put(DataSourceConstants.SCHEDULE_DATA_SOURCE, scheduleDataSource);

    DynamicDataSource dataSource = new DynamicDataSource();

    //设置数据源映射
    dataSource.setTargetDataSources(targetDataSources);
////    设置默认数据源,当无法映射到数据源时会使用默认数据源
    dataSource.setDefaultTargetDataSource(coreDataSource);
    dataSource.afterPropertiesSet();
    return dataSource;
  }
  /**
   * 根据数据源创建SqlSessionFactory
   */
  @Bean
  public SqlSessionFactory sqlSessionFactory(DynamicDataSource dataSource) throws Exception {
    SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
    sessionFactory.setDataSource(dataSource);
    sessionFactory.getObject().getConfiguration().setJdbcTypeForNull(null);
    sessionFactory.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
    return sessionFactory.getObject();
  }

  @Bean
  public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) throws Exception {
    return new SqlSessionTemplate(sqlSessionFactory);
  }

第三种,自定义Bean命名策略,按beanName进行自动匹配使用数据源

@Component
public class CoreBeanNameGenerator implements BeanNameGenerator {
  @Override
  public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
    return "core"+ ClassUtils.getShortName(definition.getBeanClassName());
  }
}

@Component
public class ScheduleBeanNameGenerator implements BeanNameGenerator {
  @Override
  public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
    return "schedule"+ ClassUtils.getShortName(definition.getBeanClassName());
  }
}

使用mybatis MapperScannerConfigurer自动扫描,将Mapper接口生成注入到spring

  @Bean
  public MapperScannerConfigurer coreMapperScannerConfig(CoreBeanNameGenerator coreBeanNameGenerator){
    MapperScannerConfigurer configurer = new MapperScannerConfigurer();
    configurer.setNameGenerator(coreBeanNameGenerator);
    configurer.setBasePackage("com.zss.third.mapper.core,com.zss.third.mapper.order");
    configurer.setSqlSessionFactoryBeanName("coreSqlSessionFactory");
    configurer.setSqlSessionTemplateBeanName("coreSqlSessionTemplate");
    return configurer;
  }

  @Bean
  public MapperScannerConfigurer scheduleMapperScannerConfig(ScheduleBeanNameGenerator scheduleBeanNameGenerator){
    MapperScannerConfigurer configurer = new MapperScannerConfigurer();
    configurer.setNameGenerator(scheduleBeanNameGenerator);
    configurer.setBasePackage("com.zss.third.mapper.schedule,com.zss.third.mapper.order");
    configurer.setSqlSessionFactoryBeanName("scheduleSqlSessionFactory");
    configurer.setSqlSessionTemplateBeanName("scheduleSqlSessionTemplate");
    return configurer;
  }

到此,三种多数据源匹配主要点介绍完,详细直接下载github项目。 在resources/db含有相关测试表及数据脚本。

到此这篇关于springboot2+mybatis多种方式实现多数据配置方法的文章就介绍到这了,更多相关springboot2+mybatis 多数据内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解SpringBoot和Mybatis配置多数据源

    目前业界操作数据库的框架一般是 Mybatis,但在很多业务场景下,我们需要在一个工程里配置多个数据源来实现业务逻辑.在SpringBoot中也可以实现多数据源并配合Mybatis框架编写xml文件来执行SQL.在SpringBoot中,配置多数据源的方式十分便捷, 下面开始上代码: 在pom.xml文件中需要添加一些依赖 <!-- Spring Boot Mybatis 依赖 --> <dependency> <groupId>org.mybatis.spring.b

  • spring boot mybatis多数据源解决方案过程解析

    在我们的项目中不免会遇到需要在一个项目中使用多个数据源的问题,像我在得到一个任务将用户的聊天记录进行迁移的时候,就是用到了三个数据源,当时使用的AOP的编程方式根据访问的方法的不同进行动态的切换数据源,觉得性能不太好,先在又新用到了一种使用方式,觉得不错,记录下来. 介绍一下DEMO项目,使用的spring boot集成mybatis,mybatis查询数据库是基于注解形式查询的,目的查询两个数据库test1和test2的用户信息,并在控制台打印. 1.pom文件 <dependencies>

  • springboot + mybatis配置多数据源示例

    在实际开发中,我们一个项目可能会用到多个数据库,通常一个数据库对应一个数据源. 代码结构: 简要原理: 1)DatabaseType列出所有的数据源的key---key 2)DatabaseContextHolder是一个线程安全的DatabaseType容器,并提供了向其中设置和获取DatabaseType的方法 3)DynamicDataSource继承AbstractRoutingDataSource并重写其中的方法determineCurrentLookupKey(),在该方法中使用Da

  • 详解springboot+mybatis多数据源最简解决方案

    说起多数据源,一般都来解决那些问题呢,主从模式或者业务比较复杂需要连接不同的分库来支持业务.我们项目是后者的模式,网上找了很多,大都是根据jpa来做多数据源解决方案,要不就是老的spring多数据源解决方案,还有的是利用aop动态切换,感觉有点小复杂,其实我只是想找一个简单的多数据支持而已,折腾了两个小时整理出来,供大家参考. 废话不多说直接上代码吧 配置文件 pom包就不贴了比较简单该依赖的就依赖,主要是数据库这边的配置: mybatis.config-locations=classpath:

  • Spring Boot 整合mybatis 使用多数据源的实现方法

    前言 本篇教程偏向实战,程序猿直接copy代码加入到自己的项目中做简单的修修改改便可使用,而对于springboot以及mybatis不在此进行展开介绍,如有读者希望了解可以给我留言,并持续关注,我后续会慢慢更新.(黑色区域代码部分,安卓手机可手动向左滑动,来查看全部代码) 整合 其实整合很简单,如果是用gradle的话,在build.gradle文件里加入 compile('org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.1')

  • 详解Spring Boot整合Mybatis实现 Druid多数据源配置

    一.多数据源的应用场景 目前,业界流行的数据操作框架是 Mybatis,那 Druid 是什么呢? Druid 是 Java 的数据库连接池组件.Druid 能够提供强大的监控和扩展功能.比如可以监控 SQL ,在监控业务可以查询慢查询 SQL 列表等.Druid 核心主要包括三部分: 1. DruidDriver 代理 Driver,能够提供基于 Filter-Chain 模式的插件体系. 2. DruidDataSource 高效可管理的数据库连接池 3. SQLParser 当业务数据量达

  • spring boot+mybatis 多数据源切换(实例讲解)

    由于公司业务划分了多个数据库,开发一个项目会同事调用多个库,经过学习我们采用了注解+aop的方式实现的 1.首先定义一个注解类 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface TargetDataSource { String value();//此处接收的是数据源的名称 } 2.然后建一个配置类,这个在项目启动时会加载数据源,一开始采用了HikariCP,查资料说是最快性能最好的

  • Spring Boot 集成Mybatis实现主从(多数据源)分离方案示例

    本文将介绍使用Spring Boot集成Mybatis并实现主从库分离的实现(同样适用于多数据源).延续之前的Spring Boot 集成MyBatis.项目还将集成分页插件PageHelper.通用Mapper以及Druid. 新建一个Maven项目,最终项目结构如下: 多数据源注入到sqlSessionFactory POM增加如下依赖: <!--JSON--> <dependency> <groupId>com.fasterxml.jackson.core<

  • Spring Boot + Mybatis多数据源和动态数据源配置方法

    网上的文章基本上都是只有多数据源或只有动态数据源,而最近的项目需要同时使用两种方式,记录一下配置方法供大家参考. 应用场景 项目需要同时连接两个不同的数据库A, B,并且它们都为主从架构,一台写库,多台读库. 多数据源 首先要将spring boot自带的DataSourceAutoConfiguration禁掉,因为它会读取application.properties文件的spring.datasource.*属性并自动配置单数据源.在@SpringBootApplication注解中添加ex

  • springboot2+mybatis多种方式实现多数据配置方法

    业务系统复杂程度增加,为了解决数据库I/O瓶颈,很自然会进行拆库拆表分服务来应对.这就会出现一个系统中可能会访问多处数据库,需要配置多个数据源. 第一种场景:项目服务从其它多处数据库取基础数据进行业务处理,因此各库之间不会出现重表等情况. 第二种场景:为了减轻写入压力进行读写分库,读走从库,写为主库.此种表名等信息皆为一致. 第三种场景:以上两种皆有.对于某些业务需要大数据量的汇总统计,希望不影响正常业务必须走从库(表信息一致),某些配置信息不存在读写压力,出现不分库(表信息不一致) 项目源代码

  • Oracle在Mybatis中SQL语句的配置方法

    数据库中有下划线的字段在实体中应采用驼峰命名法,如P_NAME对应pName,实例如下: 1.XML文件中SQL语句配置(Geteway.xml文件) <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-m

  • 允许phpmyadmin空密码登录的配置方法

    这是因为默认phpmyadmin空密码登录是被禁止的,如果想要phpmyadmin空密码允许登录,就需要修改phpmyadmin相关配置. 在phpmyadmin3安装配置图解教程一文中,我介绍了phpmyadmin的安装与配置,至于修改phpmyadmin登录密码的界面,我在Mysql修改root密码的命令及方法中已告知,如果想要允许phpmyadmin以空密码方式登录,就要修改libraries/config.default.php配置文件(如果你是以根目录下config.inc.php配安

  • ASP.NET Core中如何利用多种方式给Action传参

    前言 ASP.NET Core 是一个跨平台,开源的,轻量级,高性能 并且 高度模块化的web框架.在 ASP.NET Core MVC 中有很多种方式可以给 Action 方法传递参数,比如说:url方式,querystring方式,request header,request body,form 等等.本篇就和大家一起讨论下如何使用这些方式,并且用代码去一一验证. 创建 AuthorRepository 类 在这个例子中我会使用一个 Repository 类,然后在 Controller 下

  • 基于MyBatis XML配置方法(全面了解)

    MyBatis 的配置文件包含了影响 MyBatis 行为甚深的设置(settings)和属性(properties)信息. 文档的顶层结构如下: configuration 配置 properties 属性 settings 设置 typeAliases 类型命名 typeHandlers 类型处理器 objectFactory 对象工厂 plugins 插件 environments 环境 environment 环境变量 transactionManager 事务管理器 dataSourc

  • Spring Boot 与 mybatis配置方法

    1.首先,spring boot 配置mybatis需要的全部依赖如下: <!-- Spring Boot 启动父依赖 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> </

  • Mybatis分页插件PageHelper的配置和简单使用方法(推荐)

    前言 在web开发过程中涉及到表格时,例如dataTable,就会产生分页的需求,通常我们将分页方式分为两种:前端分页和后端分页. 前端分页 一次性请求数据表格中的所有记录(ajax),然后在前端缓存并且计算count和分页逻辑,一般前端组件(例如dataTable)会提供分页动作. 特点是:简单,很适合小规模的web平台:当数据量大的时候会产生性能问题,在查询和网络传输的时间会很长. 后端分页 在ajax请求中指定页码(pageNum)和每页的大小(pageSize),后端查询出当页的数据返回

  • 使用多种方式实现遍历HashMap的方法

    今天讲解的主要是使用多种方式来实现遍历HashMap取出Key和value,首先在java中如果想让一个集合能够用for增强来实现迭代,那么此接口或类必须实现Iterable接口,那么Iterable究竟是如何来实现迭代的,在这里将不做讲解,下面主要讲解一下遍历过程. //定义一个泛型集合 Map<String, String> map = new HashMap<String, String>(); //通过Map的put方法向集合中添加数据 map.put("001&

  • spring boot配置MySQL数据库连接、Hikari连接池和Mybatis的简单配置方法

    此方法为极简配置,支持MySQL数据库多库连接.支持Hikari连接池.支持MyBatis(包括Dao类和xml文件位置的配置). 1.pom.xml中引入依赖: <!-- Begin of DB related --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId>

随机推荐