看完这篇,别再说不会Spring 分库分表了

news2024/12/23 0:50:22

多数据源,读写分离,分库分表,基本上已经是现在任何一个项目的基本配置了,在之前的文章
Spring多数据源实现icon-default.png?t=N6B9https://blog.csdn.net/wangerrong/article/details/131910740  里讲了多数据源的实现,其实已经包含了读写分离(master和slave分别配置主库和只读库就好了),现在就记录下分库分表的实现过程。

1,引入jdbc, mybatis, shardingsphere等依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    <version>2.4.2</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.30</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>8.0.30</version>
</dependency>
<!-- jpa持久化工具 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <version>2.7.6</version>
</dependency>
<!-- 必须引入的包 ShardingSphere -->
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
    <version>5.2.0</version>
</dependency>

2,建立数据库和数据表

 

3,添加分库分表配置到bootsrap.yml

server:
  port: 9102
# NaCos
spring:
  application:
    name: deviceservice
  shardingsphere:
    # 数据源配置
    datasource:
      # 数据源名称,多数据源以逗号分隔
      names: db0,db1
      db0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://xxxx:3306/db_0?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
        username: root
        password: xxxxxxxxx
      db1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://yyyy:3306/db_1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
        username: root
        password: yyyyyyyyy
    # 分片规则配置
    rules:
      sharding:
        # 分片算法配置
        sharding-algorithms:
          database-inline:
            # 分片算法类型
            type: INLINE
            props:
              # 分片算法的行表达式(算法自行定义,此处为方便演示效果)
              algorithm-expression: db$->{order_id%10 > 4?1:0}
              # 关键,查询时是否在所有分库分表中查询
              allow-range-query-with-inline-sharding: true
          table-inline:
            # 分片算法类型
            type: INLINE
            props:
              # 分片算法的行表达式
              algorithm-expression: t_order_$->{order_id % 3}
              # 关键,查询时是否在所有分库分表中查询
              allow-range-query-with-inline-sharding: true
        tables:
          # 逻辑表名称
          t_order:
            # 行表达式标识符可以使用 ${...} 或 $->{...},但前者与 Spring 本身的属性文件占位符冲突,因此在 Spring 环境中使用行表达式标识符建议使用 $->{...}
            actual-data-nodes: db${0..1}.t_order_${0..2}
            # 分库策略
            database-strategy:
              standard:
                # 分片列名称
                sharding-column: order_id
                # 分片算法名称
                sharding-algorithm-name: database-inline
            # 分表策略
            table-strategy:
              standard:
                # 分片列名称
                sharding-column: order_id
                # 分片算法名称
                sharding-algorithm-name: table-inline
    # 属性配置
    props:
      # 展示修改以后的sql语句
      sql-show: true
  profiles:
    active: dev
---
spring:
  config:
    activate:
      on-profile: dev
    import: optional:config\application-dev.yml

4,  实体类和mapper

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("t_order")
public class Order {
    private long orderId;
    private String createdTime;
}
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("t_device")
public class Device {
    private long deviceId;
    private String name;
    private String createdTime;
}

 

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xxx.domain.Order;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

@Mapper
@Repository
public interface OrderMapper extends BaseMapper<Order> {

}
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xxx.domain.Device;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

@Mapper
@Repository
public interface DeviceMapper extends BaseMapper<Device> {
}

 


import com.xxx.domain.Order;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public interface OrderService {
    public void saveOrder(Order order);

    public List<Order> list();

    public void delete(long orderId);

    public void update(long orderId);
}
import com.xxx.domain.Device;
import org.springframework.stereotype.Service;

@Service
public interface DeviceService {
    public void saveDevice(Device device);
}

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xxx.domain.Order;
import com.xxx.mapper.OrderMapper;
import com.xxx.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;

    @Override
    public void saveOrder(Order order) {
        orderMapper.insert(order);
    }

    @Override
    public void delete(long orderId) {
        QueryWrapper qw = new QueryWrapper<Order>();
        qw.eq("order_id",orderId);
        orderMapper.delete(qw);
    }

    @Override
    public void update(long orderId) {
        Order order = new Order();
        order.setOrderId(orderId);
        order.setCreatedTime("2200-07-26 00:00:01");

        QueryWrapper qw = new QueryWrapper<Order>();
        qw.eq("order_id",orderId);
        orderMapper.update(order,qw);
    }


    @Override
    public List<Order> list() {
        QueryWrapper qw = new QueryWrapper<Order>();
        qw.ge("order_id",0);
        qw.orderByAsc("order_id");
        return orderMapper.selectList(qw);
    }
}
import com.xxx.domain.Device;
import com.xxx.mapper.DeviceMapper;
import com.xxx.service.DeviceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class DeviceServiceImpl implements DeviceService {
    @Autowired
    private DeviceMapper deviceMapper;

    @Override
    public void saveDevice(Device device) {
        deviceMapper.insert(device);
    }
}

import com.xxx.common.UserContext;
import com.xxx.domain.Device;
import com.xxx.domain.Order;
import com.xxx.service.DeviceService;
import com.xxx.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@RefreshScope
@Slf4j
@RequestMapping("/device")
public class DeviceController extends AbstractController{
    @Autowired
    private OrderService orderService;
    @Autowired
    private DeviceService devieService;

    @GetMapping("/save")
    public String save(@RequestParam("orderId") int orderId){
        Order order = new Order();
        order.setOrderId(orderId);
        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String dateStr = sdf.format(new Date());
        order.setCreatedTime(dateStr);
        orderService.saveOrder(order);

        Device device = new Device();
        device.setDeviceId(orderId);
        device.setName(orderId+"_"+dateStr);
        device.setCreatedTime(dateStr);
        devieService.saveDevice(device);

        return "success";
    }

    @GetMapping("/delete")
    public String delete(@RequestParam("orderId") long orderId) {
        orderService.delete(orderId);
        return "success";
    }

    @GetMapping("/update")
    public String update(@RequestParam("orderId") int orderId) {
        orderService.update(orderId);
        return "success";
    }

    @GetMapping("/list")
    public List<Order> list() {
        return orderService.list();
    }
}

上面代码是一个简单的验证:

1,  通过对做了分库分表配置的t_order表的增删改查,验证分库分表后的增删改查是否生效,验证通过

2,验证对没做分库分表配置的t_device表的增加,验证正常数据库操作(默认走spring.shardingsphere.datasource.names: db0,db1配置里的第一个数据库)是否生效,验证通过

5,总结

Springboot + shardingsphere 实现分库分表的需求,比较简单,但是要想真正地投入实用,还有很多路要走,比如实现自定义分库分表规则的算法,自定义分布式表的主键ID,基于分库分表后的排序(默认已实现按分库分表的列进行排序)和分页等等等。

码字不易,记得点赞关注哟!

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/790957.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

广东省《5A物理抗菌纺织品》团体标准颁布

近日&#xff0c;经广东省标准化协会批准发布由广东人仁康科技有限公司主导制定的《5A物理抗菌纺织品》&#xff08;T/GDBX 073—2023&#xff09;团体标准&#xff0c;于2023年7月21日发布并实施。 根据标准制修订工作流程&#xff0c;该项标准2022年由人仁康和广检集团组织起…

【【51单片机AD/DA的分析】】

51单片机AD/DA的分析 看似单片机实验&#xff0c;其实是要学好数电 模数转换 与 数模转换 运算放大器 DA的转换就是利用运算放大器实现的 输出电压v0-(D7~D0)/256 x (VrefxRfb)/R D7~D0 就是我们控制的按键看输入多少 然后再划分256份 Vref是我们设置的一个基准电压 PWM 这种…

若依分离版——解决配置双数据源oracle,mysql分页错误问题

1. 按照若依的手册配置双数据源mysql&#xff0c;oracle 2. 在service指定 数据源 DataSource(value DataSourceType.MASTER) 或者DataSource(value DataSourceType.SLAVE) Service public class SysPostServiceImpl implements ISysPostService {/*** 查询岗位信息集合* …

分享10个NodeJS相关的专业级工具

Node.js已成为开发人员创建强大且可扩展的Web应用程序的首选选项。根据2022年StackOverflow开发者调查&#xff0c;Node.js被评为专业开发人员中使用最广泛的Web框架。这个成功可以归功于其庞大的生态系统&#xff0c;其中提供了许多工具和框架。了解并接纳这个生态系统对于优化…

前端面试题-JS进阶

1 内置类型 JS 中分为七种内置类型&#xff0c;七种内置类型⼜分为两⼤类型&#xff1a;基本类型和对象&#xff08; Object &#xff09;。基本类型有六种&#xff1a; null &#xff0c; undefined &#xff0c; boolea n&#xff0c; number &#xff0c; string &#xff…

【数据动态填充到element表格;将带有标签的数据展示为文本格式】

一&#xff1a;数据动态填充到element表格&#xff1b; 二&#xff1a;将带有标签的数据展示为文本格式&#xff1b; 1、 <el-row><el-col :span"24"><el-tabs type"border-card"><el-tab-pane label"返回值"><el-…

计算机流水线在正常程序中的体现(效果可视)

众所周知,流水线技术对于软件开发人员不是可见的(visiable),毕竟已经在在机器语言之下,是组成机器语言的基本逻辑 但今天我就带领大家看看我新发现的结果,那就是流水线的可视效果,包括流水线预测技术的侧面体现,当然也是可见的 首先我先声明一下需要的基础,需要懂16位以及32位操…

leetcode 面试题01.04 回文排列

⭐️ 题目描述 &#x1f31f; leetcode链接&#xff1a;回文排列 思路&#xff1a;回文串两种可能。只有一个字符出现1次其他字符都是偶数次。要么都是偶数次。统计字母的个数即可。 代码&#xff1a; bool canPermutePalindrome(char* s){// 回文串两种可能// 1. 只有一个字…

几百本常用计算机开发语言电子书链接

GitHub - XiangLinPro/IT_book: 本项目收藏这些年来看过或者听过的一些不错的常用的上千本书籍&#xff0c;没准你想找的书就在这里呢&#xff0c;包含了互联网行业大多数书籍和面试经验题目等等。有人工智能系列&#xff08;常用深度学习框架TensorFlow、pytorch、keras。NLP、…

JavaWeb银行项目

主要功能 实现了贷款、存款、理财、提现、充值、开户、绑卡、转账等功能。 介绍 1、这个是一个类似有支付宝一样的web项目。 2、登录和注册&#xff0c;都是通过手机号来进行的。 3、注册的新用户需要先进行开户操作&#xff0c;然后进行绑卡操作。 4、在开户的时候回给你…

计算机专业还会继续火热吗

目录 引言 1.计算机专业火热的原因 2.学好计算机需要的技能 3.计算机未来会持续火热吗 4.博主的建议 引言 今年&#xff0c;张雪峰老师在高考志愿填报领域再次火了一把。他主张专业的实用性&#xff0c;建议家长填报那些未来不愁就业的专业&#xff0c;不好就业的专业不要去…

顺序表操作详解

文章目录 一、线性表二、顺序表1、概念2、接口实现1>初始化顺序表2>操作结束后释放空间3>打印顺序表4>尾插5>头插6>头删7>尾删8>顺序表查找9>顺序表在pos位置插入x10>顺序表删除pos位置的值 一、线性表 线性表&#xff08;linear list&#xff0…

爬取微博热搜榜并进行数据分析

设计方案 爬虫爬取的内容 &#xff1a;爬取微博热搜榜数据。 网络爬虫设计方案概述 用requests库访问页面用get方法获取页面资源&#xff0c;登录页面对页面HTML进行分析&#xff0c;用beautifulsoup库获取并提取自己所需要的信息。再讲数据保存到CSV文件中&#xff0c;进行…

《深度探索c++对象模型》第二章笔记

非原创&#xff0c;在学习 目录 2 构造函数语意学(The Semantics of Constructors) 2.1 Default Constructor的构建操作 “带有Default Constructor”的Member Class Object “带有Default Constructor”的Base Class “带有一个Virtual Function”的Class “带有一个Virtu…

机器学习深度学习——向量求导问题

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——图像分类数据集 &#x1f4da;订阅专栏&#xff1a;机器学习&&深度学习 希望文章对你们有所帮助…

【低代码专题方案】iPaaS运维方案,助力企业集成平台智能化高效运维

01 场景背景 随着IT行业的发展和各家企业IT建设的需要&#xff0c;信息系统移动化、社交化、大数据、系统互联、数据打通等需求不断增多&#xff0c;企业集成平台占据各个企业领域&#xff0c;成为各业务系统数据传输的中枢。 集成平台承接的业务系统越多&#xff0c;集成平台…

详解zookeeper安装使用

目录 1.概述 1.1.功能 1.2.特点 1.3.数据结构 2.安装 2.1.Windows 2.2.Linux 3.基础操作 3.1.增 3.2.删 3.3.改 3.4.查 3.5.监听 4.JAVA操作Zookeeper 4.1.依赖 4.2.客户端 4.3.增 4.4.删 4.5.查 4.6.改 1.概述 1.1.功能 zookeeper&#xff0c;Apache旗下…

pytorch:使用tensorboardX可视化网络模型时add_graph位置报错

1.报错信息 TypeError: graph() got an unexpected keyword argument ‘use_strict_trace’ 提示 graph()这个函数多了一个参数’use_strict_trace’&#xff1b; 也觉得应该是tensorboardX版本问题&#xff0c;但uninstall 再insatall之后也不行&#xff0c;用另一台机子也…

STM32H5开发(3)----电源控制RCC

STM32H5开发----3.电源控制&RCC STM32H503 供电STM32H562/563/573 LDO 供电STM32H562/563/573 SMPS供电LDO/SMPS 供电PWR 特性电源电压监测温度监测低功耗模式低功耗模式-SLEEP 模式低功耗模式-STOP 模式低功耗模式-STANDBY模式低功耗模式监控管脚VBAT模式复位触发源时钟源…

主机漏洞利用演示MS17-010(永恒之蓝)

ms17-010危害&#xff1a;对被攻击方的电脑造成蓝屏&#xff01; 申明&#xff1a;本篇文章的用意仅做学习使用 网络搭建环境&#xff1a; 软件&#xff1a;Vmware Workstation 17 攻击机&#xff1a;Kali 靶机环境&#xff1a;Windows 7 Nmap软件的基本功能&#xff1a; …