主键字符串从增Java实现
主键字符串自增Java实现
程序实现字符串主键自增,例如:“SN000001”,希望下一条数据是“SN000002”,所以需要字符串主键自增,所以需要传入上一次的主键的字符串,通过调用工具类的方法可以获取下一条记录。
package com.commsoft.ypass.csmp.util.sys; /** * 字符串主键自增,条件当传进来的Str是空时,自动创建初始化主键 * 后面的依次自增 * @author lizhenbin * */ public class PrimaryKey { // 数字串最小值 private static final char MIN_DATA = '0'; // 数字串最大值 private static final char MAX_DATA = '9'; // 数字串默认从1开始 private static final char START_DATA = '1'; // 默认长度 private static final int DEFAULT_SIZE = 8; // KeySize的最大数 // Long的最大长度是19位,防止溢出 private static final int MAX_KEYSIZE_VALUE = 18; // 默认字符串Head private static final String DEFAULT_HEAD = "KEY"; // 主键字符串头部 private String keyHead; // 字符串数字位数,不足补0 private Integer keySize = 8; // 是否允许数字最大之后自增,默认false private boolean keyInc = false; // 程序执行开始系统时间 private Long startExecute = 0L; // 程序执行结束系统时间 private Long finishExecute = 0L; /** * 初始化主键字符串格式,默认达到KeySize后不可自增 * @param keyHead 字符串开头部分 * @param keySize 字符串数组长度 */ public PrimaryKey(String keyHead, Integer keySize) { super(); /** * 设置不可自增 */ if(this.checkSize(keySize)) this.keySize = keySize; else this.keySize = this.DEFAULT_SIZE; if(this.checkHead(keyHead)) this.keyHead = keyHead; else this.keyHead = this.DEFAULT_HEAD; } /** * 初始化主键字符串的格式 * @param keyHead 字符串开头部分 * @param keySize 字符串数组长度 * @param keyInc 数值最大值之后是否允许自增 */ public PrimaryKey(String keyHead, Integer keySize, boolean keyInc) { super(); if(this.checkSize(keySize)) this.keySize = keySize; else this.keySize = this.DEFAULT_SIZE; if(this.checkHead(keyHead)) this.keyHead = keyHead; else this.keyHead = this.DEFAULT_HEAD; this.keyInc = keyInc; } /** * 返回下一个字符串 * @param currentKey 当前主键 * @return 正常:下一个主键值 = 当前主键 + 1; * 当字符串数字达到KeySize的最大数时 * KeyInc为true时, 下一个主键字符串返回最大数 + 1 * KeyInc为false时, 返回空值 */ public synchronized String nextKey(String currentKey) { // 记录开始执行程序系统时间 this.startExecute = System.currentTimeMillis(); try { /** * 去掉首尾空字符 */ currentKey = currentKey.trim(); if(!this.check(currentKey)) { System.out.println(PrimaryKey.class.getSimpleName() + " Error: Input CurrentKey Str Type Illegal, Check '" + currentKey +"' is Right!"); return null; } StringBuilder sb = new StringBuilder(); sb.append(this.keyHead); int charIndex = 0; for(int i = 0; i < currentKey.length(); i++) { char symbol = currentKey.charAt(i); if(symbol >= this.MIN_DATA && symbol <= this.MAX_DATA) { charIndex = i; break; } } String dataStr = currentKey.substring(charIndex, currentKey.length()); Long dataNum = Long.valueOf(dataStr); dataNum++; if(dataNum < this.splitDataPosition()) { for(int i = 0; i <= this.keySize - String.valueOf(dataNum).length() - 1; i++) { sb.append(this.MIN_DATA); } sb.append(dataNum); }else if(dataNum >= this.splitDataPosition() && dataNum < this.maxDateNumber()) { sb.append(dataNum); }else{ // 超过大小最大数时 if(this.keyInc) { sb.append(dataNum); }else{ // 允许自增标志位false的时候返回空值 return null; } } return sb.toString(); } catch (Exception e) { System.out.println(e.toString()); return null; } finally { this.finishExecute = System.currentTimeMillis(); // System.out.println(PrimaryKey.class.getSimpleName() + " nextKey() Execute: " // + (this.finishExecute - this.startExecute) +"ms."); } } /** * 获取初始化字符串 * @return */ public synchronized String initStartKey() { StringBuilder sb = new StringBuilder(); sb.append(this.keyHead); for(int i = 0; i < this.keySize - 1; i++) { sb.append(this.MIN_DATA); } sb.append(this.START_DATA); return sb.toString(); } /** * 获取需要补零的最大数字 * @return */ private Long splitDataPosition() { StringBuilder sb = new StringBuilder(); sb.append(this.START_DATA); for(int i = 0; i < this.keySize - 1; i++) { sb.append(this.MIN_DATA); } return Long.valueOf(sb.toString()); } /** * 获取最大数 * @return */ private Long maxDateNumber() { StringBuilder sb = new StringBuilder(); for(int i = 0; i < this.keySize; i++) { sb.append(this.MAX_DATA); } return Long.valueOf(sb.toString()); } /** * 简单的验证空值 * @param key * @return * @throws Exception */ private boolean check(String key) throws Exception { try { // 空值验证 if(key == null || key.equals("")) return false; // key字符串长度验证 if(key.length() <= this.keyHead.length()) return false; // 是否符合初始化串开头验证 String head = key.substring(0, this.keyHead.length()); if(!head.equals(this.keyHead)) return false; /** * 串数字长度验证,当允许最大熟自增时候不检测 * 当不允许达到最大数字时验证长度合法性 */ String data = key.substring(this.keyHead.length(), key.length()); if(data.length() != this.keySize && !this.keyInc) return false; // 验证是否是数字串,通过一个转换变量 for(int i = 0; i < data.length(); i++) { char symbol = data.charAt(i); if(symbol > this.MAX_DATA || symbol < this.MIN_DATA) { return false; } } return true; } catch (Exception e) { throw e; } } /** * 验证输入的KeySize合法性 * @param keySize * @return */ private synchronized boolean checkSize(Integer keySize) { if(keySize != null && keySize > 0 && keySize <= this.MAX_KEYSIZE_VALUE) return true; return false; } /** * 验证输入的KeyHead,条件全部要求是字母 * @param keyHead * @return */ private synchronized boolean checkHead(String keyHead) { if(keyHead != null && !keyHead.equals("")) { for(int i = 0; i < keyHead.length(); i++) { char symbol = keyHead.charAt(i); if(symbol >= this.MIN_DATA && symbol <= this.MAX_DATA) { return false; } } return true; } return false; } }