springboot 按月分表的实现方式

yizhihongxing

下面是springboot按月分表的实现方式完整攻略:

第一步:创建表和初始化数据

首先,我们需要创建一张原始的订单表,结构如下:

CREATE TABLE `order` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `order_no` varchar(64) DEFAULT NULL COMMENT '订单号',
  `order_amount` decimal(10,2) DEFAULT NULL COMMENT '订单金额',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';

接下来,初始化一些数据,可以通过以下SQL语句插入数据:

INSERT INTO `order`(order_no, order_amount, create_time) VALUES 
('202201010001', 100, '2022-01-01 10:10:10'), 
('202201020001', 300, '2022-01-02 10:10:10'),
('202202010001', 200, '2022-02-01 10:10:10');

第二步:实现按月分表的方式

定义分表规则

首先,我们需要定义分表规则,这里我们选择按照订单创建时间来进行分表,即每个月一张表。

创建分表的SQL语句

接下来,我们可以通过以下SQL语句来创建按月分表的订单表:

CREATE TABLE IF NOT EXISTS `order_{0}` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `order_no` varchar(64) DEFAULT NULL COMMENT '订单号',
  `order_amount` decimal(10,2) DEFAULT NULL COMMENT '订单金额',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';

上面的语句中,{0}表示动态的表名后缀,例如表名为order_202201

实现分表的代码逻辑

最后,我们可以通过实现springboot的拦截器和多数据源来实现按月分表的逻辑。

首先,我们要实现拦截器,来根据订单创建的时间来判断应该使用哪个数据源,代码示例:

@Component
public class OrderTableInterceptor implements HandlerInterceptor {

    private static final String TABLE_PREFIX = "order_";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String orderNo = request.getParameter("orderNo");
        if (StringUtils.isEmpty(orderNo)) {
            throw new BusinessException("orderNo不能为空");
        }
        Date createTime = getOrderCreateTime(orderNo);
        if (createTime == null) {
            throw new BusinessException("获取订单创建时间失败");
        }

        String dataSourceKey = TABLE_PREFIX + DateUtil.format(createTime, "yyyyMM");
        DataSourceContextHolder.setDataSourceKey(dataSourceKey);
        return true;
    }

    /**
     * 根据订单号获取订单创建时间
     */
    private Date getOrderCreateTime(String orderNo) {
        // 查询订单,返回订单创建时间
        // 这里假设根据订单号从数据库中查询出来的订单创建时间为:2022-01-01 10:10:10
        return DateUtil.parse("2022-01-01 10:10:10");
    }
}

在上面的代码中,我们首先根据订单号获取订单创建时间,然后将订单创建时间格式化成表名的后缀,例如订单创建时间为2022-01-01 10:10:10,则表名后缀为202201。最后,使用DataSourceContextHolder来动态切换数据源。

接下来,我们还需要实现多数据源的配置和切换,这里我们采用springboot官方推荐的AbstractRoutingDataSource来实现,代码示例:

public class DynamicDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDataSourceKey();
    }
}

其中,DataSourceContextHolder就是用来保存当前线程要使用的数据源的key。

最后,我们需要在springboot的配置文件中加入以下配置,来指定使用DynamicDataSource作为数据源:

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/order?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: root
    initial-size: 3
    min-idle: 3
    max-active: 500
    max-wait: 60000
    time-between-eviction-runs-millis: 60000
    min-evictable-idle-time-millis: 300000
    validation-query: SELECT 1 FROM DUAL
    test-while-idle: true
    test-on-borrow: false
    test-on-return: false

datasource:
  # 按月分表的数据源配置
  order_202201:
    url: jdbc:mysql://localhost:3306/order_202201?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
  order_202202:
    url: jdbc:mysql://localhost:3306/order_202202?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

在上面的配置中,我们针对每个月的订单表都配置了一个单独的数据源。

第三步:测试

最后,我们可以通过以下代码来测试按月分表的实现方式:

@RestController
public class OrderController {

    @Autowired
    OrderMapper orderMapper;

    @GetMapping("/order")
    public List<Order> getOrderList(@RequestParam String orderNo) {
        return orderMapper.getOrderList(orderNo);
    }

    @PostMapping("/order")
    public Order addOrder(@RequestBody Order order) {
        orderMapper.addOrder(order);
        return order;
    }
}

其中,OrderMapper是用来操作数据库的Mapper,在里面会使用我们刚刚实现的动态数据源的逻辑。在测试时,可以通过Postman等工具来发送请求,例如:

  • GET http://localhost:8080/order?orderNo=202201010001
  • POST http://localhost:8080/order

测试成功后,就可以使用按月分表的方式来快速的拆分大量的订单数据了。

示例

下面是两个示例:

示例1

假设当前时间为2022年1月,我们要添加一个订单,订单创建时间为2022年1月3日,订单号为202201030001。发送POST请求如下:

POST http://localhost:8080/order
Content-Type: application/json

{
    "orderNo": "202201030001",
    "orderAmount": 200,
    "createTime": "2022-01-03 00:00:00"
}

返回结果如下:

{
    "id": 4,
    "orderNo": "202201030001",
    "orderAmount": 200.00,
    "createTime": "2022-01-03T00:00:00.000+00:00"
}

在数据库中,会自动创建一张名为order_202201的订单表,并且将该订单插入到该表中。

示例2

假设现在要查询订单号为202201010001的订单,发送GET请求如下:

GET http://localhost:8080/order?orderNo=202201010001

返回结果如下:

[
    {
        "id": 1,
        "orderNo": "202201010001",
        "orderAmount": 100.00,
        "createTime": "2022-01-01T10:10:10.000+00:00"
    }
]

在查询时,程序会根据订单创建时间来确定使用哪张表,例如该订单创建时间为2022年1月1日,所以会查询order_202201表,并返回查询结果。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:springboot 按月分表的实现方式 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • Java8加java10等于Java18的版本查看及特性详解

    Java8加Java10等于Java18的版本查看及特性详解 在本篇攻略中,我们会讲解如何通过一些简单的命令来查看Java版本,并介绍一些Java8和Java10的重要特性。同时,我们还会提到Java18这一版本是否真实存在的问题。 1. 查看Java版本 1.1 使用java -version命令 在命令行中键入java -version命令,可查看当前系…

    Java 2023年5月19日
    00
  • 如何简单使用mybatis注解

    下面我来详细讲解如何简单使用mybatis注解。 1. 引入mybatis注解依赖 首先在项目中引入mybatis注解依赖,例如: <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <ver…

    Java 2023年5月20日
    00
  • SpringBoot集成JPA持久层框架,简化数据库操作

    以下是详细讲解“SpringBoot集成JPA持久层框架,简化数据库操作”的完整攻略。 1. 引入JPA依赖 在SpringBoot中引入JPA依赖非常简单,只需要在Maven或Gradle的配置文件中添加以下依赖就可以了。 Maven依赖配置 <dependency> <groupId>org.springframework.boo…

    Java 2023年5月20日
    00
  • 剑指Offer之Java算法习题精讲数组查找与字符串交集

    剑指Offer之Java算法习题精讲 – 数组查找与字符串交集 一、本章介绍 本章将会对“剑指Offer”系列书籍中有关数组查找与字符串交集的核心算法习题进行总结和分析。我们将会结合具体的算法样例进行讲解,并且会针对其中涉及到的算法思想与编程技巧进行加深细致的探讨。 二、数组查找 1. 二维数组中的查找 题目描述: 在一个二维数组中,每一行都按照从左到右递增…

    Java 2023年5月19日
    00
  • SpringMVC4 + MyBatis3 + SQL Server 2014整合教程(含增删改查分页)

    下面是关于“SpringMVC4 + MyBatis3 + SQL Server 2014整合教程(含增删改查分页)”的完整攻略,包含两个示例说明。 SpringMVC4 + MyBatis3 + SQL Server 2014整合教程 在本文中,我们将介绍如何使用SpringMVC4、MyBatis3和SQL Server 2014实现一个简单的增删改查分…

    Java 2023年5月17日
    00
  • 如何使用intellij IDEA搭建Spring Boot项目

    使用IntelliJ IDEA搭建Spring Boot项目的完整攻略如下: 安装IntelliJ IDEA 首先,我们需要安装IntelliJ IDEA。可以从官方网站下载并安装最新版本的IntelliJ IDEA。 创建Spring Boot项目 在IntelliJ IDEA中,我们可以使用Spring Initializr来创建Spring Boot项…

    Java 2023年5月15日
    00
  • Java OpenSSL生成的RSA公私钥进行数据加解密详细介绍

    针对“Java OpenSSL生成的RSA公私钥进行数据加解密详细介绍”的话题,以下是完整攻略的介绍: 一、概述 OpenSSL是一个开源的安全套接字层(SSL)实现库,能够实现多种安全协议,包括SSL和TLS。Java OpenSSL是使用Java编写的,利用OpenSSL库生成RSA公私钥,以及使用公私钥进行数据的加解密。 本文将详细介绍Java Ope…

    Java 2023年5月19日
    00
  • Spring Boot集成Kafka的示例代码

    下面我将详细讲解“Spring Boot集成Kafka的示例代码”的完整攻略: 1. 准备工作 首先,我们需要在本地安装好 Kafka,然后创建一个 Topic。 2. 添加依赖 在 Spring Boot 项目中,我们需要使用以下两个依赖: <dependency> <groupId>org.springframework.kafk…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部