编程 java MySQL如何获取唯一订单编号?

2024-11-18 18:51:44 +0800 CST views 914

java MySQL如何获取唯一订单编号?

1. 前言

前提:系统并发量不大,数据库没有分库分表。

在实际开发工作中,有时需要我们设计唯一的订单编号。例如,编号格式为:ZHIFOU20240225000001。我们的目标是在确保每天生成的订单编号唯一的前提下,最好使其自增长。

设计思路:

  1. 使用 SQL 查询当天创建时间的最大订单编号。
  2. 判断该编号是否存在:如果不存在,从 ZHIFOUYYYYMMDD000001 开始生成;如果存在,则对编号的数字部分自增。

2. 完整实现

2.1 mapper.xml

<mapper namespace="com.zhifou.OrderMapper">
    <select id="getMaxOrderNumber" resultType="java.lang.String">
        select max(order_number) as orderNumber
        from zc_order
        where DATE(create_time) = CURDATE()
    </select>
</mapper>

该 SQL 语句用于查询当前日期的最大订单编号。

2.2 mapper 接口

public interface OrderMapper extends BaseMapper<Order> {

    /**
     * 获取今日最大订单编号
     * @return 今日的最大订单编号
     */
    String getMaxOrderNumber();
}

该接口提供获取今日最大订单编号的方法。

2.3 编号工具类(核心实现)

public class UniqueNumberUtil {
  /**
   * 获取唯一编号
   * @param prefix 前缀
   * @param todayMaxNumber 数据库中今天日期的最大编号
   * @param numberLength 数字部分的位数
   * @return 唯一编号
   */
  public static String getUniqueNumber(String prefix, String todayMaxNumber, Integer numberLength) {
    // 日期部分 (yyyyMMdd)
    String dateParam = DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN);
    // 数字部分
    String number;
    
    // 如果存在今日最大订单编号
    if (StrUtil.isNotBlank(todayMaxNumber)) {
        // 获取数字部分,例如 ZHIFOU20240201000001,数字部分是 "000001"
        int num = Integer.parseInt(todayMaxNumber.substring(prefix.length() + 8));
        num++; // 数字自增
        // 如果自增后的数字长度不足,补0
        if (String.valueOf(num).length() < numberLength) {
            number = String.format("%0" + numberLength + "d", num);
        } else {
            number = String.valueOf(num);
        }
    } else {
        // 如果不存在,初始编号为 000001
        number = String.format("%0" + numberLength + "d", 1);
    }
    // 完整编号格式:前缀 + yyyyMMdd + 数字部分
    return prefix + dateParam + number;
  }
}

2.4 订单实体类

@Getter
@Setter
@Accessors(chain = true)
@TableName("wxg_order")
public class Order implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    private String companyName;

    private Long userId;

    private String orderNumber;

    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;

    @TableField(fill = FieldFill.UPDATE)
    private Date updateTime;
}

2.5 测试用例

测试一:获取今日前缀为 ZHIFOU 的订单编号

@Autowired
private OrderMapper orderMapper;

@Test
void customTest() {
    String orderNumber = UniqueNumberUtil.getUniqueNumber("ZHIFOU", this.orderMapper.getMaxOrderNumber(), 6);
    System.out.println(orderNumber);
}

测试二:获取今日前缀为 ALIBABA 的订单编号

@Autowired
private OrderMapper orderMapper;

@Test
void customTest() {
    String orderNumber = UniqueNumberUtil.getUniqueNumber("ALIBABA", this.orderMapper.getMaxOrderNumber(), 6);
    System.out.println(orderNumber);
}

3. 总结

通过上述实现,我们可以确保每一天的订单编号都是唯一且自增长的。核心思想是基于数据库查询当天的最大编号,并通过数字部分自增来实现编号的连续性和唯一性。这种方案适用于系统并发量不大且没有分库分表的场景。

复制全文 生成海报 数据库 订单管理 编程

推荐文章

#免密码登录服务器
2024-11-19 04:29:52 +0800 CST
PHP来做一个短网址(短链接)服务
2024-11-17 22:18:37 +0800 CST
Grid布局的简洁性和高效性
2024-11-18 03:48:02 +0800 CST
阿里云免sdk发送短信代码
2025-01-01 12:22:14 +0800 CST
Dropzone.js实现文件拖放上传功能
2024-11-18 18:28:02 +0800 CST
JavaScript设计模式:单例模式
2024-11-18 10:57:41 +0800 CST
WebSocket在消息推送中的应用代码
2024-11-18 21:46:05 +0800 CST
Vue3中的v-bind指令有什么新特性?
2024-11-18 14:58:47 +0800 CST
LLM驱动的强大网络爬虫工具
2024-11-19 07:37:07 +0800 CST
Golang在整洁架构中优雅使用事务
2024-11-18 19:26:04 +0800 CST
你可能不知道的 18 个前端技巧
2025-06-12 13:15:26 +0800 CST
Hypothesis是一个强大的Python测试库
2024-11-19 04:31:30 +0800 CST
Nginx负载均衡详解
2024-11-17 07:43:48 +0800 CST
如何配置获取微信支付参数
2024-11-19 08:10:41 +0800 CST
php机器学习神经网络库
2024-11-19 09:03:47 +0800 CST
在 Vue 3 中如何创建和使用插件?
2024-11-18 13:42:12 +0800 CST
Golang - 使用 GoFakeIt 生成 Mock 数据
2024-11-18 15:51:22 +0800 CST
Claude:审美炸裂的网页生成工具
2024-11-19 09:38:41 +0800 CST
Vue3中的组件通信方式有哪些?
2024-11-17 04:17:57 +0800 CST
快手小程序商城系统
2024-11-25 13:39:46 +0800 CST
程序员茄子在线接单