产生自定义格式的自动增长序列号

Posted 段桥123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了产生自定义格式的自动增长序列号相关的知识,希望对你有一定的参考价值。

产生自定义格式的自动增长序列号:

Java代码  技术分享图片
  1. /** 
  2.  * 自己维护的序列号,至少从1开始增长 
  3.  */  
  4. public abstract class IncrementNumber {  
  5.       
  6.     public IncrementNumber() {}  
  7.       
  8.     public IncrementNumber(int interval, int maxNum) {  
  9.         this.interval = interval;  
  10.         this.maxNum = maxNum;  
  11.     }  
  12.       
  13.     public synchronized int cal() throws Exception {  
  14.         if (serialNum == -1) {  
  15.             serialNum = initStartNum(); // 已经使用的序列号一定 小于 缓存的序列号  
  16.             intervalMax = serialNum + interval;  
  17.             updateStartNum(intervalMax);  
  18.             return serialNum;  
  19.         }  
  20.         if (isMax(serialNum)) { // 达到预定的最大值  
  21.             resetSerialNum();  
  22.             return serialNum;  
  23.         }  
  24.         serialNum++;  
  25.         if (serialNum >= (intervalMax - 1)) { // 到达区间最大值  
  26.             intervalMax += interval;  
  27.             updateStartNum(intervalMax);  
  28.         }  
  29.         return serialNum;  
  30.     }  
  31.       
  32.     /** 
  33.      * 初始化序列号,从缓存系统中来,比如数据库、文件等 
  34.      * @return 初始序列号 
  35.      * @throws Exception 
  36.      */  
  37.     public abstract int initStartNum() throws Exception;  
  38.       
  39.     /** 
  40.      * 更新区间最大值到缓存系统,比如数据库、文件中。 
  41.      * @param intervalMax 区间最大值 
  42.      * @throws Exception 
  43.      */  
  44.     public abstract void updateStartNum(int intervalMax) throws Exception;  
  45.       
  46.     /** 
  47.      * 重置序列号,从1开始 
  48.      */  
  49.     protected void resetSerialNum() throws Exception {  
  50.         this.serialNum = 1;  
  51.         intervalMax = serialNum + interval;  
  52.         updateStartNum(intervalMax);  
  53.     }  
  54.       
  55.     /** 
  56.      * 是否是最大值 
  57.      * @param num 
  58.      * @return 
  59.      */  
  60.     private boolean isMax(int num) {  
  61.         return num >= maxNum;  
  62.     }  
  63.       
  64.     public int getInterval() {  
  65.         return this.interval;  
  66.     }  
  67.       
  68.     public int getMaxNum() {  
  69.         return this.maxNum;  
  70.     }  
  71.       
  72.     /** 区间最大值 */  
  73.     protected int intervalMax = 0;  
  74.       
  75.     /** 每次增加量 */  
  76.     protected int interval = 20;  
  77.       
  78.     /** 预定的最大值 */  
  79.     protected int maxNum = 9999;  
  80.       
  81.     /** 序列号 */  
  82.     protected int serialNum = -1;  
  83. }  

 

使用方法:

Java代码  技术分享图片
  1. @Service  
  2. @Transactional  
  3. public class TableKeyManager extends IncrementNumber {  
  4.       
  5.     public TableKeyManager() {  
  6.         super(100, 99999999);  
  7.     }  
  8.   
  9.     @Override  
  10.     public int initStartNum() throws Exception {  
  11.         TableKey tableKey = tableKeyDao.getById(name);  
  12.         date = DateConvertUtils.getDayEnd(DateConvertUtils.parse(tableKey.getDate(), "yyMMdd"));  
  13.         dateEndMillis = date.getTime();  
  14.         prefix = tableKey.getDate();  
  15.         return (int) tableKey.getMaxNum();  
  16.     }  
  17.   
  18.     @Override  
  19.     public void updateStartNum(int intervalMax) throws Exception {  
  20.         TableKey tableKey = tableKeyDao.getById(name);  
  21.         tableKey.setDate(DateConvertUtils.format(new Date(dateEndMillis), "yyMMdd"));  
  22.         tableKey.setMaxNum(intervalMax);  
  23.         tableKeyDao.update(tableKey);  
  24.     }  
  25.       
  26.     public String getNum() {  
  27.         try {  
  28.             long now = System.currentTimeMillis();  
  29.             int no = 0;  
  30.             if (now > dateEndMillis) {  
  31.                 date = DateConvertUtils.getDayEnd(new Date(now));  
  32.                 dateEndMillis = date.getTime();  
  33.                 prefix = DateConvertUtils.format(date, "yyMMdd");  
  34.                 resetSerialNum();  
  35.                 no = this.serialNum;  
  36.             } else {  
  37.                 no = cal();  
  38.             }  
  39.             return prefix + ApplicationUtil.getFixedSizeNum(no, 8);  
  40.         } catch (Exception e) {  
  41.             e.printStackTrace();  
  42.         }  
  43.         throw new RuntimeException("生成序列号错误");  
  44.     }  
  45.       
  46.     public void setName(String name) {  
  47.         this.name = name;  
  48.     }  
  49.       
  50.     private String prefix = null;  
  51.       
  52.     private long dateEndMillis = 0l;  
  53.       
  54.     private Date date = null;  
  55.       
  56.     private String name;  
  57.       
  58.     @Autowired  
  59.     private TableKeyDao tableKeyDao;  
  60. }  

 

这种方法仅在初始化时查询一次数据库,在每次到达增长上限时,计数自动叠加一个步长,同时更新数据库中的数据上限。

 

table_key的数据结构

Sql代码  技术分享图片
  1. CREATE TABLE `table_key` (  
  2.   `key_name` varchar(100) NOT NULL COMMENT ‘需要维护的key名称‘,  
  3.   `cur_no` mediumtext COMMENT ‘当前数据编号‘,  
  4.   `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ‘数据编号更新时间‘,  
  5.   `create_time` datetime DEFAULT NULL COMMENT ‘记录创建时间‘,  
  6.   PRIMARY KEY (`key_name`)  
  7. ) ENGINE=InnoDB DEFAULT CHARSET=utf8  

以上是关于产生自定义格式的自动增长序列号的主要内容,如果未能解决你的问题,请参考以下文章

pgsql如何让表id自动增长

sqlserver中如何设置两个自动增长的表示列

[转]MySQL如何设置自动增长序列 SEQUENCE

Oracle怎么建自动增长列

mysql的主键是自动增长的,oracle的主键是起啥作用的

自定义View实现自动数字增长的TextView