• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Spring Boot多数据源切换查询

武飞扬头像
唯有努力不欺人丶
帮助1

今天遇到一个场景,公司的消息因为过多。所以做成了分库的情况。一个月内的数据存在当前表中。一个月之前的数据存放在备份表中。然后把主库和备份库做成多数据源的形式。在查询的时候如果主库表中没有就去备份库中查询。
其实说起来好像挺高端的。但是实现上很简单,下面是具体的实现。

数据源配置

导包,基本项目架构啥的我就不多说了。直接上配置文件。我这里是用yml的形式:

spring:
  datasource:
    # Druid数据库连接池
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:clickhouse://xxx:8123/test
    driverClassName: com.clickhouse.jdbc.ClickHouseDriver
    druid:
      first:  # 数据源1
        # 数据库驱动
        driver-class-name: com.clickhouse.jdbc.ClickHouseDriver
        url: jdbc:clickhouse://xxx:8123/test
        username: default
        password: default
      second:  # 数据源2
        # 数据库驱动
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://xxx:3306/test?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone= GMT+8
        username: root
        password: 123456
      third:  # 数据源3
        # 数据库驱动
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://xxx:3306/test?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone= GMT+8
        username: root
        password: 123456
      fourth:  # 数据源3
        # 数据库驱动
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://XXX:3306/test_b?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false
        username: root
        password: 123456
      initial-size: 10
      max-active: 100
      min-idle: 10
      max-wait: 60000

这里所有关于数据库地址和名称我都隐藏了,要根据具体的情况配置。但是如图所示,我们这里配置了四个数据源。第一个是个clickhouse数据库,二三四都是mysql。其中第三个是我说到的消息的主库,第四个是我说的消息的历史库。

sql配置

    @DataSource(name = DataSourceNames.THIRD)
    Integer if_exist(Map<String, Object> params);

    @DataSource(name = DataSourceNames.FOURTH)
    Integer if_exist_archive(Map<String, Object> params);

    @DataSource(name = DataSourceNames.THIRD)
    Map<String, Object> preview(Map<String, Object> params);

    @DataSource(name = DataSourceNames.FOURTH)
    Map<String, Object> preview_archive(Map<String, Object> params);

注意看上面的代码,第一个方法if_exist 指定的是第三个数据源,我上面说过是消息表的主库。if_exist_archive指定的是第四个数据源,也就是消息表的历史库。
同理下面的两个查询数据的方法一个是主库查询,一个是历史库查询。
sql其实就是很无脑的一个判断是否存在,一个查询数据。

    <select id="if_exist" parameterType="map" resultType="int">
        SELECT EXISTS(SELECT 1
        FROM msg AS b
        WHERE FileName = #{filename}
        LIMIT 1)
    </select>

    <select id="if_exist_archive" parameterType="map" resultType="int">
        SELECT EXISTS(SELECT 1
        FROM msg AS b
        WHERE FileName = #{filename}
        LIMIT 1)
    </select>

    <select id="preview" parameterType="map" resultType="map">
        SELECT
            uncompress(b.Message) AS Message
        FROM msg AS b
        WHERE FileName = #{filename}
        LIMIT 1
    </select>
    
    <select id="preview_archive" parameterType="map" resultType="map">
        SELECT
        uncompress(b.Message) AS Message
        FROM msg AS b
        WHERE FileName = #{filename}
        LIMIT 1
    </select>

代码维护切换数据库

上面我们数据源,sql都配置好了。接下来就是代码维护了。理论上就是主库查不到就去历史库查询,使用方法如下:

        Map<String, Object> result;

        if (msgDao.if_exist(params) > 0) {
            result = msgDao.preview(params);
        } else {
            result = msgDao.preview_archive(params);
        };

就这么几行代码就实现了这个功能。

结语

其实这个功能我感觉是会则不难,难则不会。
看到了人家的做法之后恍然大悟,觉得简单的很。可是在这之前我是没有这种类似的想法的。甚至说之前的做法都局限于一个数据库,最多就是分表而已。写起来也没这么简单。两张表需要两个entity和Dao甚至xml。总而言之又学到了一种用法,还是挺开心的。
本篇笔记就记到这里,如果稍微帮到你了记得点个喜欢点个关注,也祝大家工作顺顺利利,每天学习一点点~

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgkeffa
系列文章
更多 icon
同类精品
更多 icon
继续加载