SpringBoot+Mybatis+Sharding-JDBC

花了2天时间研究了一下Sharding-JDBC的使用,这里简单记录一下。
代码弄的比较乱,就没放到git上,需要源码的可以留下邮箱或者其他联系方式,我看到了发你。

遗留问题:Druid无法监控2个数据源的sql。
应该需要通过编写DataSourceConfig.java的方式解决。

目录
1.POM文件的内容
2.分库分表+分库不分表
3.读写分离
4.ComplexKeysShardingAlgorithm实现

1.POM文件的内容

pom文件在引用Sharding-jdbc时有2张方式:

  • sharding-jdbc-spring-boot-starter(后面的描述用的是这种方式)
    这种方式可以不用自己写DataSourceConfig文件

  • sharding-jdbc-core
    这种方式的例子,基本都是要自己写DataSourceConfig文件的
    参考://www.greatytc.com/p/3b2ab87b0de7
    https://blog.csdn.net/a992795427/article/details/85102918
    https://www.cnblogs.com/mr-yang-localhost/p/8280500.html

    #sharding-jdbc-spring-boot-starter方式的参考pom文件
    <dependencies>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
          <groupId>org.mybatis.spring.boot</groupId>
          <artifactId>mybatis-spring-boot-starter</artifactId>
          <version>2.1.0</version>
      </dependency>
      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>5.1.21</version>
      </dependency>
    
      <dependency>
          <groupId>io.shardingsphere</groupId>
          <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
          <version>3.1.0.M1</version>
      </dependency>
    
      <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>druid-spring-boot-starter</artifactId>
          <version>1.1.23</version>
      </dependency>
    </dependencies>
    

2.分库分表+分库不分表

用的的数据库
image.png
# 相关表结构
CREATE TABLE `order0` (
  `id` bigint(11) NOT NULL COMMENT '主键ID',
  `user_id` bigint(11) DEFAULT NULL COMMENT '用户ID',
  `order_id` bigint(11) DEFAULT NULL COMMENT '订单ID',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 CREATE TABLE `user_info` (
  `user_id` bigint(19) NOT NULL,
  `user_name` varchar(45) DEFAULT NULL,
  `account` varchar(45) NOT NULL,
  `password` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

application.properties文件参考

spring.application.name=sharding-jdbc

#mybatis
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.type-aliases-package=com.lbc.demo.model
mybatis.mapper-locations=classpath:mapper/*Mapper.xml

#当注册遇到相同名字是否允许被注册,在配置中心无效
spring.main.allow-bean-definition-overriding=true

#所有主从库
sharding.jdbc.datasource.names=user0,user1

#dsmaster0
sharding.jdbc.datasource.user0.type=com.alibaba.druid.pool.DruidDataSource
sharding.jdbc.datasource.user0.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.user0.url=jdbc:mysql://localhost:3306/user0?useSSL=false
sharding.jdbc.datasource.user0.username=root
sharding.jdbc.datasource.user0.password=password

#slave for ds_master_0
sharding.jdbc.datasource.user1.type=com.alibaba.druid.pool.DruidDataSource
sharding.jdbc.datasource.user1.driver-class-name=com.mysql.jdbc.Driver
sharding.jdbc.datasource.user1.url=jdbc:mysql://localhost:3306/user1?useSSL=false
sharding.jdbc.datasource.user1.username=root
sharding.jdbc.datasource.user1.password=password

#分库规则
sharding.jdbc.config.sharding.default-database-strategy.inline.sharding-column=user_id
sharding.jdbc.config.sharding.default-database-strategy.inline.algorithm-expression=user$->{user_id % 2}

# 绑定逻辑表
sharding.jdbc.config.sharding.binding-tables=order 
# 设置分表规则
# sharding.jdbc.config.sharding.tables.逻辑表.actual-data-nodes:逻辑表对应的真实表
# sharding.jdbc.config.sharding.tables.逻辑表.table-strategy.inline.sharding-column:分表列
# sharding.jdbc.config.sharding.tables.逻辑表.table-strategy.inline.algorithm-expression:分表算法
# sharding.jdbc.config.sharding.tables.逻辑表.key-generator-column-name:主键列
# 分库,也分表
sharding.jdbc.config.sharding.tables.order.actual-data-nodes=user$->{0..1}.order$->{0..1}
sharding.jdbc.config.sharding.tables.order.table-strategy.inline.sharding-column=order_id
sharding.jdbc.config.sharding.tables.order.table-strategy.inline.algorithm-expression=order$->{order_id % 2}
sharding.jdbc.config.sharding.tables.order.key-generator-column-name=id

# 只分库,不分表
sharding.jdbc.config.sharding.tables.user_info.actual-data-nodes=user$->{0..1}.user_info
sharding.jdbc.config.sharding.tables.user_info.table-strategy.inline.sharding-column=user_id
sharding.jdbc.config.sharding.tables.user_info.table-strategy.inline.algorithm-expression=user_info
sharding.jdbc.config.sharding.tables.user_info.key-generator-column-name = user_id

#逻辑主从库名和实际主从库映射关系
#sharding.jdbc.config.sharding.master-slave-rules.ds0.master-data-source-name=dsmaster0
#用逗号分隔
#sharding.jdbc.config.sharding.master-slave-rules.ds0.slave-data-source-names=dsmaster0
#sharding.jdbc.config.sharding.master-slave-rules.dsmaster1.masterDataSourceName=dsmaster1
#sharding.jdbc.config.sharding.master-slave-rules.dsmaster1.slaveDataSourceNames=dsmaster1slave0

server.port=8080

3.读写分离

用到的数据库和表机构同上
application.yml参考文件

sharding:
  jdbc:
    dataSource:
      names: db-test0,db-test1
      # 配置主库
      db-test0: #org.apache.tomcat.jdbc.pool.DataSource
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/user0?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
        username: root
        password: password
        #最大连接数
        maxPoolSize: 3
      db-test1: # 配置第一个从库
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/user1?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT
        username: root
        password: password
        maxPoolSize: 3

    config:
      masterslave: # 配置读写分离
        load-balance-algorithm-type: round_robin # 配置从库选择策略,提供轮询与随机,这里选择用轮询//random 随机 //round_robin 轮询
        name: db1s2
        master-data-source-name: db-test0
        slave-data-source-names: db-test1

    props:
      sql: # 开启SQL显示,默认值: false,注意:仅配置读写分离时不会打印日志!!!
        show: true

mybatis:
  configuration:
    map-underscore-to-camel-case: true
  type-aliases-package: com.lbc.demo.model
  mapper-locations: classpath:mapper/*Mapper.xml

4.ComplexKeysShardingAlgorithm实现
Complex方式的配置文件和2.分库分表+分库不分表的配置文件类似,只改了一个东西

分库,也分表

sharding.jdbc.config.sharding.tables.order.actual-data-nodes=user$->{0..1}.order$->{0..1}
sharding.jdbc.config.sharding.tables.order.table-strategy.complex.sharding-columns=user_id,order_id
sharding.jdbc.config.sharding.tables.order.table-strategy.complex.algorithm-class-name=com.lbc.demo.config.ComplexShardingAlgorithm

然后,需要增加一个路由类ComplexShardingAlgorithm,这里最好debug一下。

public class ComplexShardingAlgorithm implements ComplexKeysShardingAlgorithm {
/**
 * @param collection     在加载配置文件时,会解析表分片规则。将结果存储到 collection中,doSharding()参数使用
 * @param shardingValues SQL中对应的
 * @return
 */
@Override
public Collection<String> doSharding(Collection<String> collection, Collection<ShardingValue> shardingValues) {
    System.out.println("collection:" + collection + ",shardingValues:" + shardingValues);

    Collection<Long> orderIdValues = getShardingValue(shardingValues, "order_id");
    Collection<Long> userIdValues = getShardingValue(shardingValues, "user_id");

    List<String> shardingSuffix = new ArrayList<>();

    // user_id,order_id分片键进行分表
    for (Long userId : userIdValues) {
        for (Long orderId : orderIdValues) {
            String suffix = userId % 2 + "_" + orderId % 2;
            //写死测试
            suffix="0";
            for (String s : collection) {
                if (s.endsWith(suffix)) {
                    shardingSuffix.add(s);
                }
            }
        }
    }

    return shardingSuffix;
}

private Collection<Long> getShardingValue(Collection<ShardingValue> shardingValues, final String key) {
    Collection<Long> valueSet = new ArrayList<>();
    Iterator<ShardingValue> iterator = shardingValues.iterator();
    while (iterator.hasNext()) {
        ShardingValue next = iterator.next();
        if (next instanceof ListShardingValue) {
            ListShardingValue value = (ListShardingValue) next;
            // user_id,order_id分片键进行分表
            if (value.getColumnName().equals(key)) {
                return value.getValues();
            }
        }
    }
    return valueSet;
}
}

参考了太多了,记不清了:
//www.greatytc.com/p/3b2ab87b0de7
//www.greatytc.com/p/9eebfae039c9
https://segmentfault.com/a/1190000019906637
https://www.cnblogs.com/yixinjishu/p/10876071.html
https://www.cnblogs.com/mr-yang-localhost/p/8280500.html
[https://blog.csdn.net/hy245120020/article/details/85335446]
//www.greatytc.com/p/e4f291052c83
(https://blog.csdn.net/hy245120020/article/details/85335446)
https://blog.csdn.net/forezp/article/details/94343671
https://blog.csdn.net/a992795427/article/details/85102918
https://www.cnblogs.com/mr-yang-localhost/p/8280500.html

SpringBoot 2.3 整合最新版 ShardingJdbc + Druid + MyBatis 实现分库分表

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,478评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,825评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,482评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,726评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,633评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,018评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,168评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,320评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,264评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,288评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,995评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,587评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,909评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,284评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,862评论 2 339