Spring Boot集成ShardingSphere分片利器 AutoTable (二)—— 自动分片算法示例 | Spring Cloud 46

news2024/11/18 17:18:51

一、前言

在前面我们通过以下章节对ShardingSphereAutoTable 有了基础的了解:

Spring Boot集成ShardingSphere分片利器 AutoTable (一)—— 简单体验 | Spring Cloud 45

书接上回,本章进行对AutoTable 支持的自动分片算法进行逐一示例说明。

二、示例搭建

示例采用springboot集成shardingsphere-jdbc方式搭建。

2.1 项目总体结构

在这里插入图片描述

2.2 Maven 依赖

shading-sphere/shading-auto-tables-algorithm/pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>shading-sphere</artifactId>
        <groupId>com.gm</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>shading-algorithm</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
            <version>5.2.1</version>
        </dependency>

        <!-- 解决Mybatis中LocalDateTime和SQL中datetime的交互 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-typehandlers-jsr310</artifactId>
            <version>1.0.2</version>
        </dependency>

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

        <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>1.33</version>
        </dependency>
        
    </dependencies>

</project>
  • shardingsphere-jdbc-core-spring-boot-starter使用版本5.2.1

  • JDBCORM 框架选用mybatis-plus

2.3 配置文件

server:
  port: 8844

spring:
  application:
    name: @artifactId@
  shardingsphere:
    # 数据源配置
    datasource:
      names: ds1,ds2
      ds1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://192.168.0.35:3306/db1?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai
        username: root
        password: '1qaz@WSX'
      ds2:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://192.168.0.46:3306/db2?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai
        username: root
        password: '1qaz@WSX'

    # 定义规则
    rules:
      sharding:
        # 采用自动分片算法
        autoTables:

以上配置为各自动分片算法公用的基础配置。

三、自动分片算法

AutoTable 支持全部的自动分片算法,包括:

  • MOD:取模分片算法
  • HASH_MOD:哈希取模分片算法
  • VOLUME_RANGE:基于分片容量的范围分片算法
  • BOUNDARY_RANGE:基于分片边界的范围分片算法
  • AUTO_INTERVAL:自动时间段分片算法

3.1 取模 —— MOD

类似 MySQLPATITION 里的 MOD,由ShardingSphere通过分片数和取模的分母,自动计算实际表个数。

可配置属性:

属性名称数据类型说明
sharding-countint分片数量

3.1.1 示例

该示例实际需要2个数据源(也支持单数据源的场景),每个数据源中各有3t_auto_order_mod分表,分表格式为:t_auto_order_mod_${0..5}

3.1.1.1 自动分片算法配置

        # 采用自动分片算法
        autoTables:
          # 取模
          t_auto_order_mod:
            actualDataSources: ds$->{1..2}
            sharding-strategy:
              standard:
                sharding-column: order_id
                sharding-algorithm-name: auto_order_mod
            # 分布式序列策略
            key-generate-strategy:
              # 自增列名称,缺省表示不使用自增主键生成器
              column: order_id
              # 分布式序列算法名称
              key-generator-name: snowflake
        # 分片算法配置
        sharding-algorithms:
          # 取模
          auto_order_mod:
            type: MOD
            props:
              sharding-count: 6              

3.1.1.2 实体类

com/gm/shading/auto/tables/algorithm/entity/AutoOrderMod.java

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;

@Data
@TableName("t_auto_order_mod")
public class AutoOrderMod {

    @TableId(type = IdType.ASSIGN_ID)
    private Long orderId;
    private BigDecimal price;
    private Long userId;
    private String status;
}

3.1.1.3 Mapper

com/gm/shading/auto/tables/algorithm/mapper/AutoOrderModMapper.java

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gm.shading.auto.tables.algorithm.entity.AutoOrderMod;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface AutoOrderModMapper extends BaseMapper<AutoOrderMod> {
    void save(AutoOrderMod autoOrder);
}

src/main/resources/mapper/AutoOrderModMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.gm.shading.auto.tables.algorithm.mapper.AutoOrderModMapper">
    <insert id="save" parameterType="com.gm.shading.auto.tables.algorithm.entity.AutoOrderMod">
        insert into t_auto_order_mod (price, user_id, status)
        values (#{price}, #{userId}, #{status})
    </insert>
</mapper>

3.1.1.4 单元测试

com/gm/shading/auto/tables/algorithm/ShadingAutoTablesAlgorithmApplicationTests.java

    @Autowired
    AutoOrderModMapper autoOrderModMapper;
    
    @Autowired
    JdbcTemplate jdbcTemplate; 
    
    @Test
    public void testCreateAutoOrderMod() {
        jdbcTemplate.execute("CREATE TABLE `t_auto_order_mod` (\n" +
                " `order_id` bigint(20) NOT NULL COMMENT '订单id',\n" +
                " `price` decimal(10,2) NOT NULL COMMENT '订单价格',\n" +
                " `user_id` bigint(20) NOT NULL COMMENT '下单用户id',\n" +
                " `status` varchar(50) NOT NULL COMMENT '订单状态',\n" +
                " PRIMARY KEY (`order_id`) USING BTREE\n" +
                ") ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;");
    }

    @Test
    public void InsertAutoOrderMod() {
        Random random = new Random();
        for (int i = 1; i < 10; i++) {
            AutoOrderMod order = new AutoOrderMod();
            order.setPrice(new BigDecimal(i));
            order.setUserId(Integer.valueOf(random.nextInt(25)).longValue());
            order.setStatus(i + "");
            autoOrderModMapper.save(order);
        }
    }

3.2 散列取模 —— HASH_MOD

MOD取模通常数值类型的分片,而HASH_MOD不仅适用于数值,也适用于字符(通过hash值取模)列进行分片。该算法基本和MOD类似。

可配置属性:

属性名称数据类型说明
sharding-countint分片数量

3.2.1 示例

该案例只有一个数据源,数据源中有 6t_auto_order_hash_mod分表,按 order_idhash值进行取模计算得到实际表。分表格式为:t_auto_order_hash_mod_${0..5}

3.2.1.1 自动分片算法配置

        # 采用自动分片算法
        autoTables:
          # 散列取模
          t_auto_order_hash_mod:
            actualDataSources: ds1
            sharding-strategy:
              standard:
                sharding-column: order_id
                sharding-algorithm-name: auto_order_hash_mod
            # 分布式序列策略
            key-generate-strategy:
              # 自增列名称,缺省表示不使用自增主键生成器
              column: order_id
              # 分布式序列算法名称
              key-generator-name: snowflake
        # 分片算法配置
        sharding-algorithms:
          # 散列取模
          auto_order_hash_mod:
            type: HASH_MOD
            props:
              sharding-count: 6              

3.2.1.2 实体类

com/gm/shading/auto/tables/algorithm/entity/AutoOrderHashMod.java

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;

@Data
@TableName("t_auto_order_hash_mod")
public class AutoOrderHashMod {

    @TableId(type = IdType.ASSIGN_ID)
    private Long orderId;
    private BigDecimal price;
    private Long userId;
    private String status;
}

3.2.1.3 Mapper

com/gm/shading/auto/tables/algorithm/mapper/AutoOrderHashModMapper.java

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gm.shading.auto.tables.algorithm.entity.AutoOrderHashMod;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface AutoOrderHashModMapper extends BaseMapper<AutoOrderHashMod> {
    void save(AutoOrderHashMod autoOrder);
}

src/main/resources/mapper/AutoOrderHashModMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.gm.shading.auto.tables.algorithm.mapper.AutoOrderHashModMapper">
    <insert id="save" parameterType="com.gm.shading.auto.tables.algorithm.entity.AutoOrderHashMod">
        insert into t_auto_order_hash_mod (price, user_id, status)
        values (#{price}, #{userId}, #{status})
    </insert>
</mapper>

3.2.1.4 单元测试

com/gm/shading/auto/tables/algorithm/ShadingAutoTablesAlgorithmApplicationTests.java

    @Autowired
    AutoOrderHashModMapper autoOrderHashModMapper;
    
    @Autowired
    JdbcTemplate jdbcTemplate; 

    @Test
    public void testCreateAutoOrderHashMod() {
        jdbcTemplate.execute("CREATE TABLE `t_auto_order_hash_mod` (\n" +
                " `order_id` bigint(20) NOT NULL COMMENT '订单id',\n" +
                " `price` decimal(10,2) NOT NULL COMMENT '订单价格',\n" +
                " `user_id` bigint(20) NOT NULL COMMENT '下单用户id',\n" +
                " `status` varchar(50) NOT NULL COMMENT '订单状态',\n" +
                " PRIMARY KEY (`order_id`) USING BTREE\n" +
                ") ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;");
    }

    @Test
    public void InsertAutoOrderHashMod() {
        Random random = new Random();
        for (int i = 1; i < 10; i++) {
            AutoOrderHashMod order = new AutoOrderHashMod();
            order.setPrice(new BigDecimal(i));
            order.setUserId(Integer.valueOf(random.nextInt(25)).longValue());
            order.setStatus(i + "");
            autoOrderHashModMapper.save(order);
        }
    }

3.3 容量范围 —— VOLUME_RANGE

该算法会根据 (${range-upper} - ${range-lower}) / ${sharding-volume} + 2 来算出实际的分片数量,从而实现自动分片功能。

可配置属性:

属性名称数据类型说明
range-lowerlong范围下界,超过边界的数据会报错
range-upperlong范围上界,超过边界的数据会报错
sharding-volumelong分片容量

要注意,这个算法之所以 + 2 ,实际上包含了两个隐藏表:

  • 储存小于 range-lower 情况的数据
  • 储存大于 range-upper 情况的数据

3.3.1 示例

该示例实际需要2个数据源,每个数据源中各有 2t_auto_order_volume_range分表,按 price 的容量范围计算得到实际表。分表格式为:t_auto_order_volume_range_${0..3}

3.3.1.1 自动分片算法配置

        # 采用自动分片算法
        autoTables:
          # 容量范围
          t_auto_order_volume_range:
            actualDataSources: ds$->{1..2}
            sharding-strategy:
              standard:
                sharding-column: price
                sharding-algorithm-name: auto_order_volume_range
            # 分布式序列策略
            key-generate-strategy:
              # 自增列名称,缺省表示不使用自增主键生成器
              column: order_id
              # 分布式序列算法名称
              key-generator-name: snowflake
        # 分片算法配置
        sharding-algorithms:
          # 容量范围
          auto_order_volume_range:
            type: VOLUME_RANGE
            props:
              range-lower: 0
              range-upper: 20000
              sharding-volume: 10000              

也就是说,上面的例子包含((20000 - 0) / 10000 + 2) = 4个分片:

db1: 
  - t_auto_order_volume_range_0: (-∞..0) 
  - t_auto_order_volume_range_2: [10000..20000) 
db2:
  - t_auto_order_volume_range_1: [0..10000) 
  - t_auto_order_volume_range_3: [20000..+∞)

3.3.1.2 实体类

com/gm/shading/auto/tables/algorithm/entity/AutoOrderVolumeRange.java

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;

@Data
@TableName("t_auto_order_volume_range")
public class AutoOrderVolumeRange {

    @TableId(type = IdType.ASSIGN_ID)
    private Long orderId;
    private BigDecimal price;
    private Long userId;
    private String status;
}

3.3.1.3 Mapper

com/gm/shading/auto/tables/algorithm/mapper/AutoOrderVolumeRangeMapper.java

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gm.shading.auto.tables.algorithm.entity.AutoOrderVolumeRange;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface AutoOrderVolumeRangeMapper extends BaseMapper<AutoOrderVolumeRange> {
    void save(AutoOrderVolumeRange autoOrder);
}

src/main/resources/mapper/AutoOrderVolumeRangeMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.gm.shading.auto.tables.algorithm.mapper.AutoOrderVolumeRangeMapper">
    <insert id="save" parameterType="com.gm.shading.auto.tables.algorithm.entity.AutoOrderVolumeRange">
        insert into t_auto_order_volume_range (price, user_id, status)
        values (#{price}, #{userId}, #{status})
    </insert>
</mapper>

3.3.1.4 单元测试

com/gm/shading/auto/tables/algorithm/ShadingAutoTablesAlgorithmApplicationTests.java

    @Autowired
    AutoOrderVolumeRangeMapper autoOrderVolumeRangeMapper;
    
    @Autowired
    JdbcTemplate jdbcTemplate;

    @Test
    public void testCreateAutoOrderVolumeRange() {
        jdbcTemplate.execute("CREATE TABLE `t_auto_order_volume_range` (\n" +
                " `order_id` bigint(20) NOT NULL COMMENT '订单id',\n" +
                " `price` decimal(10,2) NOT NULL COMMENT '订单价格',\n" +
                " `user_id` bigint(20) NOT NULL COMMENT '下单用户id',\n" +
                " `status` varchar(50) NOT NULL COMMENT '订单状态',\n" +
                " PRIMARY KEY (`order_id`) USING BTREE\n" +
                ") ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;");
    }
    
    @Test
    public void InsertAutoOrderVolumeRange() {
        Random random = new Random();
        for (int i = 1; i < 10; i++) {
            AutoOrderVolumeRange order = new AutoOrderVolumeRange();
            order.setPrice(new BigDecimal(random.nextInt(20000)));
            order.setUserId(Integer.valueOf(random.nextInt(25)).longValue());
            order.setStatus(i + "");
            autoOrderVolumeRangeMapper.save(order);
        }
    }

3.4 边界范围 —— BOUNDARY_RANGE

该算法会根据自定义范围进行分片,如:0 ~ 100在分片0,100 ~ 1000在分片1,1000 ~ 1500在分片2 等。

可配置属性:

属性名称数据类型说明
sharding-rangesString分片范围,多个边界可以用 , 隔开

要注意实际上包含了两个隐藏表:

  • 储存小于自定义范围最小值情况的数据
  • 储存大于自定义范围最大值情况的数据

3.4.1 示例

该示例实际需要2个数据源,每个数据源中各有 3t_auto_order_boundary_range分表,并且按 price 的自定义范围计算得到实际表。分表格式为:t_auto_order_boundary_range_${0..5}

3.4.1.1 自动分片算法配置

        # 采用自动分片算法
        autoTables:
          # 边界范围
          t_auto_order_boundary_range:
            actualDataSources: ds$->{1..2}
            sharding-strategy:
              standard:
                sharding-column: price
                sharding-algorithm-name: auto_order_boundary_range
            # 分布式序列策略
            key-generate-strategy:
              # 自增列名称,缺省表示不使用自增主键生成器
              column: order_id
              # 分布式序列算法名称
              key-generator-name: snowflake
        # 分片算法配置
        sharding-algorithms:
          # 边界范围
          auto_order_boundary_range:
            type: BOUNDARY_RANGE
            props:
              sharding-ranges: 10,15,100,12000,16000            

此示例中的自定义范围可以拆分为:

-∞..10, 
10..15, 
15..100, 
100..12000, 
12000..16000, 
16000..+∞

3.4.1.2 实体类

com/gm/shading/auto/tables/algorithm/entity/AutoOrderBoundaryRange.java

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;

@Data
@TableName("t_auto_order_boundary_range")
public class AutoOrderBoundaryRange {

    @TableId(type = IdType.ASSIGN_ID)
    private Long orderId;
    private BigDecimal price;
    private Long userId;
    private String status;
}

3.4.1.3 Mapper

com/gm/shading/auto/tables/algorithm/mapper/AutoOrderBoundaryRangeMapper.java

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gm.shading.auto.tables.algorithm.entity.AutoOrderBoundaryRange;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface AutoOrderBoundaryRangeMapper extends BaseMapper<AutoOrderBoundaryRange> {
    void save(AutoOrderBoundaryRange autoOrder);
}

src/main/resources/mapper/AutoOrderBoundaryRangeMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.gm.shading.auto.tables.algorithm.mapper.AutoOrderBoundaryRangeMapper">
    <insert id="save" parameterType="com.gm.shading.auto.tables.algorithm.entity.AutoOrderBoundaryRange">
        insert into t_auto_order_boundary_range (price, user_id, status)
        values (#{price}, #{userId}, #{status})
    </insert>
</mapper>

3.4.1.4 单元测试

com/gm/shading/auto/tables/algorithm/ShadingAutoTablesAlgorithmApplicationTests.java

    @Autowired
    AutoOrderBoundaryRangeMapper autoOrderBoundaryRangeMapper;
    
    @Autowired
    JdbcTemplate jdbcTemplate; 
       
    @Test
    public void testCreateAutoOrderBoundaryRange() {
        jdbcTemplate.execute("CREATE TABLE `t_auto_order_boundary_range` (\n" +
                " `order_id` bigint(20) NOT NULL COMMENT '订单id',\n" +
                " `price` decimal(10,2) NOT NULL COMMENT '订单价格',\n" +
                " `user_id` bigint(20) NOT NULL COMMENT '下单用户id',\n" +
                " `status` varchar(50) NOT NULL COMMENT '订单状态',\n" +
                " PRIMARY KEY (`order_id`) USING BTREE\n" +
                ") ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;");
    }

    @Test
    public void InsertAutoOrderBoundaryRange() {
        Random random = new Random();
        for (int i = 1; i < 10; i++) {
            AutoOrderBoundaryRange order = new AutoOrderBoundaryRange();
            order.setPrice(new BigDecimal(random.nextInt(20000)));
            order.setUserId(Integer.valueOf(random.nextInt(25)).longValue());
            order.setStatus(i + "");
            autoOrderBoundaryRangeMapper.save(order);
        }
    }

3.5 自动日期间隔 —— AUTO_INTERVAL

日期间隔将按:时间开始边界 到 时间结束边界 之间的秒数 除以 分片秒数 再加 2,从而计算出总分片数。也就是 ({datetime-upper} - {datetime-lower}) / sharding-seconds + 2

可配置属性:

属性名称数据类型说明
datetime-lowerString分片的起始时间范围,时间戳格式:yyyy-MM-dd HH:mm:ss
datetime-upperString分片的结束时间范围,时间戳格式:yyyy-MM-dd HH:mm:ss
sharding-secondslong单一分片所能承载的最大时间,单位:秒,允许分片键的时间戳格式的秒带有时间精度,但秒后的时间精度会被自动抹去

要注意,这个算法之所以 + 2 ,实际上包含了两个隐藏表:

  • 储存小于 datetime-lower 情况的数据
  • 储存大于 datetime-upper 情况的数据

3.5.1 示例

该示例实际需要2个数据源,共 5t_auto_order_auto_interval分表,按 create_time 计算分片所能承载的最大时间得到实际表。分表格式为:t_auto_order_auto_interval_${0..4}

3.5.1.1 自动分片算法配置

        # 采用自动分片算法
        autoTables:
          # 自动日期间隔
          t_auto_order_auto_interval:
            actualDataSources: ds$->{1..2}
            sharding-strategy:
              standard:
                sharding-column: create_time
                sharding-algorithm-name: auto_order_auto_interval
            # 分布式序列策略
            key-generate-strategy:
              # 自增列名称,缺省表示不使用自增主键生成器
              column: order_id
              # 分布式序列算法名称
              key-generator-name: snowflake
        # 分片算法配置
        sharding-algorithms:
          # 自动日期间隔
          auto_order_auto_interval:
            type: AUTO_INTERVAL
            props:
              datetime-lower: 2023-05-07 00:00:00
              datetime-upper: 2023-05-10 00:00:00
              sharding-seconds: 86400           

此示例中会按解析为:

?, 2023-05-07 00:00:00 = 0
2023-05-07 00:00:00, 2023-05-08 00:00:00 = 1
2023-05-08 00:00:00, 2023-05-09 00:00:00 = 2
2023-05-09 00:00:00, 2023-05-10 00:00:00 = 3
2023-05-10 00:00:00, ? = 4

3.5.1.2 实体类

com/gm/shading/auto/tables/algorithm/entity/AutoOrderBoundaryRange.java

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;

@Data
@TableName("t_auto_order_auto_interval")
public class AutoOrderAutoInterval {

    @TableId(type = IdType.ASSIGN_ID)
    private Long orderId;
    private BigDecimal price;
    private Long userId;
    private String status;
    private LocalDateTime createTime;
}

3.5.1.3 Mapper

com/gm/shading/auto/tables/algorithm/mapper/AutoOrderAutoIntervalMapper.java

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gm.shading.auto.tables.algorithm.entity.AutoOrderAutoInterval;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface AutoOrderAutoIntervalMapper extends BaseMapper<AutoOrderAutoInterval> {
    void save(AutoOrderAutoInterval autoOrder);
}

src/main/resources/mapper/AutoOrderAutoIntervalMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.gm.shading.auto.tables.algorithm.mapper.AutoOrderAutoIntervalMapper">
    <insert id="save" parameterType="com.gm.shading.auto.tables.algorithm.entity.AutoOrderAutoInterval">
        insert into t_auto_order_auto_interval (price, user_id, status,create_time)
        values (#{price}, #{userId}, #{status}, #{createTime})
    </insert>
</mapper>

3.5.1.4 单元测试

com/gm/shading/auto/tables/algorithm/ShadingAutoTablesAlgorithmApplicationTests.java

    @Autowired
    AutoOrderAutoIntervalMapper autoOrderAutoIntervalMapper;

    @Autowired
    JdbcTemplate jdbcTemplate;
    
    @Test
    public void testCreateAutoOrderAutoInterval() {
        jdbcTemplate.execute("CREATE TABLE `t_auto_order_auto_interval` (\n" +
                " `order_id` bigint(20) NOT NULL COMMENT '订单id',\n" +
                " `price` decimal(10,2) NOT NULL COMMENT '订单价格',\n" +
                " `user_id` bigint(20) NOT NULL COMMENT '下单用户id',\n" +
                " `status` varchar(50) NOT NULL COMMENT '订单状态',\n" +
                " `create_time` datetime NOT NULL COMMENT '订单时间',\n" +
                " PRIMARY KEY (`order_id`) USING BTREE\n" +
                ") ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;");
    }

    @Test
    public void InsertAutoOrderAutoInterval() {
        Random random = new Random();
        for (int i = 1; i < 10; i++) {
            AutoOrderAutoInterval order = new AutoOrderAutoInterval();
            order.setPrice(new BigDecimal(random.nextInt(20000)));
            order.setUserId(Integer.valueOf(random.nextInt(25)).longValue());
            order.setStatus(i + "");
            // 随机减少一定天数再随机增加一定天数
            order.setCreateTime(LocalDateTime.now().minusDays(random.nextInt(10)).plusDays(random.nextInt(10)));
            autoOrderAutoIntervalMapper.save(order);
        }
    }

3.6 源码

上述示例完整源码请见:https://gitee.com/gm19900510/springboot-cloud-example.git

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

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

相关文章

【JAVAEE】使用wait()方法和notify()方法解决线程不安全中的有序性问题

目录 1.wait()方法 2.notify()方法 3.notifyAll()方法 4.wait()和sleep()方法的区别 由于线程之间是抢占式执行的&#xff0c;因此线程之间执行的先后顺序难以预知。但是在实际开发中有时候我们希望合理的协调多个线程之间的执行先后顺序。 完成这个协调工作&#xff0c;主…

QML之HTML5画布移植(Porting from HTML5 Canvas)

移植一个HTML5画布图像到QML画布非常简单。在成百上千的例子中&#xff0c;我们选择了一个来移植。 螺旋图形&#xff08;Spiro Graph&#xff09; 我们使用一个来自Mozila项目的螺旋图形例子来作为我们的基础示例。原始的HTML5代码被作为画布教程发布。 下面是我们需要修改…

OpenGL(十)——基础光照

目录 一、前言 二、环境光照 三、漫反射光照 3.1 法向量 3.2顶点着色器 3.3 VAO属性解释 3.4 片段着色器 四、镜面光照 4.1 片段着色器 一、前言 现实世界光照十分复杂&#xff0c;冯氏光照模型是对现实世界光照的抽象&#xff0c;主要由3部分组成&#xff0c;环境amb…

【JAVAEE】使用synchronized关键字和volatile关键字解决线程安全问题中的原子性,内存可见性和有序性问题

目录 1.synchronized关键字---监视器锁monitor lock 1.1synchronized的特性 互斥 刷新内存 可重入 1.3synchronized使用注意事项 2.volatile关键字 2.1volatile保证内存可见性问题 MESI缓存一致性协议 内存屏障 2.2volatile解决有序性问题 3.总结synchronized和vola…

ELK -- kibana 用nginx代理后无法访问

背景&#xff1a; 本地搭建好elk后&#xff0c;一切正常&#xff0c;后面改成用nginx代理kibana的5601端口&#xff0c;发现代理后无法正常访问&#xff08;未代理的地址可正常访问&#xff09;&#xff0c;花了很多时间去查问题&#xff0c;报错基本都是http://ip:port/spaces…

Leetcode刷题之复制带随机指针的链表

生命不是安排&#xff0c;而是追求&#xff0c;人生的意义也许永远没有答案&#xff0c;但也要尽情感受这种没有答案的人生。 --弗吉尼亚. 伍尔芙 目录 前言&#xff1a; &#x1f338;一.复制带随机指针的链表 &#x1f305;1.复制结点链接到原本链表每一个结点的…

24个强大的HTML属性,每个资深Web工程师都应该掌握!

HTML 属性非常多&#xff0c;除了基本的一些属性外&#xff0c;还有很多很有用的功能性特别强大的属性&#xff1b; 本文将介绍24个强大的HTML属性&#xff0c;这些属性可以让你的网站更加动态和交互&#xff0c;让用户感到更加舒适和愉悦。 让我们一起来探索这24个强大的HTML…

进程优先级+环境变量++地址空间+虚拟地址空间

索引 一.进程优先级二.环境变量1.通过代码如何获取环境1.通过第三个命令行参数获得2.根据第三方变量environ获取3.通过系统调用获取环境变量 2.验证环境变量可以被子进程继承下去 三.验证地址空间1.验证程序地址空间2.证明地址空间不是物理地址 四.虚拟地址空间虚拟地址空间存在…

BI财务智能分析,让企业管理更上一层楼

智能财务建设既可以看作是财务管理工作在经济社会数字化转型的全面开启&#xff0c;也可以看作是财务职能在以数字化技术为支撑&#xff0c;形成对内提升单位管理水平和风险管控能力、对外服务财政管理和宏观经济治理的会计职能拓展&#xff0c;究其本质则是在财务数字化转型升…

简单介绍之隔离级别与分布式事务

一&#xff0c;分布式系统与环境问题 概念 系统可以笼统分为集中式系统和分布式系统。 集中式系统就是由一台或多台主计算机组成中心节点&#xff0c;系统所有功能均由其集中处理。 分布式系统是硬件和软件组件分布不同的网络计算机上&#xff0c;彼此之间仅仅通过消息传递进…

植被参数光学遥感反演方法(Python)及遥感与生态模型数据同化算法技术应用

传统的地面实测方法能够得到比较准确的植被参数&#xff08;如叶面积指数、覆盖度、生物量、叶绿素、干物质、叶片含水量、FPAR等&#xff09;&#xff0c;但其获取信息有限&#xff0c;难以满足大范围提取植被参数的需求&#xff0c;尤其在异质地表区域。遥感技术的发展为植被…

C++学习day--07 字符串

1、黑客攻击系统-用户输入的优化 第 1 节 项目需求 1. 用户登录时&#xff0c;用户可能输入很长的用户名。 2. 使用 char 类型和 int 类型&#xff0c;表示用户名和密码&#xff0c;不安全。 第 2 节 项目实现 #include <iostream> #include <Windows.h> …

MacBook重置与推荐软件配置

Mac OS 12.6.5 前言重置初始化配置说明 GitJava 8 & Maven & MysqlJava 8mavenMySQL配置 MotrixDBeaver添加aliyun的maven至DBeaver添加MySQL VS CodeSteamTyporaiStas Menus 前言 用了一年的机械革命游戏本,机器加外设20斤的重量背过几次出门后就再也不想带出门了,运行…

PyYaml反序列化漏洞

0x01 HDCTF 遇到预期解是考的yaml了&#xff0c;前来学习下 语法 语法就不贴了&#xff0c;其他文章有介绍 语法和 yml配置文件的 语法差不多 就不一一介绍 漏洞成因与利用 PyYaml < 5.1 在python 中 pyyaml是提供 python 和Yaml 两种语言的转换&#xff0c;与pickle 类…

C++20协程

简介 ​ C20协程只是提供协程机制&#xff0c;而不是提供协程库。C20的协程是无栈协程&#xff0c;无栈协程是一个可以挂起/恢复的特殊函数&#xff0c;是函数调用的泛化&#xff0c;且只能被线程调用&#xff0c;本身并不抢占内核调度。 ​ C20 提供了三个新关键字(co_await…

【DRF配置管理】如何建立swagger风格api接口文档

原文作者&#xff1a;我辈李想 版权声明&#xff1a;文章原创&#xff0c;转载时请务必加上原文超链接、作者信息和本声明。 DRF应用和管理 【DRF配置管理】Django安装和使用DRF框架 【DRF配置管理】如何在视图函数配置参数(一) 【DRF配置管理】如何在视图函数配置参数(二) 【…

C. Enlarge GCD(内存的限制 + 数组的访问速度)

Problem - C - Codeforces Mr. F 有 n 个正整数 a1,a2,…,an。 他认为这些整数的最大公约数太小了。所以他想通过删除其中一些整数来扩大它。 但是这个问题对他来说太简单了&#xff0c;所以他不想自己做。如果你帮他解决这个问题&#xff0c;他会给你一些奖励分数。 你的任…

AntDB数据库携手金蝶Apusic应用服务器, 共促信创产业繁荣发展

日前&#xff0c;湖南亚信安慧科技有限公司&#xff08;简称&#xff1a;亚信安慧&#xff09;与深圳市金蝶天燕云计算股份有限公司&#xff08;简称&#xff1a;金蝶天燕&#xff09;完成AntDB数据库与金蝶Apusic服务器软件V9.0、V10产品的兼容互认&#xff0c;兼容性良好&…

不是吧,3 : 00 面试,还没10分钟就出来了,问的也太...

从外包出来&#xff0c;没想到死在另一家厂子 自从加入这家公司&#xff0c;每天都在加班&#xff0c;钱倒是给的不少&#xff0c;所以也就忍了。没想到2月一纸通知&#xff0c;所有人不许加班&#xff0c;薪资直降30%&#xff0c;顿时有吃不起饭的赶脚。 好在有个兄弟内推我去…

Android WebRtc+SRS/ZLM视频通话(3):安装ZLMediaKit

Android WebRtcSRS/ZLM视频通话&#xff08;3&#xff09;&#xff1a;安装ZLMediaKit 来自奔三人员的焦虑日志 接着上一章内容&#xff0c;继续来记录ZLMediaKit的安装&#xff0c;这里的ZLMediaKit实际上和SRS的功能差不多&#xff0c;都是国内流媒体服务框架使用人数比价多&…