本文阐述使用多数据源的额场景,以及如何使用springboot的配置多数据源。

关于后者,主要是直接引用其它博文:https://blog.csdn.net/u012060033/article/details/123759694

如果不想了解不太必要知道的,建议查看 https://www.cnblogs.com/chen-msg/p/7485701.html

一、多数据源的使用场景

使用多数据源的原因一般有:

  1. 数据采集
  2. 分库
  3. 其它

本文主要讨论的是分库问题。现在讨论的一般所谓“分库”是主要因为两个目的:

  1. 实现多租户
  2. 数据的水平分割,以便增加数据吞吐能力
  3. 读写分离

实现多租户

在某些前提下,通过分库来实现多租户也是可以,例如不想浪费应用服务器的资源,减少维护的压力。

但这个行为,本人并不是很认可。因为当你的客户没有多少数据量的时候,分库分表其实没有太大意义。

如果客户的数据很多,那么客户应该给出更多的钱,这种情况下也没有必要和其它客户共享一个硬件资源。

至于业界一直鼓吹的SAAS,云之类的,大部分业务场景下,对于大公司并没有特别的吸引力。因为财大气粗,这个时候他们主要考虑一个问题:数据安全性。

大一点的公司也是这个思路。例如字节自己建立数据中心,也是类似的心思:安全,不想受制于人等等。

所以,现今国内大公司更多的做法是:自己采购服务器,自己组建it团队。和其它公司共享一个别的公司运营的云平台,把关键的商务数据放上去,不太可能的。

读写分离

这个建议直接使用数据库自身的功能了。但如果的确有某些不得不用的理由,也是可以的。

不过项目做多了,总是有一些特别的要求,所以本章节不再讨论要不要使用多数据源。

二、配置多数据源

2.1配置多数据源所需要面临的几个问题

  • 如果有ocrm等和数据源有关的组件,那么这些组件内部如何切换
  • 多个数据源之间的事务一致性如何处理(如果它们有关系的话)
  • 切换数据源的成本如何降低一些,即如何使用更少的资源和更少的计算能力来进行切换

如何保持事务一致性的话题内容太多,此处略过。

所以剩下的主要关心问题就是如何切换。

如果是mybatis或者mybatis-plus等orm还是相对友好的--因为是现成的。如果是自己编写的ocrm框架,那么需要稍微花费一些心思。

2.2一般的实现方式

spring本身支持多数据源的配置,所以难度上并没有什么。对于设计人员而言,主要工作是慎重选择实现的方式。

spring的方式步骤:

  1. 定义个数据源
  2. 定义数据源有关的bean对象:datasource,jdbcTemplate,事务管理器等等

其它变化都是基于以上基础实现的。

以下文章讲解的比较清楚:https://www.cnblogs.com/chen-msg/p/7485701.html

三、例子

例子上按照https://www.cnblogs.com/chen-msg/p/7485701.html来编写。

运行环境:windows11 ,mysql8.0.x,springboot 2.6.7

3.1 application.properties

spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.autoCommit=false
spring.datasource.hikari.connectionTimeout=180000
spring.datasource.hikari.idleTimeout=600000
spring.datasource.hikari.maxLifetime=1800000
spring.datasource.hikari.minimumIdle=3
spring.datasource.hikari.maximumPoolSize=6
spring.datasource.hikari.connection-test-query=select 1 #多数据源演示
spring.datasource.school.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.school.jdbcUrl=jdbc:mysql://localhost:7799/spring?rewriteBatchedStatements=true&autoReconnect=true&allowMultiQueries=true&useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.school.username=spring
spring.datasource.school.password=123 spring.datasource.factory.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.factory.jdbcUrl=jdbc:mysql://localhost:7799/factory?rewriteBatchedStatements=true&autoReconnect=true&allowMultiQueries=true&useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.factory.username=spring
spring.datasource.factory.password=123

3.2 DataSourceConfig.java --配置数据源

package com.example.multids.config;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager; @Configuration
public class DataSourceConfig {
@Bean(name = "factoryDataSource")
@Qualifier("factoryDataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.factory")
public DataSource factoryDataSource()
{
System.out.println("-------------------- factoryDataSource init ---------------------");
return DataSourceBuilder.create().build();
} @Bean(name = "schoolDataSource")
@Qualifier("schoolDataSource")
@ConfigurationProperties(prefix = "spring.datasource.school")
public DataSource schoolDataSource()
{
System.out.println("-------------------- schoolDataSource init ---------------------");
return DataSourceBuilder.create().build();
} @Bean(name = "schoolJdbcTemplate")
@Qualifier("schoolJdbcTemplate")
public JdbcTemplate schoolJdbcTemplate(@Qualifier("schoolDataSource") DataSource dataSource)
{
return new JdbcTemplate(dataSource);
} @Bean(name = "factoryJdbcTemplate")
@Qualifier("factoryJdbcTemplate")
public JdbcTemplate factoryJdbcTemplate(@Qualifier("factoryDataSource") DataSource dataSource)
{
return new JdbcTemplate(dataSource);
} /******配置事务管理********/ @Bean
public PlatformTransactionManager schoolTransactionManager(@Qualifier("schoolDataSource")DataSource ds) {
return new DataSourceTransactionManager(ds);
} @Bean
public PlatformTransactionManager factoryTransactionManager(@Qualifier("factoryDataSource")DataSource ds) {
return new DataSourceTransactionManager(ds);
}
}

3.3 SqlController- 测试控制器

package com.example.multids.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; @RestController
@RequestMapping(value = "/multids")
public class SqlController { @Qualifier("schoolJdbcTemplate")
@Autowired
private JdbcTemplate jdbcTp; @Qualifier("factoryJdbcTemplate")
@Autowired
private JdbcTemplate factoryJdbcTp; @RequestMapping(value = "getAll", method = { RequestMethod.GET, RequestMethod.POST })
public Object getAll() {
String sql = "select * from student limit 2";
List<Map<String, Object>> studentList = jdbcTp.queryForList(sql);
String inventorySql = "select * from inventory limit 2";
List<Map<String, Object>> inventoryList = factoryJdbcTp.queryForList(inventorySql);
Map<String, Object> result = new HashMap<>();
result.put("student-spring-ds", studentList);
result.put("inventory-factory-ds", inventoryList);
return result;
}
}

3.4 测试结果

浏览器执行结果:http://localhost:8081/multids/getAll

四、小结

总体而言,配置还是比较简单。

spring多数据源配置笔记的更多相关文章

  1. 基于xml的Spring多数据源配置和使用

    上一篇讲了<基于注解的Spring多数据源配置和使用>,通过在类或者方法上添加@DataSource注解就可以指定某个数据源.这种方式的优点是控制粒度细,也更灵活. 但是当有些时候项目分模 ...

  2. spring BasicDataSource 数据源配置 sqlserver数据库 oracle数据库 mysql数据jdbc配置

    spring BasicDataSource 数据源配置 sqlserver数据库 oracle数据库 mysql数据jdbc配置 jdbc.properties 文件信息如下: ---------- ...

  3. 基于注解的Spring多数据源配置和使用(非事务)

    原文:基于注解的Spring多数据源配置和使用 1.创建DynamicDataSource类,继承AbstractRoutingDataSource package com.rps.dataSourc ...

  4. spring(16)------spring的数据源配置

    在spring中,通过XML的形式实现数据源的注入有三种形式. 一.使用spring自带的DriverManagerDataSource 使用DriverManagerDataSource配置数据源与 ...

  5. 基于注解的Spring多数据源配置和使用

    前一段时间研究了一下spring多数据源的配置和使用,为了后期从多个数据源拉取数据定时进行数据分析和报表统计做准备.由于之前做过的项目都是单数据源的,没有遇到这种场景,所以也一直没有去了解过如何配置多 ...

  6. Spring jndi数据源配置方法

    xml配置: <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverMana ...

  7. spring 多数据源配置

    多数据源配置方法: 在配置数据源配置文件中多加一个数据源配置即可: <bean id="dataSource" class="org.apache.commons. ...

  8. Spring 多数据源配置(转)

    转载自:https://www.cnblogs.com/digdeep/p/4512368.html 同一个项目有时会涉及到多个数据库,也就是多数据源.多数据源又可以分为两种情况: 1)两个或多个数据 ...

  9. Spring boot 数据源配置。

    配置文件 : spring boot  配置文件 有两种形式 ,一种是properties文件.一种是yml文件.案列使用properties文件. 数据源的默认配置 : spring boot 约定 ...

  10. spring多数据源配置

    项目中我们经常会遇到多数据源的问题,尤其是数据同步或定时任务等项目更是如此.多数据源让人最头痛的,不是配置多个数据源,而是如何能灵活动态的切换数据源.例如在一个spring和hibernate的框架的 ...

随机推荐

  1. dotnet 警惕 Assembly.Location 返回空

    在大部分情况下,获取当前所运行的应用程序的所在路径时,常用的就是 Assembly.Location 属性,按照之前的经验,使用 Assembly.Location 是最为稳定的做法,然而在 dotn ...

  2. WPF 对接 Vortice 调用 D2D 使用 IWICBitmap 离屏渲染

    通过 Vortice 库可以使用非常底层的方式调用到 Direct2D1 进行渲染,本文将使用 D2D 离屏渲染到 IWICBitmap 上,再使用一点点反射黑科技,直接将此 IWICBitmap 对 ...

  3. 2018-2-13-win10-uwp-修改CalendarDatePicker图标颜色

    title author date CreateTime categories win10 uwp 修改CalendarDatePicker图标颜色 lindexi 2018-2-13 17:23:3 ...

  4. 关于Git和Svn的区别

    关于Git 和 Svn 的选用,详细列出区别 Git 是分布式的,而 Svn 不是分布的; Git 把内容按元数据方式存储,而 SVN 是按文件; Git 没有一个全局版本号,而 SVN 有:目前为止 ...

  5. Jenkins 简述及其搭建

    什么是持续集成? 持续集成(CI)是在软件开发过程中自动化和集成许多团队成员的代码更改和更新的过程.在 CI 中,自动化工具在集成之前确认软件代码是有效且无错误的,这有助于检测错误并加快新版本的发布. ...

  6. vue.js+canvas实现随机验证码

    登录注册啥的,不需要下载插件,上图: 代码: <template> <div class="about"> <p>当前验证码:{{codeStr ...

  7. 我第一个开源AI小产品-video2blog即将正式发布

    前言 首先它是为了解决我自己的个人问题.不管能不能帮到你,或者对于看到的你是否有点利用价值,也没太大的关系,最起码你可以来看看我开发小产品的整个过程. 一段时间以来,我开始通过youtube平台来获取 ...

  8. Spark中的闭包引用和广播变量

    闭包引用 概念 所有编程语言都有闭包的概念,闭包就是在一个函数中引用了函数外的变量. Spark中,普通的变量是在Driver程序中创建的,RDD的计算是在分布式集群中的task程序上进行的.因此,当 ...

  9. Linux定时任务实现每秒执行一次

    编写/root/test.sh脚本 该方法适用于调度周期能被60整除的情况 #!/bin/bash step=1 for (( i = 0; i < 60; i = (i+step) )); d ...

  10. 1分钟了解什么是SQL聚合函数,一看就懂,一学就会!(AVG(column_name)\COUNT(column_name)\MAX(column_name)\MIN(column_name)\SUM(column_name))

    聚集函数:SQL基本函数,聚集函数对一组值执行计算,并返回单个值,也被称为组函数.聚集函数经常与SELECT语句的GROUP BY子句的HAVING一同使用.但是不可用于WHERE语句中,因为WHER ...