只有一个JAVA文件,拷贝过去即可用,直接贴代码:
package com.serial;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class CreatOrder {
public static void main(String[] args) {
getOrderNo();
}
public static String getOrderNo() {
SerialNumber serial = new FileEveryDaySerialNumber(4, "yyyy/MM/dd/",
"EveryDaySerialNumber.dat");
String orderNo = serial.getSerialNumber();
System.out.println(orderNo);
return orderNo;
}
}
abstract class SerialNumber {
public synchronized String getSerialNumber() {
return process();
}
protected abstract String process();
}
abstract class EveryDaySerialNumber extends SerialNumber {
protected SimpleDateFormat sdf = null;
protected DecimalFormat df = null;
public EveryDaySerialNumber(int width, String dataFormat) {
if (width < 1) {
throw new IllegalArgumentException(
"Parameter length must be great than 1!");
}
// 补齐序列化流水号的位数
char[] chs = new char[width];
for (int i = 0; i < width; i++) {
chs[i] = '0';
}
df = new DecimalFormat(new String(chs));
sdf = new SimpleDateFormat(dataFormat);
}
protected String process() {
Date date = new Date();
int n = getOrUpdateNumber(date, 1);
// 返回日期格式+序列号的编号
return format(date) + format(n);
}
protected String format(Date date) {
return sdf.format(date);
}
protected String format(int num) {
return df.format(num);
}
/**
* 获得序列号,同时更新持久化存储中的序列
*
* @param current 当前的日期
* @param start 初始化的序号
* @return 所获得新的序列号
*/
protected abstract int getOrUpdateNumber(Date current, int start);
}
class FileEveryDaySerialNumber extends EveryDaySerialNumber {
/**
* 持久化存储的文件
*/
private File file = null;
/**
* 存储的分隔符
*/
private final static String FIELD_SEPARATOR = ",";
/**
* 返回指定时间格式+序列化长度的业务流水号
*
* @param width 序列化位数
* @param sdf 时间格式
* @param filename 序列化文件
*/
public FileEveryDaySerialNumber(int width, String dataFormat,
String filename) {
super(width, dataFormat);
file = new File(filename);
}
@Override
protected int getOrUpdateNumber(Date current, int start) {
String date = format(current);
// 如果是第一次调用,num默认为传入start
int num = start;
if (file.exists()) {
// 从序列化文件中取出数据
List<String> list = FileUtil.readList(file);
String[] data = list.get(0).split(FIELD_SEPARATOR);
// 序列化文件中的日期和传入的日期匹配,则取出序列化文件中的num,否则写入新一天的数据
if (date.equals(data[0])) {
num = Integer.parseInt(data[1]);
}
}
// 将从序列化文件中取出的num加1,重写写入序列化文件
// 文件格式为:20160108,2
FileUtil.rewrite(file, date + FIELD_SEPARATOR + (num + 1));
return num;
}
}
class FileUtil {
/**
* 将data数据写入序列化文件EveryDaySerialNumber.dat中
*
* @param file
* @param data
*/
public static void rewrite(File file, String data) {
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(file));
bw.write(data);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bw != null) {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 将序列化文件EveryDaySerialNumber.dat 按行读出放入data中 2016-1-8
*
* @param file
* @return
*/
public static List<String> readList(File file) {
BufferedReader br = null;
List<String> data = new ArrayList<String>();
try {
br = new BufferedReader(new FileReader(file));
for (String str = null; (str = br.readLine()) != null;) {
data.add(str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return data;
}
}
参数说明 i 时间格式可以根据客户需求自主设置
ii 序列化位数可以根据该业务每日的调用量设置,如每日最多会产生一百条数据,则设置3位(000~999)即可
iii 持久化保存文件,保证服务重新启动后,流水号的正常获取
调用结果:2016/01/08/0002
同时打开序列化文件查看其存储内容为:2016/01/08/,3
由此可见在本次获取流水号的同时,程序已经生成下一流水号并保存到序列化文件中。
注:可以通过设置不同的日期格式,获取不同格式的流水号。如:201601080002、2016-01-08-0002等。