如何用Mybatis分库分表
分库
在分库的时候 有时候为了方便 一些表需要存放所有库的信息,称为全局库。如:用户表存放所有的用户。
此时分库的思路 数据库分为全局库和业务库,其中业务库又分为N多个库,全局库只放个别表方便开发。
这个时候 就需要一个全局DAO,此时我们的Mybatis就需要支持两个DAO
两个DAO(bizDao和globalDao)就需要有两个sqlSessionFactory,bizSqlSessionFactory和globalSqlSessionFactory和两个事物管理器transactionManager
<bean id="bizDao" class="com.xxx.dao.BizDao">
<property name="sqlSessionFactory" ref="bizSqlSessionFactory"/>
</bean>
<bean id="globalDao" class="com.xxx.dao.GlobalDao">
<property name="sqlSessionFactory" ref="globalSqlSessionFactory"/>
</bean>
<bean id="bizSqlSessionFactory" parent="sqlSessionFactoryDefault" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="routingDataSource"/>
</bean> <bean id="globalSqlSessionFactory" parent="sqlSessionFactoryDefault" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="globalDataSource"/>
</bean>
根据请求动态指定业务库DataSource
分库就是一个项目有多个数据库,对Myabtis来说就有多个数据源(dataSource)根据你的请求 判断应该查询哪个库 从而指定动态指定哪个数据源
可以继承Spring的AbstractRoutingDataSource重写接口中determineCurrentLookupKey()根据业务需求返回当前的dbkey(哪个库1、2、3、4。。。)
全局库和业务库事物管理器
因为事物是基于Service的,所以Service也建议分为全局Service和业务Service,根据Service类型(建议配个AOP全局处理 放到ThreadLocal中)
实现PlatformTransactionManager接口,接口中getTransaction()方法可以动态的返回指定的事物管理器(从上面的ThreadLocal中拿到当前的事物管理器)
思考:为什么AbstractRoutingDataSource中多个DataSource不需要动态配置事物管理器?
总结:业务库和全局库有两个不同的DataSource,其中业务库的DataSource继承Spring的AbstractRoutingDataSource,
Spring又分为了N个DataSource(对bizSqlSessionFactory而言 只有一个RoutingDataSource,RoutingDataSource里面有一个数据源集合)
全局的globalSqlSessionFactory也可以当bizSqlSessionFactory中的AbstractRoutingDataSource的一个属性 这么做虽然减少了配置,但是开发不直观。
分表
上面的分库的思路就是动态指定DateSource和TransactionManager
分表:就是在Mybatis中写一个拦截器 动态的更改表名
1.拦截器
SqlSessionFactoryBean里面有个private Interceptor[] plugins;属性 可以配置一些拦截器
我们自己定义的拦截器需要实现Interceptor接口
接口需要加以下注解
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class}) })
2.在拦截器里面 我们需要动态解析SQL和更改SQL
@Intercepts({
@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class})
})
public class MybatisInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
if (invocation.getTarget() instanceof StatementHandler) {
RoutingStatementHandler handler = (RoutingStatementHandler) invocation.getTarget();
//通过反射拿到statement对象
StatementHandler delegate = (StatementHandler) ReflectUtil.getFieldValue(handler, "delegate");
BoundSql boundSql = delegate.getBoundSql();
String sql = boundSql.getSql();
String pageSql =sql+" limit 1 ";//操作sql
//再通过反射把新sql设置进去
ReflectUtil.setFieldValue(boundSql, "sql", pageSql);
}
return invocation.proceed();
}
如何用Mybatis分库分表的更多相关文章
- SpringMVC + MyBatis分库分表方案
mybatis作为流行的ORM框架,项目实际使用过程中可能会遇到分库分表的场景.mybatis在分表,甚至是同主机下的分库都可以说是完美支持的,只需要将表名或者库名作为动态参数组装sql就能够完成.但 ...
- Mybatis的分表实战
前言: 以前写代码, 关于mysql的分库分表已被中间件服务所支持, 业务代码涉及的sql已规避了这块. 它对扩展友好, 你也不知道到底他分为多少库, 多少表, 一切都是透明的. 不过对于小的团队/工 ...
- sharding-jdbc结合mybatis实现分库分表功能
最近忙于项目已经好久几天没写博客了,前2篇文章我给大家介绍了搭建基础springMvc+mybatis的maven工程,这个简单框架已经可以对付一般的小型项目.但是我们实际项目中会碰到很多复杂的场景, ...
- 三、SpringBoot 整合mybatis 多数据源以及分库分表
前言 说实话,这章本来不打算讲的,因为配置多数据源的网上有很多类似的教程.但是最近因为项目要用到分库分表,所以让我研究一下看怎么实现.我想着上一篇博客讲了多环境的配置,不同的环境调用不同的数据库,那接 ...
- Sharding JDBC整合SpringBoot 2.x 和 MyBatis Plus 进行分库分表
Sharding JDBC整合SpringBoot 2.x 和 MyBatis Plus 进行分库分表 交易所流水表的单表数据量已经过亿,选用Sharding-JDBC进行分库分表.MyBatis-P ...
- MyBatis实现Mysql数据库分库分表操作和总结
前言 作为一个数据库,作为数据库中的一张表,随着用户的增多随着时间的推移,总有一天,数据量会大到一个难以处理的地步.这时仅仅一张表的数据就已经超过了千万,无论是查询还是修改,对于它的操作都会很耗时,这 ...
- Java实战:教你如何进行数据库分库分表
摘要:本文通过实际案例,说明如何按日期来对订单数据进行水平分库和分表,实现数据的分布式查询和操作. 本文分享自华为云社区<数据库分库分表Java实战经验总结 丨[绽放吧!数据库]>,作者: ...
- 利用sharding-jdbc分库分表
sharding-jdbc是当当开源的一款分库分表的数据访问层框架,能对mysql很方便的分库.分表,基本不用修改原有代码,只要配置一下即可,完整的配置参考以下内容: <?xml version ...
- 转数据库分库分表(sharding)系列(一) 拆分实施策略和示例演示
本文原文连接: http://blog.csdn.net/bluishglc/article/details/7696085 ,转载请注明出处!本文着重介绍sharding切分策略,如果你对数据库sh ...
随机推荐
- 在css里如何控制表单中文本的value内的文字的位置,比方说让它向右移动2px
方法1:比较简单的方法是将文本放到一个容器中(div,span,a等等)然后给容器设置样式,通过控制容器的位置来达到控制字体位置.(margin-left:10px; margin-top:15px; ...
- python中字典类型的使用
Python字典类型 字典是一种键值对的集合,键值对之间无序 字典类型的定义 采用{}或者dict()来创建字典对象,键值对之间使用:进行分隔. {<键1>:<值1>, < ...
- 175-基于TI DSP TMS320C6455、Xilinx V5 FPGA XC5VSX95T的高速数据处理核心板
基于TI DSP TMS320C6455.Xilinx V5 FPGA XC5VSX95T的高速数据处理核心板 一.板卡概述 该DSP+FPGA高速信号采集处理板由我公司自主研发,包含一片TI DSP ...
- Linux防火墙--iptables--白名单配置
1.服务器22端口和1521端口开通给指定IP [root@node2 sysconfig]# iptables -t filter -nL INPUT Chain INPUT (policy ACC ...
- 生成树计数 Matrix-Tree 定理 学习笔记
一直都知道要用Matrix-Tree定理来解决生成树计数问题,但是拖到今天才来学.博主数学不好也只能跟着各位大佬博客学一下它的应用以及会做题,证明实在是不会. 推荐博客: https://www.cn ...
- CS184.1X 计算机图形学导论(第三讲)
第一单元(介绍关于变换的数学知识) :基本二维变换 模型坐标系,世界坐标系 1.缩放 Scale(规模,比例) Sx表示在x方向上放大的倍数,Sy表示在y方向上放大的倍数,因此X坐标乘以Sx,Y坐标乘 ...
- redis JedisConnectionException: Could not get a resource from the pool
转载:https://blog.csdn.net/testcs_dn/article/details/43052585 产生此错误的原因通常是: 一.Redis没有启动: 我自己遇到一次这样的问题.汗 ...
- 前端每日实战:47# 视频演示如何用纯 CSS 创作一个蝴蝶标本展示框
效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/xzgZzQ 可交互视频教程 此视频 ...
- HDU 6090 Rikka with Graph —— 2017 Multi-University Training 5
Rikka with Graph Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- HihoCoder - 1664 (单调队列)
题目:https://vjudge.net/contest/319166#problem/B 题意: 一个01间隔矩阵,求一个方阵的最大边长,这个方阵的要求是里面01分隔,不能有01相邻 思路:同 ...