`
lizhenbin2010
  • 浏览: 101278 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

主键字符串自增Java实现

    博客分类:
  • J2se
 
阅读更多

      程序实现字符串主键自增,例如:“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;
	}
}

  

分享到:
评论

相关推荐

    自定义字符串自增java

    字符串的自增,自定义格式,可实现项目中由程序实现VARCHAR类型的主键自增

    JPA主键策略(针对数据库自增字段重置后无效检查项)

    这种策略占用空间较大,因为主键是一个字符串类型的字段。uuid策略适用于需要高唯一性的场景,但它占用空间较大。 hilo hilo是一种基于高低位生成主键的策略。这种策略需要在数据库中建立一个额外的表,默 认表名...

    04_传智播客JPA详解_第一个JPA实例与JPA主键生成策略

    5. **UUID**:生成全局唯一的UUID字符串作为主键。 6. **ASSIGNED**:主键由应用程序负责生成,JPA不参与。 在JPA中,可以通过`@GeneratedValue`注解指定主键生成策略,如`@GeneratedValue(strategy = ...

    java实现数据库主键生成示例

    2. 创建一个 `StringBuilder` 对象,用于构建主键字符串,`StringBuilder str = new StringBuilder(20);` 3. 将时间戳追加到字符串中,确保主键的一部分基于时间。 4. 使用 `integer.getAndIncrement()` 获取当前 ...

    java上传下载主键(源代码+说明)

    在数据库中,主键可以是自增的整数、UUID字符串,或者是根据业务逻辑生成的唯一值。例如,对于自增主键,MySQL的`AUTO_INCREMENT`特性可以自动为新插入的记录生成一个唯一的ID。而在Java中,我们可以使用JPA(Java ...

    mysql 如何插入随机字符串数据的实现方法

    如果需要在`citation`表中插入随机引用,而`papers`表的主键不是递增的,可以先添加一个临时的自增列`temp`,然后利用这个临时列来映射随机生成的数字。比如,插入10万条数据的SQL语句可以修改为: ```sql String ...

    短网址服务两种不同算法JAVA实现

    首先,为长URL生成一个唯一的ID(例如,使用数据库的自增主键),然后将这个ID转换为特定长度的字符串。例如,可以使用模运算将ID映射到一个较小的数值范围,再将这个数值转换为Base36或Base62编码。这种方式的优势...

    跟着铁哥学Java,MyStore项目 CH02 用户模块实现

    `@NotNull`和`@NotEmpty`的区别在于,前者用于检查对象是否为null,后者用于检查集合或字符串是否为空。全局异常捕获是通过SpringBoot的AOP(面向切面编程)实现,可以统一处理未被捕获的异常,提供一致的错误响应。...

    自动生成主键uuid.zip

    上述代码首先通过`UUID.randomUUID()`生成一个UUID实例,然后使用`toString()`方法将其转换为字符串,再通过`replace("-","")`移除短横线,最后得到一个32位的无序UUID。 如果需要生成有序的32位UUID,情况会稍微...

    真实项目中关于主键生成方式的剖析(JPA)

    例如,对于自增类型,可以设置`native`策略,对于手动生成的主键,如字符串类型,可以使用`assigned`策略。这里,`&lt;T&gt;`泛型允许我们根据需求选择主键的类型,如`Long`用于自增,`String`用于手动指定。 在旧系统...

    hibernate主键生成策略

    - **简介**:`uuid.string` 策略生成一个 16 位的字符串表示的唯一标识符。 - **应用场景**:与 `uuid.hex` 类似,适用于需要全局唯一标识符的场合。 - **特点**: - 生成的 UUID 以字符串形式存储。 - 存储空间...

    Hibernate主键生成

    4. **uuid**:生成128位的UUID字符串作为主键,适用于字符串列。这种方式保证了全局唯一性,但可能较长。 5. **hilo**:基于hi/lo算法,需要额外的数据库表来存储主键生成历史状态。提高性能,减少对数据库的交互...

    Hibernate用UUID作为主键的Demo

    在使用UUID作为主键时,数据库表对应的主键字段应设置为足够的长度,如MySQL的`CHAR(36)`或PostgreSQL的`VARCHAR(36)`,以容纳32位十六进制字符串加上4个破折号。 ### 6. 测试与运行 在实际项目中,你可以创建一个...

    hibernate的主键生成策略

    uuid策略生成全局唯一的UUID字符串作为主键,确保了跨数据库和网络环境的唯一性。 9. **foreign**: foreign策略依赖于另一个实体的主键,通常用于关联映射中。 选择合适的主键生成策略取决于项目需求,包括...

    MybatisPlus主键生成策略方法详解.docx

    - `ID_WORKER_STR`: 基于`idWorker`的字符串表示,适合字符串类型的数据库字段。 3. **局部注解配置策略** 局部注解`@TableId`可用于单个实体类字段上,指定主键类型。例如: ```java @TableId(type = IdType....

    Hibernate主键生成策略

    - **描述**:生成一个 16 位的 UUID 字符串。 - **优点**:保证全局唯一性。 - **缺点**:主键长度较长,可能会影响性能。 - **应用场景**:需要保证全局唯一性的场景,且对主键长度有一定要求。 10. **foreign...

    08_ibatis教程_sql主键生成方式.rar

    在Java中,可以直接使用`java.util.UUID.randomUUID().toString()`生成UUID字符串,然后作为主键插入数据库。 6. **数据库触发器(Database Triggers)**: 在某些情况下,可以创建数据库触发器来自动处理主键的...

    java自动生成ID号的方法

    这个方法会生成一个无短横线的32位字符串,具有很高的唯一性,但并不适合用作连续编号,因为它们是完全随机的。 2. **雪花算法(Snowflake)**:由Twitter开源的一种分布式ID生成算法,通过时间戳、工作节点ID和...

    mysql_guid主键生成方式范例

    GUID是一个128位的数字,通常以32位16进制字符串的形式表示,如“0123456789ABCDEF0123456789ABCDEF”。它的独特之处在于,只要生成算法正确,即使在不同地点、同一时间生成的多个GUID也几乎不可能相同。这使得GUID...

    Excel生成Java 带JPA注解的实体类

    这里,`parseExcelAndGenerateCode`方法是核心,它需要实现读取Excel、解析内容并构建Java源码字符串的逻辑。`saveJavaSourceToFile`则负责将生成的源码保存到指定的Java源码目录。 通过这种方式,开发人员可以大大...

Global site tag (gtag.js) - Google Analytics