前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >SpringBoot+Mybatis-Plus整合Sharding-JDBC5.1.1实现单库分表

SpringBoot+Mybatis-Plus整合Sharding-JDBC5.1.1实现单库分表

作者头像
掉发的小王
发布于 2022-07-11 08:16:35
发布于 2022-07-11 08:16:35
2.1K00
代码可运行
举报
文章被收录于专栏:小王知识分享小王知识分享
运行总次数:0
代码可运行

一、前言

小编最近一直在研究关于分库分表的东西,前几天docker安装了mycat实现了分库分表,但是都在说mycat的bug很多。很多人还是倾向于shardingsphere,其实他是一个全家桶,有JDBC、Proxy 和 Sidecar组成,小编今天以最简单的JDBC来简单整合一下! 现在最新版已经是5.1.1,经过一天的研究用于解决了所有问题,完成了单库分表!!

想了解4.0.0版本的可以看一下小编刚刚写的:SpringBoot+Mybatis-Plus整合Sharding-JDBC4.0.0实现单库分表 如果想看mycat的可以看一下小编之前写的文章哈:Docker安装Mycat和Mysql进行水平分库分表实战

二、踩过的坑

1. 数据源问题

不要使用druid-spring-boot-starter这个依赖,启动会有问题

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<dependency>-->
	<groupId>com.alibaba</groupId>
	<artifactId>druid-spring-boot-starter</artifactId>
	<version>1.1.21</version>
/dependency>

报错信息:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userMapper' defined in file 
[D:\jiawayun\demo\target\classes\com\example\demo\mapper\UserMapper.class]:
 Invocation of init method failed; nested exception is 
 java.lang.IllegalArgumentException: Property 'sqlSessionFactory' 
 or 'sqlSessionTemplate' are required

==解决方案:==

使用单独的druid

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.8</version>
</dependency>

建议使用==默认的数据源==,sharding-jdbc也是使用的默认的数据源,小编使用的自带的,忘记druid后面会不会有问题了!!

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type: com.zaxxer.hikari.HikariDataSource

2. Insert 语句不支持分表路由到多个数据节点

报错信息: Insert statement does not support sharding table routing to multiple data nodes.

解决方案: 看小编文章:解决不支持分表路由问题

三、导入maven依赖

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
    <version>5.1.1</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<!-- lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.10</version>
</dependency>
<!--jdbc-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- mysql -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

<!-- mybatis-plus -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.1</version>
</dependency>

四、新建表

1. 新建二张表

命名为:user_0user_1

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE `user_0`  (
  `cid` bigint(25) NOT NULL,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `gender` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `data` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`cid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

2. 数据库结构

五、框架全局展示

1. User实体类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Data
public class User implements Serializable {
    private static final long serialVersionUID = 337361630075002456L;
    
    private Long cid;
    
    private String name;

    private String gender;

    private String data;

}

2. controller

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RestController
@RequestMapping("/test")
public class UserController {

    @Autowired
    private UserMapper userMapper;

    @GetMapping("/insertTest")
    public void insertTest(){
        for (int i = 1 ; i < 10; i++) {
            User test = new User("王"+i,"男","数据" + i);
            userMapper.insert(test);
        }
    }
}

3. mapper

我们直接省略了service,简单一下哈!!

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface UserMapper extends BaseMapper<User> {
}

4. application.yml配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
server:
  port: 8089

spring:
  shardingsphere:
    mode:
      type: memory
    # 是否开启
    datasource:
      # 数据源(逻辑名字)
      names: m1
      # 配置数据源
      m1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/test?useSSL=false&autoReconnect=true&characterEncoding=UTF-8&serverTimezone=UTC
        username: root
        password: root
    # 分片的配置
    rules:
      sharding:
        # 表的分片策略
        tables:
          # 逻辑表的名称
          user:
            # 数据节点配置,采用Groovy表达式
            actual-data-nodes: m1.user_$->{0..1}
            # 配置策略
            table-strategy:
              # 用于单分片键的标准分片场景
              standard:
                sharding-column: cid
                # 分片算法名字
                sharding-algorithm-name: user_inline
            key-generate-strategy: # 主键生成策略
              column: cid  # 主键列
              key-generator-name: snowflake  # 策略算法名称(推荐使用雪花算法)
        key-generators:
          snowflake:
            type: SNOWFLAKE
        sharding-algorithms:
          user_inline:
            type: inline
            props:
              algorithm-expression: user_$->{cid % 2}
    props:
      # 日志显示具体的SQL
      sql-show: true


logging:
  level:
    com.wang.test.demo: DEBUG

mybatis-plus:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.example.demo.entity
  configuration:
    #在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法映射 address_book ---> addressBook
    map-underscore-to-camel-case: true

5. 启动类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@MapperScan("com.example.demo.mapper")
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

六、测试插入九条数据

==本次测试策略是:行表达式分片策略:inline==

1. 插入数据

输入 :localhost:8089/test/insertTest

==分片成功==

2. 单个查询

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@GetMapping("/selectOneTest")
public void selectOneTest(){

    User user = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getCid,736989417020850176L));
    System.out.println(user);

}

这时他会根据cid去自动获取去那个表中获取数据

3. 全查询

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@GetMapping("/selectListTest")
public void selectListTest(){

    List<User> list = userMapper.selectList(null);
    System.out.println(list);

}

由于没有条件,他会去把两个表UNION ALL进行汇总

4. 分页查询

需要先配置mybatis-plus分页配置类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@GetMapping("/selectListPage")
public void selectListPage(){
    IPage<User> page = new Page(1,6);
    IPage<User> userIPage = userMapper.selectPage(page,null);
    List<User> records = userIPage.getRecords();
    System.out.println(records);
}

我们user_0有5条数据,user_1有4条数据

==我们发现它会向所有的表中去进行一遍分页查询,第一个表数据不够就会加上另一个表分页拿到的值==

==分页size为3时,一个user_0就可以满足分页条件,就会忽略user_1的分页数据。==

5. 非分片属性查询

我们先把user_0表性别修改两个为女,然后进行查询!看看没有分片的字段是否能够只去user_0去查询

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@GetMapping("/selectListByGender")
public void selectListByGender(){

    List<User> list = userMapper.selectList(Wrappers.<User>lambdaQuery().eq(User::getGender, "女"));
    System.out.println(list);
}

有图可见:不是分片的字段查询,回去全连接表去查询一遍,效率和不分表一样了哈!!

6. 分片属性来自一个表in查询

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@GetMapping("/selectInList")
public void selectList(){
    List<User> users = userMapper.selectList(Wrappers.<User>lambdaQuery().in(User::getCid,736989417020850176L,736989418119757824L));
    System.out.println(users);
}

我们可以发现,我们根据分片字段进行in查询,sharding-jdbc会识别出来来自于那个表进而提高效率,不会所有的表进行全连接。

七、总结

这样就完成了最新版的sharding-jdbc的简单测试和一些坑的解决,总的来说配置很费劲,不能有一定的错误!


Q.E.D.

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-06-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
SpringBoot+Mybatis-Plus整合Sharding-JDBC实现单库分表及其相关测试
小编最近一直在研究关于分库分表的东西,前几天docker安装了mycat实现了分库分表,但是都在说mycat的bug很多。很多人还是倾向于shardingsphere,其实他是一个全家桶,有JDBC、Proxy 和 Sidecar组成,小编今天以最简单的JDBC来简单整合一下! 现在最新版已经是5.1.1,小编看了半天也没明白怎么配置,高版本的咱不会,咱只能搞低版本的试试,体验一下,后续在研究高版本的哈!
掉发的小王
2022/07/11
1.6K0
SpringBoot+Mybatis-Plus整合Sharding-JDBC实现单库分表及其相关测试
SpringBoot 2.x ShardingSphere分库分表实战
在之前我做项目的时候,数据量比较大,单表千万级别的,需要分库分表,于是在网上搜索这方面的开源框架,最常见的就是mycat,sharding-sphere,最终我选择后者,用它来做分库分表比较容易上手。
小东啊
2019/06/26
1.6K0
SpringBoot 2.x ShardingSphere分库分表实战
MYSQLg高级-------分库分表之核心Sharding-JDBC
2 、Sharding-JDBC ( 1 )主要目的是:简化对分库分表之后数据相关操作
默 语
2024/11/20
3600
MYSQLg高级-------分库分表之核心Sharding-JDBC
1.Sharding-JDBC 分库分表实战
AI码师
2023/09/11
2620
1.Sharding-JDBC 分库分表实战
SpringBoot整合Sharding实现水平分表
垂直分表: 将一张宽表(字段很多的表), 按照字段的访问频次进行拆分,就是按照表单结构进行 拆。
架构师修炼
2022/07/30
6980
SpringBoot整合Sharding实现水平分表
Mybatis-Plus动态表名插件实现数据库分表查询
Mybatis-Plus中提供了各种插件,乐观锁、多租户、动态表名。。。。今天来研究一下基于动态表名插件实现分表的案例
鱼找水需要时间
2023/02/16
2.8K0
Mybatis-Plus动态表名插件实现数据库分表查询
SpringBoot整合Sharding实现水平分表
上一篇文章,阿粉讲了关于分库分表是怎么进行切分的,都有什么切分方式,垂直切分和水平切分,还有就是使用什么工具进行分库分表,Sharding和Mycat我们回顾一下:
Java极客技术
2022/12/04
5270
SpringBoot整合Sharding实现水平分表
SpringBoot 2.x ShardingSphere分库分表实战
在之前我做项目的时候,数据量比较大,单表千万级别的,需要分库分表,于是在网上搜索这方面的开源框架,最常见的就是mycat,sharding-sphere,最终我选择后者,用它来做分库分表比较容易上手。
java架构师
2019/06/05
1.3K0
SpringBoot 2.x ShardingSphere分库分表实战
Sharding-Jdbc 实现读写分离、分库分表
ShardingSphere-Jdbc 定位为轻量级Java框架,在Java的Jdbc层提供的额外服务。它使用客户端直连数据库,以jar包形式提供服务,可理解为增强版的Jdbc驱动,完全兼容Jdbc和各种ORM框架
民工哥
2021/07/16
7970
Sharding-Jdbc 实现读写分离、分库分表
Sharding-JDBC教程:Spring Boot整合Sharding-JDBC实现读写分离
个人博客纯净版:https://www.fangzhipeng.com/db/2019/06/26/shardingjdbc-master-slave.html
方志朋
2022/01/06
1.5K0
Sharding-JDBC教程:Spring Boot整合Sharding-JDBC实现读写分离
SpringBoot使用Sharding-JDBC分库分表
有关Sharding-JDBC介绍这里就不在多说,之前Sharding-JDBC是当当网自研的关系型数据库的水平扩展框架,现在已经捐献给Apache,具体可以查看Github,地址是
lyb-geek
2019/03/07
1.3K0
SpringBoot使用Sharding-JDBC分库分表
在springboot项目中使用mybatis 集成 Sharding-JDBC
前段时间写了篇如何使用Sharding-JDBC进行分库分表的例子,相信能够感受到Sharding-JDBC的强大了,而且使用配置都非常干净。官方支持的功能还包括读写分离、分布式主键、强制路由等。这里再介绍下如何在分库分表的基础上集成读写分离的功能。
庞小明
2018/09/19
3.9K1
在springboot项目中使用mybatis 集成 Sharding-JDBC
SpringBoot 整合sharding jdbc实现分库分表
这里为了方便,我在接口中添加了参数,可以指定活动id,因为我们的库和表都是 activity_id % 2得到,所以通过设置奇偶数,判断分片策略是否生效
AI码师
2022/09/19
9170
SpringBoot 整合sharding jdbc实现分库分表
Sharding-JDBC 实现分库分表
一、概述 分库分表介绍:当数据量变大以后,单库单表已经不能满足需求。此时就需要进行拆分,拆分纬度分为垂直拆分和水平拆分。 水平拆分:比如 服务器1 上有 user_0, order_0; 服务器2 上有 user_1, order_1。此时 user_0 和 user_1 一起组成了用户表。 垂直拆分:用户表 放在服务器1上,订单表 放在服务器2上。 此处模拟使用两个数据库,每个数据库建两张表。库的拆分使用 city 字段(按城市存不同的库),表的拆分使用 id 取模。 二、数据准备 引入 pom
凡人飞
2020/09/21
1.1K0
SpringBoot + Mybatis-Plus + Sharding-JDBC实现数据库分表以及读写分离
本文Java工程使用Maven搭建,基于SpringBoot框架,ORM框架使用Mybatis-Plus(建议自己先搭建下Demo工程)。
小小土豆dev
2024/01/19
7150
Sharding-JDBC + MyBatis-Plus + Druid 实现读写分离(yml方式 和 xml方式)
一、概述 当业务数据越来越大时,就需要进行分库分表,而 Sharding-JDBC 框架就是能完整的实现分库分表、读写分离和分布式主键等功能。 此处实现读写分离功能。因为是测试,就在同一个 MySQL 中创建两个数据库来模拟。 Sharding-JDBC 的配置方式四种:Java,YAML,Spring命名空间和Spring Boot Starter。此处只讲 YAML 和 XML 方式。 二、数据准备 新建两个数据库:ds_0 和 ds_1CREATE DATABASE `ds_0` CHARACTER
凡人飞
2020/09/20
1.4K0
超详细sharding-jdbc分库分表实现(基于spring-boot)
demo 地址:https://github.com/FleyX/demo-project/tree/master/spring-boot/sjdemo 部分内容参考 ShardingSphere 官方文档:官方文档
小森啦啦啦
2019/07/15
9.8K0
超详细sharding-jdbc分库分表实现(基于spring-boot)
给小白演示 分库分表案例
大家好,我是老田,受群里小伙伴之邀,搞一个分库分表案例,这样让很多没用过分库分表的心里也有个底,不然永远看到的都是网上的各种概念和解决方案性的文章。
田维常
2021/07/15
4480
ShardingSphere解决海量数据分库分表
互联网高速发展,同时也带来的海量数据存储问题。传统关系型数据库的单库单表已经很难支撑,如何高效存储和访问这些数据,成为业内急需解决的问题。解决思路有两个方向:
微观技术
2021/04/19
8270
ShardingSphere解决海量数据分库分表
SpringBoot3分库分表
分库分表的设计和实现方式,在之前的内容中总结过很多,本文基于SpringBoot3和ShardingSphere5框架实现数据分库分表的能力;
知了一笑
2023/09/01
6860
SpringBoot3分库分表
推荐阅读
相关推荐
SpringBoot+Mybatis-Plus整合Sharding-JDBC实现单库分表及其相关测试
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验