https://www.jianshu.com/p/ba27cb6177e9

正文

首先实现org.apache.ibatis.plugin.Interceptor接口,复写以下三个方法:

//实现拦截逻辑的地方,内部要通过invocation.proceed()显式地推进责任链前进,
//也就是调用下一个拦截器拦截目标方法Object intercept(Invocation invocation) throws Throwable; //用当前这个拦截器生成对目标target的代理,实际是通过Plugin.wrap(target,this)来完成的, //把目标target和拦截器this传给了包装函数 Object plugin(Object target); //设置额外的参数,参数配置在拦截器的Properties节点里 void setProperties(Properties properties); 

如果想要拦截所有的sql,在实现类上添加 annotation

@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class})}) 

注:Mybatis支持对Executor、StatementHandler、PameterHandler和ResultSetHandler进行拦截,也就是说会对这4种对象进行代理。

框架如上,具体实现有两个重要点:

1 表的拆分规则

可以在Mapper对象中加上一个annotation,按以下方式去获取:

String className = id.substring(0, id.lastIndexOf("."));Class  classObj = Class.forName(className);//根据配置自动生成分表SQL TableSeg tableSeg = classObj.getAnnotation(TableSeg.class); 

TableSeg对象定义:

@Target({ ElementType.TYPE })@Retention(RetentionPolicy.RUNTIME)@Inherited@Documented public @interface TableSeg { /** * 表名 * @return */ public String tableName(); /** * 分表方式,取模,如%5:表示取5余数, * 如果不设置,直接根据shardBy值分表 * @return */ public String shardType(); /** * 根据什么字段分表 * 多个字段用数学表达表示,如a+b a-b * @return */ public String shardBy(); } 
2 sql解析与替换

可以通过以下方法去获取BoundSql,这个对象有关于这个sql的内容

StatementHandler statementHandler = (StatementHandler) invocation.getTarget();BoundSql boundSql = statementHandler.getBoundSql();

目前看到一些常规做法都是利用string 的replace方案替换sql中的表名,这显然一个埋坑的做法。利用词法分析器才是完美方案,可以使用antlr4,grammar文件可以去github上找到。

antlr值得深入学习。


总结

在编写插件时需注意以下几个原则:

1)不编写不必要的插件;

2)实现plugin方法时判断一下目标类型,是本插件要拦截的对象才执行Plugin.wrap方法,否者直接返回目标本省,这样可以减少目标被代理的次数。

作者:harry_chen
链接:https://www.jianshu.com/p/ba27cb6177e9
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

转载于:https://www.cnblogs.com/davidwang456/articles/8995401.html

Mybatis实现分库分表相关推荐

  1. mybatis+mysql分库分表_一种简单易懂的 MyBatis 分库分表方案

    数据库分库分表除了使用中间件来代理请求分发之外,另外一种常见的方法就是在客户端层面来分库分表 -- 通过适当地包装客户端代码使得分库分表的数据库访问操作代码编写起来也很方便.本文的分库分表方案基于 M ...

  2. Netty游戏服务器实战开发(11):Spring+mybatis 手写分库分表策略(续)

    在大型网络游戏中,传统的游戏服务器无法满足性能上的需求.所以有了分布式和微服务新起,在传统web服务器中,我们保存用户等信息基本都是利用一张单表搞定,但是在游戏服务器中,由于要求比较高,我们不能存在大 ...

  3. mybatis+shardingJdbc实现数据库读写分离和分库分表

    文章目录 一.原理介绍 二.环境准备 2.1 数据库环境 2.2 开发环境 2.2.1 pom.xml 2.2.2 建表语句 三.主要代码 3.1 实体 3.2 Mapper 3.3 Controll ...

  4. ShardingSphere分库分表(SpringBoot+mybatis+mysql)配置

    一.什么是ShardingSphere 定位为轻量级 Java 框架,在 Java 的 JDBC 层提供的额外服务. 它使用客户端直连数据库,以 jar 包形式提供服务,无需额外部署和依赖,可理解为增 ...

  5. Mybatis-Plus 支持分库分表了?-官方神器发布!

    欢迎关注方志朋的博客,回复"666"获面试宝典 今天介绍一个 MyBatis - Plus 官方发布的神器:mybatis-mate 为 mp 企业级模块,支持分库分表,数据审计. ...

  6. Sharding-Jdbc 实现读写分离 + 分库分表,写得太好了!

    欢迎关注方志朋的博客,回复"666"获面试宝典 来自:CSDN,作者:邋遢的流浪剑客 链接:https://blog.csdn.net/qq_40378034/article/de ...

  7. 分库分表之 Sharding-JDBC 中间件,看这篇真的够了!

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 本文大纲如下 Sharding-JDBC 的基本用法和基本 ...

  8. 面试官三连问:你这个数据量多大?分库分表怎么做?用的哪个组件?

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 1.  概述 ShardingSphere是一套开源的分布 ...

  9. 太强了!这款轻量级的数据库中间件完美解决了SpringBoot中分库分表问题

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:Macky_He blog.csdn.net/Macky_H ...

最新文章

  1. suse linux ssh connerc failed
  2. 这样的“牛”人,绝佳客户最好能多碰上上几个是我们当程序员的好运
  3. C++类型转换总结【转】
  4. 导入Excel表里的数据时产生【定义了过多字段】,但有时又是成功的
  5. 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---55
  6. linux sudo权限_Linux Sudo 被曝漏洞,可导致用户以 root 权限运行命令
  7. python 封闭图形面积_python实现计算图形面积
  8. Django:django.db.utils.OperationalError: (1050, “Table ‘malicious_software_db‘ already exists“)
  9. MySQL OCP认证(文末附参考题)
  10. python 运行另一个py_如何在python中执行另一个py文件
  11. 前台jQuery实现图片轮播
  12. 使用单视点模型进行水下标定的分析
  13. 获取电脑ip并输入微信发送
  14. 详解SOAP简单对象访问协议
  15. MapGuide的系统架构
  16. VS中无法解析的外部命令的解决办法
  17. MySQL高可用之MMM介绍
  18. 美团的护城河与王兴的星辰大海
  19. 1588时钟同步算法仿真matlab,基于卡尔曼滤波与PID控制的IEEE1588从时钟同步研究
  20. Pycharm最强编辑器详细使用指南!

热门文章

  1. 编译问题二 /snmplib/tools.c:920 undefined reference to `clock_gettime' 问题解决
  2. IPv6扩展头部 (一) 扩展头部格式、类型与扩展选项
  3. python关键字是什么颜色,python – Matplotlib:如果使用关键字sym,则使用Boxplot异常值颜色更改...
  4. 11kw星三角启动延时几秒_电机星三角降压启动接线方法图解
  5. python函数能否增强代码可读性_总结的几个Python函数方法设计原则
  6. python中一个汉字是几个字符_Python中每次处理一个字符的5种方法
  7. java的输出的例子_Java例子:万年历的输出
  8. php 手机唯一标示_Php获取移动设备唯一标识
  9. c语言两个程序合并一起运行,这两个程序如何可以在一起运行
  10. 设置自增递增零开始_MySQL中如何设置自动递增id主键重新计数从1开始?