码迷,mamicode.com
首页 > 其他好文 > 详细

流水号的生成(日期+业务码+自增序列)

时间:2015-06-29 13:23:23      阅读:251      评论:0      收藏:0      [点我收藏+]

标签:流水号   序列号   日期   自增   redis   

项目开发时,使用了两套数据库,开发环境和上线环境,数据库表中大多采用了自增主键,
比如:

id int unsigned primary key auto_increment,

但往往会碰到一些问题,比如:
开发环境中,使用爬虫抓取一些数据,建立索引,再把数据迁移到上线环境,会导致索引中的id和
上线环境数据库中id对不上,所以决定使用字符串作为主键。

那么问题来了,如何生成唯一的序列号?
格式按照:yyyyMMdd+两位业务码+10位的自增序列,

比如20150101**99**0000000001。

思路:
获得日期很简单;
业务码是调用服务传入的参数;
使用Redis来实现10位的自增序列的保存和自增,使用serial.number:{日期}的格式来保存某一天的自增序列的值;

主要代码如下:

public interface SerialNumberService {
    /**
     * 序列号自增序列
     */
    String SERIAL_NUMBER = "serial.number:";

    /**
     * 根据两位业务码字符串,生成一个流水号,格式按照:<br/>
     * yyyyMMdd{bizCode}{10位的自增序列号}
     * 
     * @param bizCode
     *            两位,00-99
     * @return 20位的序列号
     * @throws ServiceException
     */
    String generate(String bizCode) throws ServiceException;

    default boolean isLegal(String bizCode) {
        if (bizCode == null || bizCode.length() != 2) {
            throw new RuntimeException("bizCode: " + bizCode + "异常");
        }
        if (Character.isDigit(bizCode.charAt(0))
                && Character.isDigit(bizCode.charAt(1)))
            return true;
        return false;
    }
}

@Service
public class SerialNumberServiceImpl implements SerialNumberService {
    @Resource
    private RedisDao redisDao;

    @Override
    public String generate(String bizCode) throws ServiceException {
        /** 检查业务码 */
        boolean isLegal = isLegal(bizCode);
        if (!isLegal) {
            throw new ServiceException("bizCode参数不合法");
        }
        /** 获取今天的日期:yyyyMMdd */
        String date = TimeUtil.getToday();
        /** 构造redis的key */
        String key = SERIAL_NUMBER + date;
        /** 自增 */
        long sequence = redisDao.incr(key);
        String seq = StringUtil.getSequence(sequence);
        StringBuilder sb = new StringBuilder();
        sb.append(date).append(bizCode).append(seq);
        String serial = sb.toString();
        return serial;
    }
}

public class TimeUtil {
    private TimeUtil() {
    }

    /**
     * 获取今日日期
     * 
     * @return
     */
    public static String getToday() {
        return "20150101";
    }

}

public class StringUtil {
    private 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();
    }

}

只声明了RedisDao接口,可以使用Jedis客户端来实现。

public interface RedisDao {
    String get(String key);

    /**
     * 自增,+1,返回增加后的值
     * 
     * @param key
     * @return
     */
    long incr(String key);
}

流水号的生成(日期+业务码+自增序列)

标签:流水号   序列号   日期   自增   redis   

原文地址:http://blog.csdn.net/u010786672/article/details/46680629

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!