sharding-jdbc 实现分表
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 实现分表的更多相关文章
- EFCore.Sharding(EFCore开源分表框架)
		EFCore.Sharding(EFCore开源分表框架) 简介 引言 开始 准备 配置 使用 按时间自动分表 性能测试 其它简单操作(非Sharing) 总结 简介 本框架旨在为EF Core提供S ... 
- 分布式事务-Sharding 数据库分库分表
		Sharding (转)大型互联网站解决海量数据的常见策略 - - ITeye技术网站 阿里巴巴Cobar架构设计与实践 - 机械机电 - 道客巴巴 阿里分布式数据库服务原理与实践:沈询_文档下载 ... 
- Sharding JDBC整合SpringBoot 2.x 和 MyBatis Plus 进行分库分表
		Sharding JDBC整合SpringBoot 2.x 和 MyBatis Plus 进行分库分表 交易所流水表的单表数据量已经过亿,选用Sharding-JDBC进行分库分表.MyBatis-P ... 
- Sharding-jdbc实现分库分表
		首先在pom文件中引入需要的依赖 <dependency> <groupId>io.shardingjdbc</groupId> <artifactId> ... 
- sharding-jdbc结合mybatis实现分库分表功能
		最近忙于项目已经好久几天没写博客了,前2篇文章我给大家介绍了搭建基础springMvc+mybatis的maven工程,这个简单框架已经可以对付一般的小型项目.但是我们实际项目中会碰到很多复杂的场景, ... 
- mysql、oracle分库分表方案之sharding-jdbc使用(非demo示例)
		选择开源核心组件的一个非常重要的考虑通常是社区活跃性,一旦项目团队无法进行自己后续维护和扩展的情况下更是如此. 至于为什么选择sharding-jdbc而不是Mycat,可以参考知乎讨论帖子https ... 
- Sharding-JDBC实现水平拆分-单库分表
		参考资料:猿天地 https://mp.weixin.qq.com/s/901rNhc4WhLCQ023zujRVQ 作者:尹吉欢 当单表的数量急剧上升,超过了1千万以上,这个时候就要对表进行水平 ... 
- 采用Sharding-JDBC解决分库分表
		源码:Sharding-JDBC(分库分表) 一.Sharding-JDBC介绍 1,介绍 Sharding-JDBC是当当网研发的开源分布式数据库中间件,从 3.0 开始Sharding-JDBC被 ... 
- 分库分表后跨分片查询与Elastic Search
		携程酒店订单Elastic Search实战:http://www.lvesu.com/blog/main/cms-610.html 为什么分库分表后不建议跨分片查询:https://www.jian ... 
- 【大数据和云计算技术社区】分库分表技术演进&最佳实践笔记
		1.需求背景 移动互联网时代,海量的用户每天产生海量的数量,这些海量数据远不是一张表能Hold住的.比如 用户表:支付宝8亿,微信10亿.CITIC对公140万,对私8700万. 订单表:美团每天几千 ... 
随机推荐
- angularJS新增 品优购新增品牌
			前台代码 brand.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"&g ... 
- Multi-target tracking with Single Moving Camera
			引自:http://www.eecs.umich.edu/vision/mttproject.html Wongun Choi, Caroline Pantofaru, Silvio Savarese ... 
- POJ3177:Redundant Paths(并查集+桥)
			Redundant Paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 19316 Accepted: 8003 ... 
- Android网络请求的时候报错 Connection refused 处理
			在用Android测试JSON数据解析的时候,报了这样一个异常: java.net.ConnectException: localhost/ - Connection refused 原来模拟器默认把 ... 
- ExecuteNonQuery,ExecuteReader,ExecuteScalar 区别
			ExecuteNonQuery方法 :执行非查询SQL操作,包括增insert.删delete.改update ExcuteReader方法 :执行查询,返回DataReader,通过DataRead ... 
- js的数据类型--数字
			近期做一些项目的时候发现,自己的js基础还是不够扎实,再看一遍犀牛书,加深自己的理解和印象.所以从这篇文章开始,后面都是关于原生js的一些内容. 这篇文章,我们具体介绍一下js的数据类型其中一种. j ... 
- Android应用自动更新功能的代码实现(转)
			由于Android项目开源所致,市面上出现了N多安卓软件市场.为了让我们开发的软件有更多的用户使用,我们需要向N多市场发布,软件升级后,我们也必须到安卓市场上进行更新,给我们增加了工作量.因此我们有必 ... 
- 删除linux上7天前后缀名.sql的文件
			#!/bin/bash#delete the file of 7 days agofind /data/mysqlbackup/ -mtime +7 -name "*.sql" - ... 
- Zyan 一个通信框架
			原文地址 本文示例 Zyan是一个简单直观的分布式应用程序开发框架. 以下是Zyan项目的简要概述. 架构图: Zyan一般由客户端和服务端组成.服务端(以组件的形式)提供服务,客户端远程调用服务端的 ... 
- .NET RabbitMQ
			在企业应用系统领域,会面对不同系统之间的通信.集成与整合,尤其当面临异构系统时,这 种分布式的调用与通信变得越发重要.其次,系统中一般会有很多对实时性要求不高的但是执行起来比较较耗时的地方,比如发送短 ... 
