mysql 和 java 自增长序号

思维的世界 2014-10-30

select  (@rowNO := @rowNo+1) AS rowno,s.com_uid from (select  com_uid from sms_balance) s,(select @rowNO :=0) b ;

或者 获取最大的编号,然后加1  再保存到数据库中.

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

/** 
 * 自己维护的序列号,至少从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的数据结构

Sql代码  mysql 和 java 自增长序号
  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  

在不用AUTO_INCREMENT的情况下生成序列,可利用带参数的LAST_INSERT_ID()函数。如果用一个带参数的LAST_INSERT_ID(expr)去插入或修改一个数据列,紧接着又调用不带参数的LAST_INSERT_ID()函数,则第二次函数调用返回的就是expr的值。下面演示该方法的具体操作:
先创建一个只有一个数据行的数据表:create table seq_table (id int unsigned not null);insert into seq_table values (0);接着用以下操作检索出序列号:
update seq_table set seq = LAST_INSERT_ID( seq + 1 );select LAST_INSERT_ID();
通过修改seq+1中的常数值,可生成不同步长的序列,如seq+10可生成步长为10的序列。该方法可用于计数器,在数据表中插入多行以记录不同的计数值。再配合LAST_INSERT_ID()函数的返回值生成不同内容的计数值。这种方法的优点是不用事务或LOCK,UNLOCK表就可生成唯一的序列编号。不会影响其它客户程序的正常表操作.

相关推荐