You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot集成Oracle时如何实现AAA格式字母编码自增

3位大写字母自增产品编码实现方案

这个编码规则本质是固定3位的26进制计数:A对应数值0,B对应1,一直到Z对应25,进位逻辑和十进制完全一致——最低位(最右侧字符)从A走到Z后归位为A,向中间位进1;中间位走到Z后继续向最高位(最左侧字符)进位,初始值AAA对应数值0,每新增1条记录数值加1再转成字母即可,和给出的序列规则完全匹配。

以下是对应技术栈的具体实现,优先保证并发场景下不重号:

1. Oracle数据库层实现(核心逻辑放这层最稳妥)

推荐直接用Oracle原生序列做数值自增,从底层避免并发重号问题,不需要业务层做额外控制。

  • 第一步:创建自增序列
-- 序列从0开始,每次步长1,缓存20个值提升插入性能
CREATE SEQUENCE SEQ_PRODUCT_CODE
START WITH 0
INCREMENT BY 1
CACHE 20;
  • 第二步:创建数值转编码的自定义函数,直接输出符合规则的3位编码
CREATE OR REPLACE FUNCTION NUM_TO_PRODUCT_CODE(p_num IN NUMBER)
RETURN VARCHAR2
IS
  v_code VARCHAR2(3);
  v_remain NUMBER := p_num;
  v_bit NUMBER;
BEGIN
  -- 计算最低位(最右侧字符,对应26^0位)
  v_bit := MOD(v_remain, 26);
  v_code := CHR(65 + v_bit);
  v_remain := TRUNC(v_remain / 26);
  -- 计算中间位(对应26^1位)
  v_bit := MOD(v_remain, 26);
  v_code := CHR(65 + v_bit) || v_code;
  v_remain := TRUNC(v_remain / 26);
  -- 计算最高位(最左侧字符,对应26^2位)
  v_bit := MOD(v_remain, 26);
  v_code := CHR(65 + v_bit) || v_code;
  RETURN v_code;
END;
/

可以直接在Oracle里测试验证:

  • SELECT NUM_TO_PRODUCT_CODE(0) FROM DUAL; 返回AAA
  • SELECT NUM_TO_PRODUCT_CODE(25) FROM DUAL; 返回AAZ
  • SELECT NUM_TO_PRODUCT_CODE(26) FROM DUAL; 返回ABA,完全匹配示例规则。
  • 第三步(可选):配置表触发器自动赋值,插入数据时不需要业务层传入编码字段
-- 示例:给PRODUCT表的PRODUCT_CODE字段自动生成编码
CREATE OR REPLACE TRIGGER TRG_PRODUCT_CODE
BEFORE INSERT ON PRODUCT
FOR EACH ROW
BEGIN
  :NEW.PRODUCT_CODE := NUM_TO_PRODUCT_CODE(SEQ_PRODUCT_CODE.NEXTVAL);
END;
/

不推荐用“先查当前最大编码、转数值加1再转码”的方案,并发插入时会出现重复编码,除非手动加悲观锁,性能和稳定性都不如原生序列。


2. Spring Boot后端实现

如果不想把转码逻辑放在数据库,后端也可以自行实现,核心是保证取递增数值的原子性。

  • 第一步:编写编码转换工具类
public class ProductCodeUtil {
    // 固定3位编码,后续要扩长度直接改这个值就行,逻辑兼容
    private static final int CODE_LENGTH = 3;
    private static final int BASE = 26;
    private static final char START_CHAR = 'A';

    // 数值转3位产品编码
    public static String numToCode(long num) {
        StringBuilder sb = new StringBuilder();
        long remain = num;
        for (int i = 0; i < CODE_LENGTH; i++) {
            int bit = (int) (remain % BASE);
            sb.append((char)(START_CHAR + bit));
            remain = remain / BASE;
        }
        // 拼接时从最低位开始,需要反转得到最高位在前的正确编码
        return sb.reverse().toString();
    }

    // 编码转数值,用于校验、排查问题场景
    public static long codeToNum(String code) {
        if (code == null || code.length() != CODE_LENGTH) {
            throw new IllegalArgumentException("产品编码必须为3位大写字母");
        }
        long num = 0;
        for (char c : code.toCharArray()) {
            num = num * BASE + (c - START_CHAR);
        }
        return num;
    }
}
  • 第二步:插入数据时直接取Oracle序列的nextval值,调用numToCode方法转成编码即可,不要自己查最大编码计算。MyBatis、JPA都支持直接取序列值,原子性由Oracle保证,多实例部署也不会出现重号。

3. Angular前端实现

前端不要做任何编码生成逻辑:

  • 新增产品表单里的产品编码字段设为只读/禁用状态,不允许用户手动修改
  • 提交新增请求后,直接拿后端返回的、入库后的真实编码展示即可,不要在前端本地计算下一个编码,避免和后端实际值不一致
  • 如果需要给用户展示编码规则,可以做静态示例,不要对接业务逻辑。

边界说明

3位大写字母一共支持26*26*26=17576个唯一编码,如果后续产品量超过这个值,只需要修改编码长度常量(数据库函数对应加位、Java工具类改CODE_LENGTH值),进位逻辑完全兼容,比如4位长度初始值为AAAA,ZZZ后会自动进位为ABAA。

内容的提问来源于stack exchange,提问作者Majed Abdullah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 07:09:18