---
title: Day07 ~ Day08
index: false
icon: laptop-code
category:
  - 开发笔记
  - 学习记录
---

### 任务

- [x] 分库分表组件

### 遇到的问题

问题就不说了，这一章节全是问题 T.T，基础不牢，地动山摇啊！！！

### 总结

首先建立一个大局观，要实现一个分库分表组件，那么先要学会如何编写 SpringBoot Starter，然后这个 Starter 需要实现的功能是分库分表，那么一定是有多个数据源，这个数据源从项目的 yml 配置文件传进来，然后就要实现多数据源的切换，然后分表操作就是要修改 SQL 的表名，所以需要做的事情大概是如下：

1. 读取数据源信息
2. 动态修改数据源
3. 动态修改 SQL

那么细节该如何实现呢？需要想几个问题，某条数据应该分到哪个库的哪个表呢？这个库表信息该存到哪里进行共享呢？如何动态修改数据源呢？如何动态修改 SQL 呢？那么就需要对应的技术进行支持：

1. Spring & SpringBoot 基础框架，提供依赖注入、配置管理功能
2. `AbstractRoutingDataSource ` 实现动态数据源的路由逻辑
3. `AspectJ` 切面编程，运行时动态拦截方法调用
4. 反射 API，从方法参数中提取路由键的值
5. 正则表达式，解析和修改 SQL
6. ThreadLocal，存储路由信息，以支持动态数据源路由

总体执行流程：

1. 调用被 `@DBRouter` 注解的方法
2. 然后被切面进行拦截，拦截之后先进行路由计算，然后把计算结果保存到 ThreadLocal 中
3. 然后 DynamicDataSource 通过保存到 ThreadLocal 中的数据确定使用哪一个数据源
4. 然后 MyBatis 插件修改 SQL 中的表字段
5. 然后数据库操作执行完成
6. 切面清理 ThreadLocal 里面的数据
7. 方法执行完成，返回结果

虽然步骤不多，但是稍不注意就会出现小 bug，抑或扰动函数算法出错，抑或解析 yml 配置出错等等诸多问题，也是花了两三天才大致搞明白这个路由组件，因为这里面的东西大部分之前都没接触过，查阅了许多文档，毕竟之前连切面都不怎么用，最多也就是拿来做全局日志处理

总之，要先在大脑里面理清总体的一个执行流程，然后根据这个流程再去看代码要清晰很多，最开始的时候没理清步骤，直接看的代码，那种感觉就像第一天学 DDD 一样，直接一脸懵逼，怎么这么多包，卧槽，第一遍下来大概只学到了百分之五十吧，这一遍大概只学到了整体架构，具体的细节还没掌握，下一次努力啃啃细节，如果要我写整个这一套代码，我肯定写出来会报很多错，但是第一次就想学透整个路程怎么可能呢？好在这一次理清了整体架构，至少有了头绪，不至于开不了头，有了头绪，到处搜一搜，拼拼凑凑也能写，哈哈哈