根据编号规则生成规则编号

    /**
     * 根据编号规则生成规则编号
     * @param rule  前缀
     * @param num 数字位数
     * @param orderField 排序字段
     * @param table 表名
     * @param sqlWhere 条件语句,不需and
     * @return newNo 
     * @Author:
     * @Date:
     */
    public static String getRuleNewNo(String rule,String num, String orderField, String table, String sqlWhere){
        int no=1;
        int length = rule.length();
        String newNo = String.format(rule + "%0"+num+"d", no);
        sqlWhere = "".equals(sqlWhere) ? "" : (" and " + sqlWhere);
        Object temp = (Object) Dao.getEntity("select max(" + orderField + ") from " + table + " where 1=1 " + sqlWhere);
        if (temp != null) {
            no = DataUtil.objToInt(temp.toString().substring(length)) + 1;
            newNo = String.format(rule + "%0"+num+"d", no);
        }
        return newNo;
    }


 

<think>好的,用户之前询问了如何根据数据库生成编号,我给出了六种方法,其中包括复合规则生成法。现在用户进一步询问复合规则生成法的具体实现方式。我需要详细解释这种方法,确保用户理解其步骤和应用场景。 首先,用户可能对复合规则生成法的概念不太清楚,需要先定义。复合规则通常涉及多个业务字段的组合,比如区域码、行业代码、日期和序列号等。用户可能想知道如何将这些元素结合起来生成唯一的编号,以及如何在数据库中实现。 接下来,我需要考虑用户可能的实际应用场景。例如,他们可能正在设计一个需要包含多种业务信息的编号系统,如客户编号、订单号等。需要强调复合规则的优势,比如可读性和业务含义,但也需要提到可能的挑战,比如复杂性和维护成本。 用户可能需要具体的例子来理解如何拼接各个部分。比如,客户编号的结构可能包括区域、行业、年份和序列号。我应该提供详细的示例,并说明每个部分的来源,如数据库配置表或外部系统。 此外,用户可能关心如何确保唯一性。这时候需要提到使用数据库的唯一索引或事务锁来避免重复。同时,生成步骤的具体实现,比如如何查询配置表、获取序列号,以及组合这些部分的代码示例,都是必要的。 还要考虑用户的技术水平。他们可能对数据库操作和编程有一定的了解,因此提供SQL和Java/Python的代码片段会更有帮助。同时,需要说明在并发情况下的处理,比如使用事务或分布式锁来防止冲突。 可能用户没有明确提到的深层需求是系统的扩展性和维护性。复合规则生成法在业务规则变化时可能需要调整结构,因此需要设计灵活的配置表,便于未来修改。这也是需要提及的重要点。 最后,总结复合规则生成法的适用场景,帮助用户判断是否适合他们的需求。比如,当编号需要包含多个业务维度且对可读性有要求时,这种方法非常合适,但如果是高并发场景,可能需要结合其他方法如号段分配或Redis来提高性能。</think>### **复合规则生成法深度解析** 复合规则生成法通过**多维度数据组合+业务逻辑**生成具有语义的编号,是ERP、CRM等业务系统中应用最广泛的编码方案。以下是实现该方法的完整技术路径: --- #### **一、核心组成要素** 一个典型的复合编号通常包含以下4类元素: | 元素类型 | 示例 | 数据来源 | |----------------|---------------------|-----------------------| | **业务标识码** | `CUST`(客户) | 系统预设常量 | | **分类维度码** | `01`(华北区域) | 参数配置表/外部系统 | | **时间戳** | `2023`(年份) | 服务器时间 | | **序列号** | `00001`(当日流水号)| 数据库序列/Redis计数器 | --- #### **二、标准化实现步骤** 以下以生成客户编号 `CUST-01A-2023-00001` 为例说明: **步骤1:建立规则配置表** ```sql CREATE TABLE code_rules ( rule_id VARCHAR(50) PRIMARY KEY COMMENT '规则类型', prefix VARCHAR(20) NOT NULL COMMENT '固定前缀', segment1_type ENUM('fixed','param','date') NOT NULL COMMENT '段1类型', segment1_format VARCHAR(50) COMMENT '段1格式', sequence_name VARCHAR(50) COMMENT '关联的序列名称', UNIQUE KEY (rule_id) ); ``` **示例配置数据**: ```sql INSERT INTO code_rules VALUES ( 'customer_code', 'CUST', 'param', 'area_code', 'customer_seq' ); ``` **步骤2:动态获取编码组件** ```python def generate_code(rule_id): # 查询规则配置 rule = db.query("SELECT * FROM code_rules WHERE rule_id = %s", rule_id) # 获取区域码(从参数表获取) area_code = db.query("SELECT param_value FROM sys_params WHERE param_key = 'area_code'") # 获取当前年份 year = datetime.now().strftime("%Y") # 获取序列号(事务中操作) with db.transaction(): seq = db.execute("UPDATE sequences SET value=LAST_INSERT_ID(value+1) WHERE name=%s", rule.sequence_name) seq = db.query("SELECT LAST_INSERT_ID()") # 组合编码 return f"{rule.prefix}-{area_code}-{year}-{str(seq).zfill(5)}" ``` **步骤3:防冲突处理** ```sql -- 在目标表添加唯一约束 ALTER TABLE customers ADD UNIQUE INDEX idx_customer_code (customer_code); -- 插入时捕获重复异常 BEGIN INSERT INTO customers (customer_code, ...) VALUES ('CUST-01A-2023-00001', ...); EXCEPTION WHEN DUPLICATE_KEY THEN RETRY generate_code(); -- 重新生成并重试 END; ``` --- #### **三、高级优化策略** 1. **缓存加速** ```java // 使用Guava缓存区域编码(有效期2小时) LoadingCache<String, String> areaCodeCache = CacheBuilder.newBuilder() .expireAfterWrite(2, TimeUnit.HOURS) .build(new CacheLoader<String, String>() { public String load(String key) { return jdbcTemplate.queryForObject( "SELECT param_value FROM sys_params WHERE param_key=?", String.class, key); } }); ``` 2. **批量预生成** ```sql -- 创建预生成编号表 CREATE TABLE pre_generated_codes ( code VARCHAR(50) PRIMARY KEY, status ENUM('UNUSED','USED') NOT NULL DEFAULT 'UNUSED', gen_time DATETIME NOT NULL ); -- 定时任务批量生成 DELIMITER $$ CREATE PROCEDURE generate_codes_batch() BEGIN DECLARE i INT DEFAULT 0; START TRANSACTION; WHILE i < 1000 DO INSERT INTO pre_generated_codes (code, gen_time) VALUES (generate_code('customer_code'), NOW()); SET i = i + 1; END WHILE; COMMIT; END$$ ``` 3. **版本化规则** ```sql ALTER TABLE code_rules ADD COLUMN version INT NOT NULL DEFAULT 1 COMMENT '规则版本'; -- 生成时携带版本号 CUST-v2-01A-2023-00001 ``` --- #### **四、典型业务场景** | 场景 | 编码示例 | 规则解析 | |---------------------|-------------------------|-----------------------------| | **医疗器械追溯码** | `MD-沪2023-01-0012345` | 类型+注册地+日期+流水号 | | **跨境电商订单号** | `KJDS-USD230515-01A-88` | 业务类型+货币+日期+仓库+渠道 | | **科研样本编号** | `SAMPLE-BJ-COVID-A0001` | 样本类型+地点+项目+分类+序号 | --- #### **五、避坑指南** 1. **长度失控问题** - 限制每个段的最大长度(如区域码不超过3位) - 添加长度校验约束 ```sql ALTER TABLE customers ADD CONSTRAINT chk_code_length CHECK (LENGTH(customer_code) <= 20); ``` 2. **规则变更兼容** - 新旧规则并行期设计(如2023年前用旧规则) - 建立编码历史版本对照表 3. **高并发瓶颈** - 序列号生成改用Redis集群 ```shell # Redis集群配置 redis-cli -c -p 7000 INCR customer:seq ``` 4. **跨时区问题** - 统一使用UTC时间生成日期部分 - 存储时区信息 ```sql ALTER TABLE codes ADD COLUMN timezone VARCHAR(32) NOT NULL DEFAULT 'UTC+8'; ``` --- 通过将业务要素结构化存储+动态组装,复合规则生成法既能满足复杂业务需求,又保持了系统扩展性。关键是要建立完善的规则管理机制和异常处理体系。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值