• 来看下这篇文章,教你如何实现一个SpringBoot的Mybatis分库分表组件


    如何设计这个组件?

    在做这个组件之前,我想应该考滤如下几个问题

    • 我们不是对所有的插入的数据进行分库分表,我应该有一个标记来标记哪些插入的操作要进行分库分表。
    • 插入的数据应该分到哪张表?分库的时候我应该如何让数据更新散列的分到不同的表中。

    对于第一个问题,因为这个组件是做的一个Spring一个分库分表的组件,我们大可使用SpringAop的特性来解决这个问题,比如:我自定义一个注解,只要在Mybatis的接口上标记了这个注解,在通过Spring Aop完美解决,那么在插入的时候我就需要分库分表的操作。

    对于第二个问题,我可以采用Hash散列的方式来处理,在Java中的HashMap类中的put方法,我们完全可以借鉴这种思路。我想了解过HashMap源码的同鞋可能更加的清楚一些,在HashMap类中有一个hash的方扰动方法,这个方法中他把key的hash值进行了一个高半位和低半位的混合异或运算。这个便更好的增加随机性,更好的让数据均匀的散列。

    可以看下下面这张图在使用了扰动函数后,数据分配的更加的均匀,这个可以更好的减少了hash碰撞。所以在解决第二个问题的时候,我们可以把这种Hash散列运用到数据库路由上。

    代码实现

    那我们先来解决第一个问题。如何让程序知道,我们在某个数据库操作的时候需要进行分库分表,这里涉及到知识有自定义注解和Spring AOP相关的

    project
    └─src
    └─main
    ├─java
    │  └─com
    │      └─yqs
    │          └─db
    │              └─router
    │                  ├─annotation
    │                  ├─config
    │                  ├─dynamic
    │                  ├─strategy
    │                  │  └─impl
    │                  └─util
    └─resources
    └─META-INF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    先来大致的分下包:

    • annotation 这个包下就是和注解相关的一些文件
    • config starter的自动配置类
    • dynamic 数据源的切换相关
    • stategy 计算被分到哪个库那个表策略相关的(这里用到的策略模式,在扩展功能时也很方便)
    • util 一些工具包,这里后面再说

    注解讲解

    先来看下在自定义注解中用到的元注解

    • Retention 标记当前注解的生命周期
    • Target 当前注解可以标记在哪些地方

    Retention

    注解有3种不同的生命周期 Class、Source、Runtime

    1. 注解只保留在源代码中,当把Java文件编辑成Class字节码的时候,此注解消失。
    2. 注解只保留在Class字节码中,当JVM在加载Class文件的时候,此注解消失。
    3. 注解在运行期间一直保留。

    这个枚举类中就对应了上面说的三种生命周期

    类型 描述
    CLASS 注解只保留在Class字节码中,当JVM在加载Class文件的时候
    SOURCE 注解只保留在源代码中
    RUNTIME 注解在运行期间一直保留

    Target

    Target和上面说的那个注解一样,都是Java的元注解,Target注解标记当前注解可以标记在哪些位置,这里只看本文章用到的注解,注解也可以标记在不同的地方,比如 类、方法、字段、构造方法。

    @Target({ElementType.TYPE,ElementType.METHOD})
    复制代码
    
    • 1
    • 2

    我想你一定在代码见过如上代码,此代码表明,当前的注解可以作用在方法,类上。加在其它的位置就会出现语法的错误。

    在项目中使用此组件配置文件

    我想在做这个项目之前应该先了解下这个组件的配置文件是什么样子的,这样在看后面的文章的时候可能更容易理解一些

    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    spring.datasource.username=root
    spring.datasource.password=123456
    spring.datasource.url=jdbc:mysql://ip:port/vipuser?useSSL=false
    
    server.port=8080
    
    mybatis.mapper-locations=classpath:mapper/*.xml
    
    # 有几个库
    db-router.db.datasource.dbCount=3
    # 每一个库里有几个表
    # 这里所说的表是相同的表比如有一个user表,
    # 然后会多复制出几个相同的表比如命名成 user_01,user_02,user_03,user_04
    db-router.db.datasource.tbCount=4
    # 这个配置你可以理解成默认的数据源是哪一个
    db-router.db.datasource.default=db00
    # 这个配置是除了默认的数据源外的数据源
    db-router.db.datasource.list=db01,db02
    db-router.db.datasource.db00.driver-class-name=com.mysql.jdbc.Driver
    db-router.db.datasource.db00.url=jdbc:mysql://ip:port/vipuser?useSSL=false
    db-router.db.datasource.db00.username=root
    db-router.db.datasource.db00.password=123456
    
    db-router.db.datasource.db01.driver-class-name=com.mysql.jdbc.Driver
    db-router.db.datasource.db01.url=jdbc:mysql://ip:port/vipuser?useSSL=false
    db-router.db.datasource.db01.username=root
    db-router.db.datasource.db01.password=123456
    
    db-router.db.datasource.db02.driver-class-name=com.mysql.jdbc.Driver
    db-router.db.datasource.db02.url=jdbc:mysql://ip:port/vipuser?useSSL=false
    db-router.db.datasource.db02.username=root
    db-router.db.datasource.db02.password=123456
    复制代码
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    实现自定义注解

    首页,我们上面说过要根据存入数据库的数据来计算将数据分配到哪个库哪张表里面。所以在定义这个注解的时候,我需要一个注解内的参数用来表明,根据哪个字段的数据计算所分配的库表。

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE,ElementType.METHOD})
    public @interface DBRouter {
    
        /**
         * 需要进行分表分库的字段
         * 通过此字段来计算分到哪个表哪个库
         * @return
         */
        String key() default 
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  • 相关阅读:
    【藏经阁一起读】(68)__《ECS技术实战指南》
    Windows下自动云备份思源笔记到Gitee
    套接字介绍
    在外包公司干了一年半软件测试的一些反思与总结
    vscode快捷生成html标签
    android查漏补缺(2)四种编译目标
    ElasticSearch如何在前后台启动
    小家电Type-C接口PD诱骗芯片 6500
    MacBook Pro(M1 Pro芯片)兼容Tensorflow1.X版本的解决方法
    【Python】QTreeWidget树形结构添加
  • 原文地址:https://blog.csdn.net/Huangjiazhen711/article/details/127700356