Mybatis-Plus动态表名插件实现数据库分表查询
浮生若梦,就当它是梦,尽兴地梦它一场;世事如云,就当它是云,从容地观它千变万化。
Mybatis-Plus中提供了各种插件,乐观锁、多租户、动态表名。。。。今天来研究一下基于动态表名插件实现分表的案例
环境准备
数据库建三张表测试
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for user_0
-- ----------------------------
DROP TABLE IF EXISTS `user_0`;
CREATE TABLE `user_0` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`age` int(2) NULL DEFAULT NULL,`email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Table structure for user_1
-- ----------------------------
DROP TABLE IF EXISTS `user_1`;
CREATE TABLE `user_1` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`age` int(2) NULL DEFAULT NULL,`email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Table structure for user_2
-- ----------------------------
DROP TABLE IF EXISTS `user_2`;
CREATE TABLE `user_2` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`age` int(2) NULL DEFAULT NULL,`email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;
pom依赖
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency>
</dependencies>
yml
server:port: 8099spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/my_user?useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghaiusername: rootpassword: root#取模分表 格式 表名&表总数量(多个,分隔)。这里随便怎么定义和解析规则对应即可modTables: user&3
# Logger Config
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
请求参数传递辅助类,就是根据什么去分表,这里是根据id
public class RequestDataHelper {/*** 请求参数存取*/private static final ThreadLocal<Long> REQUEST_DATA = new ThreadLocal<>();/*** 设置请求参数** @param requestData 请求参数 Long*/public static void setRequestData(Long requestData) {REQUEST_DATA.set(requestData);}/*** 获取请求参数** @param param 请求参数* @return 请求参数 MAP 对象*/public static <T> T getRequestData(String param) {Long id = getRequestData();if (null != id) {return (T) id;}return null;}/*** 获取请求参数** @return 请求参数 MAP 对象*/public static Long getRequestData() {return REQUEST_DATA.get();}
}
注入插件,并且程序初始化时解析分表配置
@Configuration
@MapperScan("com.sample.mapper") //和你包名一致,别问我你的怎么报错了
public class MybatisPlusConfig {private static String modTables;private static Map<String, Integer> tableMap = new HashMap<>(16);@Value("${spring.datasource.modTables:null}")public void setModTables(String modTables) {MybatisPlusConfig.modTables = modTables;}@PostConstructpublic void init() throws Exception {String[] split = modTables.split(",");for (String s : split) {String[] split1 = s.split("&");if (split1.length < 2) {throw new RuntimeException("分表配置错误");}MybatisPlusConfig.tableMap.put(split1[0], Integer.valueOf(split1[1]));}}@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();dynamicTableNameInnerInterceptor.setTableNameHandler((sql, tableName) -> {Integer integer = tableMap.get(tableName);if (integer != null) {// 获取参数方法Long id = RequestDataHelper.getRequestData();if(id == null){throw new RuntimeException("未设置分表配置");}long l = Math.floorMod(id, Long.parseLong(integer.toString()));return tableName + "_" + l;}return tableName;});interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);// 3.4.3.2 作废该方式// dynamicTableNameInnerInterceptor.setTableNameHandlerMap(map);return interceptor;}
}
实体类
@Data
@Accessors(chain = true)
@TableName(value = "user")
public class User {private Long id;private String name;private Integer age;private String email;
}
mapper
/*** @author: yh* @Description: 支持不需要 UserMapper.xml 这个模块演示内置 CRUD 咱们就不要 XML 部分了* @date: 2022/6/6 12:24*/public interface UserMapper extends BaseMapper<User> {}
测试
现在就可以测试啦,编写一个测试方法
@Resourceprivate UserMapper userMapper;/*** 分表测试* 执行后观察打印sql* @author yh* @date 2022/6/6*/@Testpublic void test1() {RequestDataHelper.setRequestData(1L);userMapper.selectList(null);RequestDataHelper.setRequestData(2L);userMapper.selectList(null);RequestDataHelper.setRequestData(3L);userMapper.selectList(null);RequestDataHelper.setRequestData(4L);userMapper.selectList(null);}
结果:
不同的业务id按照user_
加 id取模
,组成表名查询。这里的分表规则随便怎么定义 时间、id、字符串hash都可以。
完整代码已上传Gitee Spring整合常用组件
到此,本章内容就介绍完啦,如果有帮助到你 欢迎点个赞
Mybatis-Plus动态表名插件实现数据库分表查询相关推荐
- Hibernate 动态表名映射(数据库分表) NamingStrategy
NamingStrategy接口很有意思,可以作为业务类规范和数据库表规范的桥梁,例如一个数据对象User,对应数据库表是 T_USER,如果所有映射关系都是这样的情况,可以使用NamingStrat ...
- php mysql新闻表模板_新闻数据库分表案例
新闻数据库分表案例目录:[-]NetkillerMySQL手札MySQLMariaDB...Mr.NeoChan,陈景峰(BG7NYT)4.16.3.新闻数据库分表案例NetkillerMySQL手札 ...
- 数据库分表之雪花算法
文章目录 一.背景 二.数据库分表 1. 垂直分表 2. 水平分表 一.背景 需要选择合适的方案去应对数据规模的增长,以应对逐渐增长的访问压力和数据量. 数据库的扩展方式主要包括:业务分库.主从复制, ...
- MyBatis-Plus动态表名插件使用
一.MyBatis-Plus动态表名插件使用 官方文档-动态表名插件:https://baomidou.com/pages/2a45ff/#dynamictablenameinnerintercept ...
- 数据库面试 - 如何设计可以动态扩容缩容的分库分表方案?
数据库面试 - 如何设计可以动态扩容缩容的分库分表方案? 面试题 如何设计可以动态扩容缩容的分库分表方案? 面试官心理分析 对于分库分表来说,主要是面对以下问题: 选择一个数据库中间件,调研.学习.测 ...
- java分表插件_fastmybatis编写分表插件
fastmybatis支持原生的插件,将写好的插件配置到mybatis配置文件中即可 这里演示编写一个分表插件 假设有4张分表,user_log0~3,记录用户的日志情况 user_log0 user ...
- mysql常用表名大全_MySQL常用系统表大全
MySQL5.7 默认的模式有:information_schema, 具有 61个表: m ysqL, 具有31个表: performance_schema,具有87个表; sys, 具有1个表, ...
- [转载]学习数据库分表和分库思想
目录: 基本思想之什么是分库分表 基本思想之为什么要分库分表 分库分表的实施策略 何谓垂直切分 何谓水平切分 应该使用哪一种方式来实施数据库分库分表这要看数据库中数据量的瓶颈所在并综合项目的业务类型进 ...
- 超大数据量存储常用数据库分表分库算法总结
这篇文章主要介绍了超大数据量存储常用数据库分表分库算法总结,本文讲解了按自然时间来分表/分库.按数字类型hash分表/分库.按md5值来分表/分库三种方法,以及分表所带来的问题探讨,需要的朋友可以参考 ...
最新文章
- 令人郁闷的discuz!个人空间过滤机制
- [转]仿163网盘无刷新文件上传系统
- es6拼接字符串的方式。
- 数据库(3)——关系
- java数字转换为日期_Java 日期字符串date与数字long之间的转换
- c语言标准库函数大全.chm,C语言标准库函数(word版).doc
- codeforces 690D2 D2. The Wall (medium)(组合数学)
- 所有子线程全部结束的判断
- php循环产生复选框,史上最详细的vue动态生成checkbox的选项并实现多选框的保存回显...
- 李宏毅机器学习Homework1(代码简洁版)
- TOPSIS法(小白必看文章包含详细源代码及注释)
- COPY 一种接近最优的导航网格生成算法以及基于导航网格的寻路算法
- 数学文化——数论之美
- 2020学而思笔记小初课程百度云网盘分享下载
- 推荐上百本优质大数据书籍,附必读清单(大数据宝藏)
- 蚂蚁金服黑科技:SOFA DTX分布式事务,保障亿级资金操作一致性
- 用Python进行图文识别(OCR)
- Hackthebox练习kaliLinux学习
- “路漫漫其修远兮,吾将上下而求索”——读“做中学”有感 20155328
- android 2048 动画,大杀器Bodymovin和Lottie:把AE动画转换成HTML5/Android/iOS原生动画
热门文章
- 每日案例(第三期):智慧能源领域知识图谱实践案例速读03-04
- 同一局域网不同网段ip实现通信
- am335x+wm8960音频基于linux 4.9.41移植
- android 锁屏 广告,华为手机锁屏后总是出现广告该怎么办?-安卓手机屏幕解锁后总是有个广告...
- BIMFACE功能测评- 如何创建二三维标签?
- php和蝉知,蝉知getshell
- openMVS深度图计算:DenseReconstruction Estimate之EVTEstimateDepthMap之patchmatch的传播优化
- HarmonyOS之AI能力·语音识别技术
- noj 2112 拯救活动室的男女比例(最大费用最大流)
- 雷达遥感原理;侧视雷达成像系统;雷达回波强度的影响因素;雷达遥感及雷达图像的特征