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

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

比如:

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);
}
时间: 2024-11-09 00:47:37

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

项目中业务编号的实现(业务码+日期+自增序列)

目录 1. 实现思路 2. 代码实现 3. 总结 参考 做项目的时候,经常会有自动生成业务编码的需求,比如插入数据的时候需要生成如下产品编号:P-(年份日期和三位序列号),比如P-20180727001 1. 实现思路 使用业务编号+当前日期获得redis的key值; 使用redis的incr来原子性地获得其对应的自增数; 避免redis的数据冗余,需要在第一次incr的时候使用expireAt设置其数据当天24点过期. 这样即可在并发情况下获得不重复的相应编码. 2. 代码实现 public

生成日期流水号帮助类

/// <summary> /// 生成日期流水号 /// </summary> public class DateSerialNumberGenerator { private static readonly object Lock = new object(); private static string _nowYear;//系统年份 private static string _nowMonth;//系统月份 /// <summary> /// 获取下一个日期流

使用zxing批量生成二维码立牌

使用zxing批量在做好的立牌背景图的指定位置上,把指定的文本内容(链接地址.文本等)生成二维码并放在该位置, 最后加上立牌编号. 步骤: 1).做好背景图,如下图: 2).生成二维码BufferedImage对象.代码如下: /** * * @Title: toBufferedImage * @Description: 把文本转化成二维码图片对象 * @param text * 二维码内容 * @param width * 二维码高度 * @param height * 二位宽度 * @par

广告小程序后端开发(16.优惠券系统:原理流程图,奖品实验数据,生成二维码)

业务需求:在一个广告小程序内发许多其他的小程序的优惠券. 1.原理流程图 2.奖品(优惠券)实验数据 1.修改apps/ad/models.py中的Prize表类 class Prize(models.Model): """奖品""" title = models.CharField(max_length=15, null=True, blank=True, verbose_name='标题', help_text='最多15字') url=mo

微信生成二维码 只需一个网址即刻 还有jquery生成二维码

<div class="orderDetails-info"> <img src="http://qr.topscan.com/api.php?text=http://123.net/index.php?s=/Home/Index/yanzheng/mai/{$dange.id}" style="width: 5rem; margin-bottom: 1rem;" > </div> http://qr.tops

通过jquery-qrcode在线生成二维码

随着移动互联网的发展,二维码现在应用得越来越广泛了,随手扫扫就可以浏览网站.加个好友什么的,比起手工输入真的是方便太多了. 前期做了一个综合测评系统,考虑逐步实现移动化,一长串的IP地址用户输入也不方便,借助二维码的话,用户拿起手机扫扫就可以直接进入系统. 基于这个应用场景,就上网研究下了网站二维码的实现方式,归纳起来有以下两种: 1.借助一些二维码生成网站或者二维码生成器生成二维码图片,然后挂在网站上,如码云 QR-Code (二维码) 在线生成器 优点:开发成本为零,能够快速实现多样化的二维

C# winform通过ThoughtWorks.QRCode生成二维码解码可以添加logo

首先要下载ThoughtWorks.QRCode.dll文件,添加引用. ThoughtWorks.QRCode.dll下载,点击下载 界面如下: 代码: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Win

Android:使用ZXing生成二维码(支持加入Logo图案)

ZXing是谷歌的一个开源库.能够用来生成二维码.扫描二维码.本文所介绍的是第一部分. 首先上效果图: ZXing相关各种文件官方下载地址:https://github.com/zxing/zxing/releases 或者在这里下载(仅仅有本项目所用的jar包,版本:3.2.0):链接: http://pan.baidu.com/s/1hq3s5EW password: mvg7 1.生成二维码的工具类 /** * 二维码生成工具类 */ public class QRCodeUtil { /

jquery生成二维码并实现图片下载

1.引入jquery的两个js文件 <script src="../scripts/erweima/jquery-1.10.2.min.js"></script> <script type="text/javascript" src="../scripts/erweima/jquery.qrcode.min.js"></script> 2.准备一个展示二维码的div <div id="