当前位置: 首页 > 工具软件 > Hilo > 使用案例 >

编号生成之Hilo高低位算法

宰父志新
2023-12-01

高低位算法是Hibernate的一种主键生成策略,使用一个高位值和一个低位值,然后把算法得到的两个值拼接起来作为数据库中的唯一主键。

Hilo算法需要额外的数据库表的支持,但不需要每次生成都去查询数据库,查询数据库的频率取决于maxLo。
  
创建数据库表

CREATE TABLE `sn` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `lastValue` bigint(20) NOT NULL,
  `name` varchar(32) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_name` (`name`) 
)

高低位算法Java代码

	/**
	 * 高低位算法生成器
	 */
	private class HiloOptimizer {

		/**
		 * 根据name查询对应lastValue
		 */
		private String name;

		/**
		 * 前缀,例如日期
		 */
		private String prefix;

		/**
		 * 最大低位值,决定查询数据库的频率
		 */
		private int maxLo;

		/**
		 * 低位值
		 */
		private int lo;

		/**
		 * 高位值
		 */
		private long hi;

		/**
		 * 末值
		 */
		private long lastValue;

		/**
		 * 构造方法
		 */
		HiloOptimizer(String name, String prefix, int maxLo) {
			this.name = name;
			this.prefix = prefix;
			this.maxLo = maxLo;
			//初始化时使 lo > maxLo 
			this.lo = maxLo + 1;
		}

		/**
		 * 生成编号
		 */
		public synchronized String generate() {
			if (lo > maxLo) {
				//调用查询方法获得末值,使其自增并更新到数据库中
				lastValue = getLastValue(name);
				//改变lo的值
				lo = 0;
				//高位值进位
				hi = lastValue * (maxLo + 1);
			}
			//拼接编号,lo+1
			return prefix + (hi + lo++);
		}
	}
	
	/**
	 * 获取末值
	 */
	private long getLastValue(String name) {
		String jpql = "select sn from Sn sn where sn.name like :name";
		Sn sn = entityManager.createQuery(jpql, Sn.class).setLockMode(LockModeType.PESSIMISTIC_WRITE).setParameter("name", name).getSingleResult();
		long lastValue = sn.getLastValue();
		sn.setLastValue(lastValue + 1);
		return lastValue;
	}
 类似资料: