java生成订单编号 日期+流水号

参考网上的方法,一般有两种,一种是采用redis记录流水号,另一种是每次都去数据库查询最大值+1,我这里做了个结合,redis为空的时候才去数据库取。

采用redis记录流水号

// An highlighted block
package com.zwwl.mm.business.service;

import com.zwwl.mm.business.mapper.OrderDao;
import com.zwwl.mm.system.exception.TransactionException;
import com.zwwl.mm.system.service.RedisService;
import com.zwwl.mm.system.utils.RedisKeyUtils;
import com.zwwl.mm.system.utils.StrUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 单据编号生成
 */
@Service
public class SerialNumberService {

    private static final String PATTERN = "000000000000000000";

    @Resource
    private RedisService<String, Integer> redisService;
    @Resource
    private OrderDao orderDao;

    /**
     * 生成 前缀 + yyyyMMdd + XXXX  编号
     * @param preSn 前缀
     * @param width 流水号位数
     * @return
     */
    public synchronized String generateSn(String preSn, int width){
        String todayDate = new SimpleDateFormat("yyyyMMdd")
                .format(new Date());

        StringBuilder sb = new StringBuilder(preSn).append(todayDate);

        String key = RedisKeyUtils.PREFIX_SERIAL_NUMBER + sb.toString();
        Integer count = redisService.getForValue(key);
        if (count != null) {
            count = count + 1;
        } else {
            //方案二 从数据库查询当天的最大的流水号
            String maxSn = orderDao.getMaxSnByPrefix(sb.toString());
            if(StrUtils.isNotEmpty(maxSn)){
                String str = maxSn.substring(sb.length());
                count = Integer.parseInt(str) + 1;
            }else{
                count = 1;
            }
        }

        if(count.toString().length() > width){
            throw new TransactionException("单据流水号已经超过指定长度");
        }

        DecimalFormat df = new DecimalFormat(PATTERN.substring(0, width));

        sb.append(df.format(count));

        //写入redis
        redisService.setForValue(key, count,1L, TimeUnit.DAYS);

        return sb.toString();
    }

}

查询数据库表当前最大流水号

<select id="getMaxSnByPrefix" resultType="java.lang.String">
		SELECT sn
		FROM t_order
		WHERE sn LIKE CONCAT(#{prefix},'%')
		order by sn desc
		limit 1;
	</select>

版权声明:本文为zxl2355571508zxl原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。