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版权协议,转载请附上原文出处链接和本声明。