Sharding-JDBC 简介

Sharding-JDBC直接封装JDBC API,可以理解为增强版的JDBC驱动,旧代码迁移成本:

  • 可适用于任何基于Java的ORM框架,如:JPA、HIbernate、MYbatis、Spring JDBC Template或者直接使用JDBC。
  • 可基于任何第三方的数据库连接池,如:DBCP、C3P0、Druid等。
  • 理论上可支持任意实现JDBC规范的数据库。目前支持MySQL、Oracle、SQLServer等。

Sharding-JDBC定位为轻量级Java框架,使用客户端直连数据库,以jar包形式提供服务,未使用中间层,无需额外部署,无其他依赖,DBA也无需改变原有的运维方式。采用“半理解”理念的SQL解析引擎,以达到性能与兼容性的最大平衡。

Sharding-JDBC功能灵活且全面:

  • 分片策略灵活,可支持 = , BETWEEN,IN等多维度分片,也支持多分片键共用。
  • SQL解析功能完善,支持聚合,分组,排序,Limit,TOP等查询,并且支持Binding Table以及笛卡尔积的表查询。
  • 支持柔性事务(目前仅最大努力送达型)。
  • 支持读写分离。
  • 支持分布式生成全局主键。

整体架构图



sharding-JDBC 实现分表

数据库表

CREATE TABLE IF NOT EXISTS `t_order_0` (
`order_id` INT NOT NULL,
`user_id` INT NOT NULL,
PRIMARY KEY (`order_id`)
);
CREATE TABLE IF NOT EXISTS `t_order_1` (
`order_id` INT NOT NULL,
`user_id` INT NOT NULL,
PRIMARY KEY (`order_id`)
);
CREATE TABLE IF NOT EXISTS `t_order_2` (
`order_id` INT NOT NULL,
`user_id` INT NOT NULL,
PRIMARY KEY (`order_id`)
);

pom.xml

<dependency>
<groupId>com.dangdang</groupId>
<artifactId>sharding-jdbc-core</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>sharding-jdbc-config-spring</artifactId>
<version>1.4.0</version>
</dependency>

Spring配置

    <rdb:strategy id="tableShardingStrategy" sharding-columns="user_id" algorithm-expression="t_order_${user_id.longValue() % 3}"/>

    <rdb:data-source id="shardingDataSource">
<rdb:sharding-rule data-sources="dataSource">
<rdb:table-rules>
<rdb:table-rule logic-table="t_order" actual-tables="t_order_${0..2}" table-strategy="tableShardingStrategy" />
</rdb:table-rules>
</rdb:sharding-rule>
</rdb:data-source>

单测

直接对MyBatis Mapper进行测试。

Order order = new Order();
order.setOrderId(1111);
order.setUserId(222); Boolean result = orderMapper.insert(order) > 0; System.out.println(result?"插入成功":"插入失败");

OrderExample example = new OrderExample() ;
example.createCriteria().andUserIdEqualTo(1112); List<Order> orderList = orderMapper.selectByExample(example) ; System.out.println(JSONObject.toJSONString(orderList));

使用SingleKeyTableShardingAlgorithm 实现分表规则

目标:每个业务线一个数据表(business_id:业务线Id)。

自定义的分表规则类需要实现SingleKeyTableShardingAlgorithm,并重写doBetweenSharding、doEqualSharding、doInSharding。

修改数据表

ALTER TABLE `t_order_0` ADD business_id INT(4) ;
ALTER TABLE `t_order_1` ADD business_id INT(4) ;
ALTER TABLE `t_order_2` ADD business_id INT(4) ; ALTER TABLE `t_order_0` RENAME t_order_112;
ALTER TABLE `t_order_1` RENAME t_order_101;
ALTER TABLE `t_order_2` RENAME t_order_113;

重新生成Mybatis Mapper相关文件

Spring 配置

    <rdb:strategy id="tableShardingStrategy" sharding-columns="business_id"  algorithm-class="com.boothsun.util.sharding.OrderSingleKeyTableShardingAlgorithm"/>

    <rdb:data-source id="shardingDataSource">
<rdb:sharding-rule data-sources="dataSource">
<rdb:table-rules>
<rdb:table-rule logic-table="t_order" actual-tables="t_order_${[112,101,113]}" table-strategy="tableShardingStrategy" />
</rdb:table-rules>
</rdb:sharding-rule>
</rdb:data-source>

注意:这里使用的是algorithm-class而非algorithm-expression

OrderSingleKeyTableShardingAlgorithm 具体实现

/**
* 每个业务线一个表
*/
public class OrderSingleKeyTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm<Integer> { /**
* 对于分片字段的between操作都走这个方法。
*/
public Collection<String> doBetweenSharding(Collection<String> tableNames, ShardingValue<Integer> shardingValue) {
Collection<String> result = new LinkedHashSet<>(tableNames.size());
Range<Integer> range = shardingValue.getValueRange();
for (long i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {
for (String each : tableNames) {
if (each.endsWith(String.valueOf(i))) {
result.add(each);
}
}
}
return result;
} /**
* 对于分片字段的等值操作 都走这个方法。(包括 插入 更新)
*/
public String doEqualSharding(Collection<String> tableNames, ShardingValue<Integer> shardingValue) {
String sdValue = String.valueOf(shardingValue.getValue());
for (String tableName : tableNames ) {
if(tableName.endsWith(sdValue)) {
return tableName ;
}
}
throw new IllegalArgumentException("无分表参数 无法定位具体数据表");
} /**
* 对于分片字段的in操作,都走这个方法。
*/
public Collection<String> doInSharding(Collection<String> tableNames, ShardingValue<Integer> shardingValue) { Collection<String> result = new LinkedHashSet<>(tableNames.size()); for (Integer value : shardingValue.getValues()) {
for (String tableName : tableNames) {
if (tableName.endsWith(String.valueOf(value))) {
result.add(tableName);
}
}
}
return result;
}
}

单测类

/**
* 测试插入
* @throws Exception
*/
@Test
public void insertSelective() throws Exception { Order order = new Order();
order.setOrderId(123113);
order.setUserId(222);
order.setBusinessId(112); Boolean result = orderMapper.insert(order) > 0; System.out.println(result?"插入成功":"插入失败");
} /**
* 测试 in 的查询操作
* @throws Exception
*/
@Test
public void selectByExample2() throws Exception { List<Integer> values = new ArrayList<>();
values.add(112);
values.add(113); OrderExample example = new OrderExample() ;
example.createCriteria().andUserIdEqualTo(11333).andBusinessIdIn(values); List<Order> orderList = orderMapper.selectByExample(example) ; System.out.println(JSONObject.toJSONString(orderList));
} /**
* 测试between的查询操作
* @throws Exception
*/
@Test
public void selectByExample3() throws Exception { OrderExample example = new OrderExample() ;
example.createCriteria().andBusinessIdBetween(112,113); List<Order> orderList = orderMapper.selectByExample(example) ; System.out.println(JSONObject.toJSONString(orderList));
}

sharding-jdbc 实现分表的更多相关文章

  1. EFCore.Sharding(EFCore开源分表框架)

    EFCore.Sharding(EFCore开源分表框架) 简介 引言 开始 准备 配置 使用 按时间自动分表 性能测试 其它简单操作(非Sharing) 总结 简介 本框架旨在为EF Core提供S ...

  2. 分布式事务-Sharding 数据库分库分表

      Sharding (转)大型互联网站解决海量数据的常见策略 - - ITeye技术网站 阿里巴巴Cobar架构设计与实践 - 机械机电 - 道客巴巴 阿里分布式数据库服务原理与实践:沈询_文档下载 ...

  3. Sharding JDBC整合SpringBoot 2.x 和 MyBatis Plus 进行分库分表

    Sharding JDBC整合SpringBoot 2.x 和 MyBatis Plus 进行分库分表 交易所流水表的单表数据量已经过亿,选用Sharding-JDBC进行分库分表.MyBatis-P ...

  4. Sharding-jdbc实现分库分表

    首先在pom文件中引入需要的依赖 <dependency> <groupId>io.shardingjdbc</groupId> <artifactId> ...

  5. sharding-jdbc结合mybatis实现分库分表功能

    最近忙于项目已经好久几天没写博客了,前2篇文章我给大家介绍了搭建基础springMvc+mybatis的maven工程,这个简单框架已经可以对付一般的小型项目.但是我们实际项目中会碰到很多复杂的场景, ...

  6. mysql、oracle分库分表方案之sharding-jdbc使用(非demo示例)

    选择开源核心组件的一个非常重要的考虑通常是社区活跃性,一旦项目团队无法进行自己后续维护和扩展的情况下更是如此. 至于为什么选择sharding-jdbc而不是Mycat,可以参考知乎讨论帖子https ...

  7. Sharding-JDBC实现水平拆分-单库分表

    参考资料:猿天地   https://mp.weixin.qq.com/s/901rNhc4WhLCQ023zujRVQ 作者:尹吉欢 当单表的数量急剧上升,超过了1千万以上,这个时候就要对表进行水平 ...

  8. 采用Sharding-JDBC解决分库分表

    源码:Sharding-JDBC(分库分表) 一.Sharding-JDBC介绍 1,介绍 Sharding-JDBC是当当网研发的开源分布式数据库中间件,从 3.0 开始Sharding-JDBC被 ...

  9. 分库分表后跨分片查询与Elastic Search

    携程酒店订单Elastic Search实战:http://www.lvesu.com/blog/main/cms-610.html 为什么分库分表后不建议跨分片查询:https://www.jian ...

  10. 【大数据和云计算技术社区】分库分表技术演进&最佳实践笔记

    1.需求背景 移动互联网时代,海量的用户每天产生海量的数量,这些海量数据远不是一张表能Hold住的.比如 用户表:支付宝8亿,微信10亿.CITIC对公140万,对私8700万. 订单表:美团每天几千 ...

随机推荐

  1. BZOJ4103 [Thu Summer Camp 2015]异或运算 【可持久化trie树】

    题目链接 BZOJ4103 题解 一眼看过去是二维结构,实则未然需要树套树之类的数据结构 区域异或和,就一定是可持久化\(trie\)树 观察数据,\(m\)非常大,而\(n\)和\(p\)比较小,甚 ...

  2. nxlog以syslog方式发送日志

    1.nxlog简介 nxlog是个跨平台日志传输插件,支持linux.windows平台,支持window及linux内置的大部分系统日志及常见的web日志,支持tcp.udp.http(s)等协议传 ...

  3. ReentrantLock和synchronized区别和联系?

    相同:ReentrantLock提供了synchronized类似的功能和内存语义,都是可重入锁. 不同: 1.ReentrantLock功能性方面更全面,比如时间锁等候,可中断锁等候,锁投票等,因此 ...

  4. Leetcode 234. 回文链表(进阶)

    1.题目描述 请判断一个链表是否为回文链表. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶: 你能否用 O ...

  5. 51Nod 1347 旋转字符串 | 规律

    Input示例 aa ab Output示例 YES NO 规律:abcabc 只需判断原始字符串 #include <bits/stdc++.h> using namespace std ...

  6. 数据结构&图论:图

    在这里对图的存储和遍历进行一个规范,为以后更复杂的数据结构学习打下基础 首先是邻接矩阵的形式,适合于存稠密图,如果是全连接图就再合适不过了 int a[maxn][maxn]; 一个二维数组就可以搞定 ...

  7. How GitLab uses Unicorn and unicorn-worker-killer

    GitLab uses Unicorn, a pre-forking Ruby web server, to handle web requests (web browsers and Git HTT ...

  8. Vs2013 agent 安装

    1. 在windows 2008 R2上安装vs2013 agents需要满足: 1) .net 3.5 2) sp1补丁包(同windows7 sp1) 2. 安装vs2013 agents 步骤如 ...

  9. 【usaco-Liars and Truth Tellers, 2013 Jan真假奶牛】并查集

    题解: 原先我看错题了,以为是任意选择k个使得它们不矛盾. 这样的话怎么做呢?我想M^2判断,把它们分成若干个集合,集合里面两两不矛盾这个集合里所有的话就不矛盾了. 但是这样是错的.为什么呢? 每一句 ...

  10. 【HDU】6012 Lotus and Horticulture (BC#91 T2)

    [算法]离散化 [题解] 答案一定存在于区间的左右端点.与区间左右端点距离0.5的点上 于是把所有坐标扩大一倍,排序(即离散化). 让某个点的前缀和表示该点的答案. 初始sum=∑c[i] 在l[i] ...