feat: 新增编码规则和流水号段Mapper

- 将 idx_rule_reset 索引改为 UNIQUE KEY 以支持 ON DUPLICATE KEY UPDATE
- 新增 CodeRuleMapper 接口(分页查询+按编码查询)
- 新增 CodeSequenceMapper 接口(按规则ID/重置键查询+号段预分配)
- 新增 CodeSequenceMapper.xml(号段预分配 SQL)
This commit is contained in:
zhouz
2026-07-15 16:58:16 +08:00
parent 89fedc91f2
commit 9fae26b353
4 changed files with 108 additions and 1 deletions

View File

@@ -0,0 +1,43 @@
package cn.code.nl.module.base.dal.mysql.codegen;
import cn.code.nl.framework.common.pojo.PageResult;
import cn.code.nl.framework.mybatis.core.mapper.BaseMapperX;
import cn.code.nl.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.code.nl.module.base.controller.admin.codegen.vo.CodeRulePageReqVO;
import cn.code.nl.module.base.dal.dataobject.codegen.CodeRuleDO;
import org.apache.ibatis.annotations.Mapper;
/**
* 编码规则 Mapper
*
* @author zhouz
*/
@Mapper
public interface CodeRuleMapper extends BaseMapperX<CodeRuleDO> {
/**
* 分页查询编码规则
*
* @param reqVO 查询条件
* @return 分页结果
*/
default PageResult<CodeRuleDO> selectPage(CodeRulePageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<CodeRuleDO>()
.likeIfPresent(CodeRuleDO::getRuleName, reqVO.getRuleName())
.eqIfPresent(CodeRuleDO::getRuleCode, reqVO.getRuleCode())
.eqIfPresent(CodeRuleDO::getStatus, reqVO.getStatus())
.betweenIfPresent(CodeRuleDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(CodeRuleDO::getId));
}
/**
* 根据规则编码查询
*
* @param ruleCode 规则编码
* @return 编码规则
*/
default CodeRuleDO selectByRuleCode(String ruleCode) {
return selectOne(CodeRuleDO::getRuleCode, ruleCode);
}
}

View File

@@ -0,0 +1,44 @@
package cn.code.nl.module.base.dal.mysql.codegen;
import cn.code.nl.framework.mybatis.core.mapper.BaseMapperX;
import cn.code.nl.module.base.dal.dataobject.codegen.CodeSequenceDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* 编码流水号段 Mapper
*
* @author zhouz
*/
@Mapper
public interface CodeSequenceMapper extends BaseMapperX<CodeSequenceDO> {
/**
* 根据规则ID和重置键查询流水记录
*
* @param ruleId 规则ID
* @param resetKey 重置维度键
* @return 流水记录
*/
default CodeSequenceDO selectByRuleIdAndResetKey(Long ruleId, String resetKey) {
return selectOne(CodeSequenceDO::getRuleId, ruleId,
CodeSequenceDO::getResetKey, resetKey);
}
/**
* 号段预分配:原子更新 current_value = current_value + step
*
* @param ruleId 规则ID
* @param resetKey 重置维度键
* @param step 预取步长
* @param startAt 起始值(用于首次初始化)
* @param maxValue 最大值上限
* @return 更新行数
*/
int updateCurrentValueBySegment(@Param("ruleId") Long ruleId,
@Param("resetKey") String resetKey,
@Param("step") int step,
@Param("startAt") Long startAt,
@Param("maxValue") Long maxValue);
}

View File

@@ -0,0 +1,20 @@
<?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="cn.code.nl.module.base.dal.mysql.codegen.CodeSequenceMapper">
<!--
号段预分配:
1. 使用 INSERT ... ON DUPLICATE KEY 实现"不存在则插入,存在则更新"
2. 利用 idx_rule_reset (rule_id, reset_key) 唯一性校验并发安全
3. 首次插入时 current_value = startAt + step - 1后续更新时 current_value = current_value + step
注意:此 SQL 依赖 idx_rule_reset 唯一索引配合行锁,需在 Lock4j 保护下调用
-->
<update id="updateCurrentValueBySegment">
INSERT INTO base_code_sequence (rule_id, reset_key, current_value, max_value)
VALUES (#{ruleId}, #{resetKey}, #{startAt} + #{step} - 1, #{maxValue})
ON DUPLICATE KEY UPDATE
current_value = current_value + #{step},
max_value = #{maxValue}
</update>
</mapper>

View File

@@ -32,5 +32,5 @@ CREATE TABLE base_code_sequence (
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
deleted TINYINT NOT NULL DEFAULT 0 COMMENT '是否删除',
PRIMARY KEY (id),
KEY idx_rule_reset (rule_id, reset_key)
UNIQUE KEY idx_rule_reset (rule_id, reset_key)
) COMMENT '编码流水号段记录表';