如何用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 ...
随机推荐
- 《深入学习Redis(1):Redis内存模型 》笔记,待完善
参考资料 https://www.cnblogs.com/kismetv/p/8654978.html 一.内存统计 info memory 查看内存统计 五.应用举例
- mysql中文乱码解决办法
Windows 在C:\Program Files\MySQL\MySQL Server 5.5\bin目录下 MySQLInstanceConfig.exe执行 重新配置character_set_ ...
- Vue路由监听
一.问题描述 描述:页面1showowner.vue跳转到页面2showuser.vue 需求:页面1的多个结点对应于一个页面2文件[页面2未展示] 问题:并不是页面一的一个结点对应一个页面二文件 处 ...
- 人生苦短_我用Python_def(函数)_004
# coding=utf-8 # function函数:内置函数 # 例如: len int extent list range str # print insert append pop rever ...
- TensorFlow学习笔记(一)
光复制几个代码到自己机器上跑是没有用的.要理解!公式理解有困难,就用图片辅助理解! MNIST中数字的表示方法 什么是one-hot? "One-hot" encoding mea ...
- Android自动化测试框架UIAutomator原理浅析
UIAutomator是一个Android自动化测试框架,是谷歌在Android4.1版本发布时推出的一款用Java编写的UI测试框架,它只能用于UI即黑盒方面的测试.所以UIAutomator只能运 ...
- spring-boot整合shiro实现权限管理
1.运行环境 开发工具:intellij idea JDK版本:1.8 项目管理工具:Maven 4.0.0 2.GITHUB地址 https://github.com/nbfujx/springBo ...
- php strncmp()函数 语法
php strncmp()函数 语法 作用:比较字符串前n个字符,区分大小写 语法:strncmp(string1,string2,length)直线电机品牌 参数: 参数 描述 string1 必须 ...
- 使用DMA方式发送串口数据
一.初始化部分代码 //串口接收DMA缓存 uint8_t Uart_Rx[UART_RX_LEN] = {}; uint32_t Uart_Send_Buffer[] = {}; void USAR ...
- 09-排序3 Insertion or Heap Sort(25 分)
According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, and gr ...