按时间生成流水号 php,流水号的生成(日期+业务码+自增序列)

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

比如:

id int unsigned primary key auto_increment,1

但往往会碰到一些问题,比如:

开发环境中,使用爬虫抓取一些数据,建立索引,再把数据迁移到上线环境,会导致索引中的id和

上线环境数据库中id对不上,所以决定使用字符串作为主键。

那么问题来了,如何生成唯一的序列号?

格式按照:yyyyMMdd+两位业务码+10位的自增序列,

比如20150101**99**0000000001。

思路:

获得日期很简单;

业务码是调用服务传入的参数;

使用Redis来实现10位的自增序列的保存和自增,使用serial.number:{日期}的格式来保存某一天的自增序列的值;

主要代码如下:

public interface SerialNumberService {

/**

* 序列号自增序列

*/

String SERIAL_NUMBER = "serial.number:";

/**

* 根据两位业务码字符串,生成一个流水号,格式按照:

* yyyyMMdd{bizCode}{10位的自增序列号}

*

* @param bizCode

* 两位,00-99

* @return 20位的序列号

* @throws ServiceException

*/

String generate(String bizCode) throws ServiceException;

//其实,应该对bizCode做白名单验证,以免恶意伪造

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();

}

}1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

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

public interface RedisDao {

String get(String key);

/**

* 自增,+1,返回增加后的值

*

* @param key

* @return

*/

long incr(String key);

}1

2

3

4

5

6

7

8

9

10

11

12

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值