java 自定义序列号 自动增长序列号
发布时间
阅读量:
阅读量
产生自定义格式的自动增长序列号:
/** * 自己维护的序列号,至少从1开始增长
*/
public abstract class IncrementNumber {
public IncrementNumber() {}
public IncrementNumber(int interval, int maxNum) {
this.interval = interval;
this.maxNum = maxNum;
}
public synchronized int cal() throws Exception {
if (serialNum == -1) {
serialNum = initStartNum(); // 已经使用的序列号一定 小于 缓存的序列号
intervalMax = serialNum + interval;
updateStartNum(intervalMax);
return serialNum;
}
if (isMax(serialNum)) { // 达到预定的最大值
resetSerialNum();
return serialNum;
}
serialNum++;
if (serialNum >= (intervalMax - 1)) { // 到达区间最大值
intervalMax += interval;
updateStartNum(intervalMax);
}
return serialNum;
}
/** * 初始化序列号,从缓存系统中来,比如数据库、文件等
* @return 初始序列号
* @throws Exception
*/
public abstract int initStartNum() throws Exception;
/** * 更新区间最大值到缓存系统,比如数据库、文件中。
* @param intervalMax 区间最大值
* @throws Exception
*/
public abstract void updateStartNum(int intervalMax) throws Exception;
/** * 重置序列号,从1开始
*/
protected void resetSerialNum() throws Exception {
this.serialNum = 1;
intervalMax = serialNum + interval;
updateStartNum(intervalMax);
}
/** * 是否是最大值
* @param num
* @return
*/
private boolean isMax(int num) {
return num >= maxNum;
}
public int getInterval() {
return this.interval;
}
public int getMaxNum() {
return this.maxNum;
}
/** 区间最大值 */
protected int intervalMax = 0;
/** 每次增加量 */
protected int interval = 20;
/** 预定的最大值 */
protected int maxNum = 9999;
/** 序列号 */
protected int serialNum = -1;
}
使用方法:
@Service
@Transactional
public class TableKeyManager extends IncrementNumber {
public TableKeyManager() {
super(100, 99999999);
}
@Override
public int initStartNum() throws Exception {
TableKey tableKey = tableKeyDao.getById(name);
date = DateConvertUtils.getDayEnd(DateConvertUtils.parse(tableKey.getDate(), "yyMMdd"));
dateEndMillis = date.getTime();
prefix = tableKey.getDate();
return (int) tableKey.getMaxNum();
}
@Override
public void updateStartNum(int intervalMax) throws Exception {
TableKey tableKey = tableKeyDao.getById(name);
tableKey.setDate(DateConvertUtils.format(new Date(dateEndMillis), "yyMMdd"));
tableKey.setMaxNum(intervalMax);
tableKeyDao.update(tableKey);
}
public String getNum() {
try {
long now = System.currentTimeMillis();
int no = 0;
if (now > dateEndMillis) {
date = DateConvertUtils.getDayEnd(new Date(now));
dateEndMillis = date.getTime();
prefix = DateConvertUtils.format(date, "yyMMdd");
resetSerialNum();
no = this.serialNum;
} else {
no = cal();
}
return prefix + ApplicationUtil.getFixedSizeNum(no, 8);
} catch (Exception e) {
e.printStackTrace();
}
throw new RuntimeException("生成序列号错误");
}
public void setName(String name) {
this.name = name;
}
private String prefix = null;
private long dateEndMillis = 0l;
private Date date = null;
private String name;
@Autowired
private TableKeyDao tableKeyDao;
}
这种方法仅在初始化时查询一次数据库,在每次到达增长上限时,计数自动叠加一个步长,同时更新数据库中的数据上限。
table_key的数据结构
CREATE TABLE `table_key` (
`key_name` varchar(100) NOT NULL COMMENT '需要维护的key名称',
`cur_no` mediumtext COMMENT '当前数据编号',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '数据编号更新时间',
`create_time` datetime DEFAULT NULL COMMENT '记录创建时间',
PRIMARY KEY (`key_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
全部评论 (0)
还没有任何评论哟~
