前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot+Mybatis-Plus整合Sharding-JDBC实现单库分表及其相关测试

SpringBoot+Mybatis-Plus整合Sharding-JDBC实现单库分表及其相关测试

作者头像
掉发的小王
发布2022-07-11 16:17:13
1.4K0
发布2022-07-11 16:17:13
举报
文章被收录于专栏:小王知识分享

一、前言

小编最近一直在研究关于分库分表的东西,前几天docker安装了mycat实现了分库分表,但是都在说mycat的bug很多。很多人还是倾向于shardingsphere,其实他是一个全家桶,有JDBC、Proxy 和 Sidecar组成,小编今天以最简单的JDBC来简单整合一下! 现在最新版已经是5.1.1,小编看了半天也没明白怎么配置,高版本的咱不会,咱只能搞低版本的试试,体验一下,后续在研究高版本的哈!

主要分享一下在搭建过程中需要的坑,帮助后来人铺路!!

如果想看mycat的可以看一下小编之前写的文章哈:Docker安装Mycat和Mysql进行水平分库分表实战

==写在前面==:小编本来用的是4.1.1,但是运行就报错,后面再和大家说,所以本教学最终使用的版本是:4.0.0-RC1,如果嫌弃版本太老可以走了,不要浪费时间!后续小编研究明白就会更新新版本的哈

二、导入maven依赖

代码语言:javascript
复制
<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>sharding-jdbc-spring-boot-starter</artifactId>
    <version>4.0.0-RC1</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>
<!-- Druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.21</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>

三、4.1.1版本bug解决

前面说了,4.1.1这个版本有问题,现在来详细说一下哈!

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
Caused by: java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
	at org.springframework.util.Assert.notNull(Assert.java:201) ~[spring-core-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.mybatis.spring.support.SqlSessionDaoSupport.checkDaoConfig(SqlSessionDaoSupport.java:122) ~[mybatis-spring-2.0.6.jar:2.0.6]
	at org.mybatis.spring.mapper.MapperFactoryBean.checkDaoConfig(MapperFactoryBean.java:73) ~[mybatis-spring-2.0.6.jar:2.0.6]
	at org.springframework.dao.support.DaoSupport.afterPropertiesSet(DaoSupport.java:44) ~[spring-tx-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1853) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1790) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
	... 30 common frames omitted

经过长达1小时的不断改进,最终解决为用低版本的!如果有大佬有其他解决方案,欢迎评论区交流哈!!

代码语言:javascript
复制
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>4.0.0-RC1</version>
</dependency>

四、新建表

1. 新建二张表

命名为:user_0user_1

代码语言:javascript
复制
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
复制
@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
复制
@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
复制
public interface UserMapper extends BaseMapper<User> {
}

4. application.yml配置

代码语言:javascript
复制
server:
  port: 8089

spring:
  main:
    #  一个实体类对应三张表,覆盖,不然启动报错
    allow-bean-definition-overriding: true
  # Sharding-JDBC的配置
  shardingsphere:
    datasource:
      # 数据源(逻辑名字)
      names: m1
      # 配置数据源
      m1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=true&createDatabaseIfNotExist=true&serverTimezone=GMT&nullNamePatternMatchesAll=true
        username: root
        password: root
    # 分片的配置
    sharding:
      # 表的分片策略
      tables:
        # 逻辑表的名称
        user:
          # 数据节点配置,采用Groovy表达式
          actual-data-nodes: m1.user_$->{0..1}
          # 配置策略
          table-strategy:
            # 精确匹配
            inline:
              sharding-column: cid
              algorithm-expression: user_$->{cid % 2}
          # 主键生成策略
          key-generator:
            # 主键
            column: cid
            # 雪花算法
            type: SNOWFLAKE
    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
复制
@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. 展示插入数据

在这里插入图片描述
在这里插入图片描述

==分片成功==

3. 单个查询

代码语言:javascript
复制
@GetMapping("/selectTest")
public void selectTest(){

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

}

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

在这里插入图片描述
在这里插入图片描述

4. 全查询

代码语言:javascript
复制
@GetMapping("/selectListTest")
public void selectListTest(){

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

}

由于没有条件,他会去两个表中都进行查询然后汇总给我们

在这里插入图片描述
在这里插入图片描述

5. 分页查询

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

代码语言:javascript
复制
@Configuration
public class MybatisPlusConfig {

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

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

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

在这里插入图片描述
在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述

6. 非分片属性查询

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

代码语言:javascript
复制
@GetMapping("/selectListByGender")
public void selectListByGender(){

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

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

在这里插入图片描述
在这里插入图片描述

七、总结

这样就完成了一个简单的分表的测试,后面小编在研究一下其他的分片操作,后续在写博客进行更新。


Q.E.D.

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言
  • 二、导入maven依赖
  • 三、4.1.1版本bug解决
  • 四、新建表
    • 1. 新建二张表
      • 2. 数据库结构
      • 五、框架全局展示
        • 1. User实体类
          • 2. controller
            • 3. mapper
              • 4. application.yml配置
                • 5. 启动类
                • 六、测试插入九条数据
                  • 1. 插入数据
                    • 2. 展示插入数据
                      • 3. 单个查询
                        • 4. 全查询
                          • 5. 分页查询
                            • 6. 非分片属性查询
                            • 七、总结
                            相关产品与服务
                            容器服务
                            腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档