需求:
如何生成唯一的订单序列号?
格式按照:yyyyMMdd+两位业务码+10位的自增序列,
比如:20150101**99**0000000001。
思路:
(1)获得日期很简单;
(2)业务码是调用服务传入的参数;
(3)使用Redis来实现10位的自增序列的保存和自增,使用serial.number:{日期}的格式来保存某一天的自增序列的值;
直接上代码:
第一步:
public class StringUtil { static final int DEFAULT_LENGTH = 10; /** * 得到10位的序列号,长度不足10位,前面补0 * * @param seq * @return */ public static String getSequence(long seq) { String str = String.valueOf(seq); int len = str.length(); if (len >= DEFAULT_LENGTH) {// 取决于业务规模,应该不会到达10 return str; } int rest = DEFAULT_LENGTH - len; StringBuilder sb = new StringBuilder(); for (int i = 0; i < rest; i++) { sb.append('0'); } sb.append(str); return sb.toString(); } }
第二步:
public Long incr(String key, long liveTime) { RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory()); Long increment = entityIdCounter.getAndIncrement(); if ((null == increment || increment.longValue() == 0) && liveTime > 0) {//初始设置过期时间 entityIdCounter.expire(liveTime, TimeUnit.HOURS); } return increment; }
补充:incr是从0开始,如果需要从1开始,需要多加一次,这里需要1开始。还有个坑因为是五位数,所以需要将没有的位数用0去补齐。
第三步:
@Service public class SerialNumberService { @Resource private RedisDao redisDao;
//生成导入批次号 private String getOrder() { String order = ""; String dateString = DateUtils.formatDate(new Date()); Long incr = redisComponent.incr("deviceRepair" + dateString, 24); if (incr == 0) { incr = redisComponent.incr("deviceRepair" + dateString, 24); } DecimalFormat df = new DecimalFormat("00000"); String[] drs = dateString.split("-"); for (int i = 1; i < drs.length; i++) { order += drs[i]; } order = "X" + order + df.format(incr); return order; }