Advertisement

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)

还没有任何评论哟~