如何用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 ...
随机推荐
- vue,一路走来(4)--vuex
补充 调用外部js,详细介绍如何调用函数. 1.首先在main.js里引用文件 2.然后算是和jquery框架一样需要所谓的入口函数吧 不过令我烦恼的是,在应用的文件中需要把他包含在另一个函数里,才可 ...
- thinkphp在 nginx 的conf文件配置
server { listen 80; server_name www.osd-aisa.com; #charset koi8-r; #access_log logs/host.access.log ...
- django学习笔记--数据库中的多表操作
1.Django数据库----多表的新增操作 1.一对一模式下新增 创建一个详情对象,把这个对象赋值给创建的新的user对象 author_detail = models.AuthorDetail.o ...
- Sass函数:数字函数-round()函数
round() 函数可以将一个数四舍五入为一个最接近的整数: >> round(12.3) 12 >> round(12.5) 13 >> round(1.4999 ...
- javascaipt中数组元素删除方法delete和splice
一.用delete 删除数组中元素(少用) 说明:delete: 只是被删除的元素变成了 undefined ,即数组长度不变 //定义数组 var array=["aa",&qu ...
- 牛客网NOIP赛前集训营-提高组(第七场)B-随机生成树
题目描述 牛牛在纸上画了\(N\)个点(从\(1\)到\(N\)编号),每个点的颜色用一个整数描述. 牛牛决定用这\(N\)个点随机生成一棵树,生成的规则如下: \(1\)号点是根节点 对于\(2\) ...
- hive基础知识or基本操作命令
MySQL的密码是:123456 1.hive创建标准表(以后均可以按照这样创建): create [external] table [if not exists] records (year STR ...
- KEGG注释
在 KEGG 数据库中,把功能相似的蛋白质归为同一组,然后标上 KO 号.通过相似性比对,可以为未知功能的蛋白序列注释上 KO 号. 截止到 2015 年 6 月 12 日,KEGG 数据库中共收录了 ...
- iOS项目开发中的知识点与问题收集整理①
前言部分 注:本文并非绝对原创 大部分内容摘自 http://blog.csdn.net/hengshujiyi/article/details/20943045 文中有些方法可能已过时并不适用于现在 ...
- windows之cmd常用命令
一.简单介绍 CMD全称command,即命令提示符,是内置在windows图形操作系统内的磁盘操作系统,通过CMD可以方便用户查询比较复杂的信息或快速查找实现某些功能等,比如说打开文件.系统设置等操 ...