如何用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 ...
随机推荐
- php中的花括号使用详解
1.简单句法规则(用花括号界定变量名,适用于PHP所有版本,是php系统设定): $a = 'flower'; echo "She received some $as" ...
- 纯手动拉WebPanel页面保存出现错误提示 "error:字符文本中的字符太多"
环境为.Net 没有使用WorkWithPlus 纯手拉WebFrom页面 问题出现情况如下:在拉页面的过程中拖了3个Value类型的变量到Table中 页面如下 但是在我保存的时候 发现提示如下错 ...
- 如何为nginx配置https(免费证书)
前言: 给http协议申请ssl免费证书,还是比较主流的一种方式,但是逐渐得一些浏览器不支持自签名的证书了.毕竟这是为了使用者及平台都变得安全的方式,所以无可厚非的,而且也有很多网站即使不使用商业付费 ...
- Git--01 基础 - 远程仓库的使用
目录 Git 基础 - 远程仓库的使用 远程仓库的使用 查看远程仓库 添加远程仓库 从远程仓库中抓取与拉取 推送到远程仓库 查看某个远程仓库 远程仓库的移除与重命名 Git 基础 - 远程仓库的使用 ...
- vue之click事件绑定
1.@click不光可以绑定方法,也可以就地修改data里的数据 代码示例代码如下: 2.@click绑定多个操作的时候用:隔开 代码示例代码如下: <el-table><el-ta ...
- bzoj2004 [Hnoi2010]Bus 公交线路 矩阵快速幂+状压DP
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2004 题解 如果 \(N\) 没有那么大,考虑把每一位分配给每一辆车. 假设已经分配到了第 \ ...
- IBM和DoE推出世界上最快的超级计算机
IBM和美国能源部的橡树岭国家实验室今天发布了该部门最新的超级计算机Summit.IBM声称峰会目前是世界上“最强大,最聪明的科学超级计算机”,其峰值性能每秒高达20万亿次.当新的榜单在本月晚些时候发 ...
- 快速失败(fail—fast)和 安全失败(fail—safe)
快速失败(fail-fast) 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的结构进行了修改(增加.删除),则会抛出Concurrent Modification Exception. 原理 ...
- CONNECT_BY_ROOT
1.select * from EMP t where t.deptno = 10; EMPNO ENAME JOB MGR HIREDATE SAL ...
- find命令进阶(二):对找到的文件执行操作exec
以下面的命令为例: find ~ -type f -name 'foo*' -exec ls -l '{}' ';' 分面两部分,第一部分: find ~ -type f -name 'foo*' 即 ...