Java+Mysql存储过程生成订单序列号

发布时间:2024年01月13日

Mysql存储过程生成唯一订单号

直接上代码!!

1.创建存储过程

CREATE DEFINER=`root`@`localhost` PROCEDURE `getOrderSerialNo`(
                            # 前缀
							in orderPrefix varchar(64), 
						    # 返回结果
							out result int
							)
BEGIN
    # 当前流水号
	declare curOrderNo int;
	# 默认值为0
	declare errorResult int default 0;
	# 生成失败返回
	declare continue handler for sqlexception set errorResult = -1;

	#开启事务 
	start transaction;
	select cur_order_no into curOrderNo from t_order_serial_no where order_prefix = orderPrefix;
	# 如果该前缀是第一次生成 则插入1
	if curOrderNo is null then
	insert into t_order_serial_no(order_prefix, cur_order_no) values (orderPrefix, 1);
	select 1 into result;
	else 
	# 否则递增
	update t_order_serial_no set cur_order_no = cur_order_no + 1 where order_prefix = orderPrefix;
	select cur_order_no into result from t_order_serial_no where order_prefix = orderPrefix;
	end if;

	if errorResult = -1 then 
	rollback;
	set result = -1;
	else 
	commit;
	end if;

	select result;
END

2.创建数据表

CREATE TABLE `t_order_serial_no` (
  `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `order_prefix` varchar(64) NOT NULL COMMENT '订单号前缀',
  `cur_order_no` int(10) NOT NULL COMMENT '当前流水号数值',
  PRIMARY KEY (`id`),
  UNIQUE KEY `order_prefix_unique_idx` (`order_prefix`) USING BTREE COMMENT '唯一键索引'
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

3.代码

3.1 service层

@Service
public class OrderService {

    @Resource
    private OrderDAO orderDAO;
    /**
     * 订单流水号生成规则:order+年月日+5位不重复递增流水号(00001开始)
     * @return
     */
    public String getOrderSerialNumber() {
        String result;
        // 订单流水号前缀
        String orderPreFix = "ORDER" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")).replaceAll("-", "");
        // 请求参数
        Map<String, Object> requestMap = new HashMap<>();
        // 输入参数
        requestMap.put("orderPrefix", orderPreFix);
        // 输出参数
        requestMap.put("result", 0);
        Integer orderSerialNumber = orderDAO.getOrderSerialNumber(requestMap);
        if (Objects.isNull(orderSerialNumber) || -1 == orderSerialNumber) {
            throw new RuntimeException("生成失败!");
        }
        String serialNumberStr = getSerialNumber(orderSerialNumber, 5);
        result = orderPreFix + serialNumberStr;
        return result;
    }

    /**
     * 流水号位数
     * @param number 流水号数值
     * @param counts 位数
     * @return
     */
    public static String getSerialNumber(int number, int counts) {
        String result = "";
        for(int i = (number+"").length() ; i < counts; i++){
            result += "0";
        }
        result += number;
        return result;
    }
}

3.2 OrderDAO

/**
      * 获取订单流水号数值
      * @param requestMap
      * @return
      */
     Integer getOrderSerialNumber(Map<String, Object> requestMap);
 <select id="getOrderSerialNumber" parameterType="java.util.Map" statementType="CALLABLE" resultType="java.lang.Integer">
  {
        CALL getOrderSerialNo(
            #{orderPrefix, mode=IN,jdbcType=VARCHAR},
            #{result, mode=OUT,jdbcType=INTEGER}
        )
        }
    </select>

3.3 controller 层

    @Autowired
    private OrderService orderService;

    @RequestMapping("/getSerialNum")
    public String getSerialNum() {
        return orderService.getOrderSerialNumber();
    }

调用该接口进行完整订单流水号生成:
在这里插入图片描述

4.结果

以上示例演示的流水号生成规则是ORDER+年月日+五位数字(递增,不够0填充)在这里插入图片描述
注意: 在高并发情况下,只有数据库事务的隔离级别设置为REPEATABLE-READ及以上才可行。

文章来源:https://blog.csdn.net/m0_46211448/article/details/135576143
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。