SpringBoot+Mybatis-plus+shardingsphere实现分库分表的方案

 更新时间:2024年03月05日 12:11:42   作者:烟火缠过客  
实现亿级数据量分库分表的项目是一个挑战性很高的任务,下面是一个基于Spring Boot的简单实现方案,感兴趣的朋友一起看看吧

SpringBoot+Mybatis-plus+shardingsphere实现分库分表

介绍

实现亿级数据量分库分表的项目是一个挑战性很高的任务,下面是一个基于Spring Boot的简单实现方案:

  • 数据库选择:使用MySQL数据库,因为MySQL在分库分表方面有较成熟的解决方案。
  • 分库分表策略:可以采用水平分库分表的策略,根据一定的规则将数据分散存储在不同的数据库和表中,例如可以根据用户ID、订单ID等进行分片。
  • 数据分片策略:可以采用基于雪花算法的分布式ID生成器来生成全局唯一的ID,确保数据在不同数据库和表中的唯一性。
  • 数据同步:考虑到数据分散存储在不同的数据库和表中,需要实现数据同步机制来保证数据的一致性,可以使用Canal等开源工具来实现MySQL数据的实时同步。
  • 连接池优化:在处理大量数据时,连接池的配置尤为重要,可以使用Druid等高性能的连接池来提升数据库连接的效率。
  • 缓存机制:考虑使用Redis等缓存工具来缓存热点数据,减轻数据库的压力,提升系统性能。
  • 分布式事务:在分库分表的场景下,涉及到跨库事务,可以考虑使用分布式事务框架,如Seata等来保证事务的一致性。

监控与调优:实时监控数据库的性能指标,及时调整分片策略和数据库配置,保证系统的稳定性和性能。

引入依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3</version>
        </dependency>
        <!--分库分表-->
        <!-- Sharding-JDBC -->
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
            <version>5.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

yaml配置

server:
  port: 10086
spring:
  shardingsphere:
    # 数据源配置
    datasource:
      # 数据源名称,多数据源以逗号分隔
      names: db0,db1
      db0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://127.0.0.1:3306/ds0?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
        username: root
        password: root
      db1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://127.0.0.1:3306/ds1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
        username: root
        password: root
    # 分片规则配置
    rules:
      sharding:
        # 分片算法配置
        sharding-algorithms:
          database-inline:
            # 分片算法类型
            type: INLINE
            props:
              # 分片算法的行表达式(算法自行定义,此处为方便演示效果)
              algorithm-expression: db$->{age % 2}
          table-inline:
            # 分片算法类型
            type: INLINE
            props:
              # 分片算法的行表达式
              algorithm-expression: user_$->{age % 3}
        tables:
          # 逻辑表名称
          user:
            # 行表达式标识符可以使用 ${...} 或 $->{...},但前者与 Spring 本身的属性文件占位符冲突,因此在 Spring 环境中使用行表达式标识符建议使用 $->{...}
            actual-data-nodes: db${0..1}.user_${0..2}
            # 分库策略
            database-strategy:
              standard:
                # 分片列名称
                sharding-column: age
                # 分片算法名称
                sharding-algorithm-name: database-inline
            # 分表策略
            table-strategy:
              standard:
                # 分片列名称
                sharding-column: age
                # 分片算法名称
                sharding-algorithm-name: table-inline
    # 属性配置
    props:
      # 展示修改以后的sql语句
      sql-show: true

DDL准备

数据库ds0

-- ds0.user_0 definition
CREATE TABLE `user_0` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(32) NOT NULL COMMENT '姓名',
  `age` int NOT NULL COMMENT '年龄',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='用户表';
-- ds0.user_1 definition
CREATE TABLE `user_1` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(32) NOT NULL COMMENT '姓名',
  `age` int NOT NULL COMMENT '年龄',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='用户表';
-- ds0.user_2 definition
CREATE TABLE `user_2` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(32) NOT NULL COMMENT '姓名',
  `age` int NOT NULL COMMENT '年龄',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='用户表';

数据库ds1

-- ds1.user_0 definition
CREATE TABLE `user_0` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(32) NOT NULL COMMENT '姓名',
  `age` int NOT NULL COMMENT '年龄',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='用户表';
-- ds1.user_1 definition
CREATE TABLE `user_1` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(32) NOT NULL COMMENT '姓名',
  `age` int NOT NULL COMMENT '年龄',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='用户表';
-- ds1.user_2 definition
CREATE TABLE `user_2` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(32) NOT NULL COMMENT '姓名',
  `age` int NOT NULL COMMENT '年龄',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='用户表';

entity

package com.kang.sharding.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("user")  
public class User {
    @TableId(value = "id",type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    // getter, setter, toString...  
}

cotroller

package com.kang.sharding.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.kang.sharding.entity.User;
import com.kang.sharding.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController  
@RequestMapping("/user")  
public class UserController {  
    @Autowired  
    private UserService userService;
    @PostMapping ("add")
    public boolean createUser(@RequestBody User user) {
        return userService.save(user);  
    }
    @PostMapping ("update")
    public boolean updateByAge(@RequestBody User user){
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        // 分片数据不允许更新,否则会报错
        updateWrapper.eq(User::getAge,user.getAge()).set(User::getName,user.getName());
        return userService.update(updateWrapper);
    }
    @GetMapping ("delete")
    public boolean deleteUserByAge(@RequestParam("age") Integer age) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getAge,age);
        return userService.remove(queryWrapper);
    }
    @GetMapping("/{age}")
    public List<User> getUserByAge(@PathVariable Integer age) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getAge,age);
        return userService.list(queryWrapper);
    }  
    // 其他方法...  
}

service

package com.kang.sharding.service;
import com.kang.sharding.entity.User;
import com.kang.sharding.mapper.UserMapper;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;  
@Service  
public class UserService extends ServiceImpl<UserMapper, User> {
}

Mapper

package com.kang.sharding.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.kang.sharding.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}

启动类

package com.kang.sharding;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ShardingJdbcProjectApplication {
    public static void main(String[] args) {
        SpringApplication.run(ShardingJdbcProjectApplication.class, args);
    }
}

测试

添加

修改

查询

删除

在这里插入图片描述

总结

这只是个简单的入门示例,后续深入研究

到此这篇关于SpringBoot+Mybatis-plus+shardingsphere实现分库分表的文章就介绍到这了,更多相关SpringBoot Mybatis-plus shardingsphere分库分表内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • RSA加密算法java简单实现方法(必看)

    RSA加密算法java简单实现方法(必看)

    下面小编就为大家带来一篇RSA加密算法java简单实现方法(必看)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • 一文搞懂Java中对象池的实现

    一文搞懂Java中对象池的实现

    池化并不是什么新鲜的技术,它更像一种软件设计模式,主要功能是缓存一组已经初始化的对象,以供随时可以使用。本文将为大家详细讲讲Java中对象池的实现,需要的可以参考一下
    2022-07-07
  • JDK15正式发布(新增功能预览)

    JDK15正式发布(新增功能预览)

    这篇文章主要介绍了JDK15正式发布,新增功能预览,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2020-09-09
  • java7 新I/O知识点详解

    java7 新I/O知识点详解

    在本篇文章里小编给大家整理的是关于java7 新I/O知识点详解,有需要的朋友们可以学习下。
    2019-11-11
  • springboot+mysql+mybatis实现控制台打印sql

    springboot+mysql+mybatis实现控制台打印sql

    在Spring Boot中使用MyBatis与MySQL,并希望在控制台打印SQL语句,可以通过配置MyBatis的日志级别来实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • springsecurity实现登录验证以及根据用户身份跳转不同页面

    springsecurity实现登录验证以及根据用户身份跳转不同页面

    Spring Security是一种基于Spring框架的安全技术,用于实现身份验证和访问控制,本文介绍了如何使用Spring Security,结合session和redis来存储用户信息,并通过编写特定的登录处理类和Web配置,实现用户登录和注销功能
    2024-09-09
  • SpringBoot最新定时任务的7种实现方案

    SpringBoot最新定时任务的7种实现方案

    在现代应用中,定时任务是一个非常常见的需求,本文将通过7种方式讲解如何在SpringBoot中实现定时任务,包括使用@Scheduled注解、ScheduledExecutorService、Quartz、SpringTaskScheduler、Redis、XXL-JOB和Elastic-Job等,各有优缺点,选择时应根据实际需求进行考虑
    2024-12-12
  • java中instanceof 关键字作用和实际用途详解

    java中instanceof 关键字作用和实际用途详解

    这篇文章主要介绍了java中instanceof 关键字作用和实际用途,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • springboot不同环境使用不同配置文件打包方式

    springboot不同环境使用不同配置文件打包方式

    这篇文章主要介绍了springboot不同环境使用不同配置文件打包方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Java中List排序的三种实现方法实例

    Java中List排序的三种实现方法实例

    其实Java针对数组和List的排序都有实现,对数组而言你可以直接使用Arrays.sort,对于List和Vector而言,你可以使用Collections.sort方法,下面这篇文章主要给大家介绍了关于Java中List排序的三种实现方法,需要的朋友可以参考下
    2021-12-12

最新评论