在springboot中通过DataFieldMaxValueIncrementer生成全局唯一连续的ID

获取全局的ID,方法有很多,常见的有几个,这都是网上说烂了的东西

  • Snowflake雪花算法
  • UUID
  • Redis自增
  • 数据库自增

各有各的好处弊端,自己酌情而定。这里介绍一个很简单的办法,是基于数据库ID生成器。

DataFieldMaxValueIncrementer

spring-jdbc提供的一个工具类接口,它定义了3个获取下一个ID的方法。

public interface DataFieldMaxValueIncrementer {

	int nextIntValue() throws DataAccessException;

	
	long nextLongValue() throws DataAccessException;


	String nextStringValue() throws DataAccessException;

}

主要有2个实现

AbstractSequenceMaxValueIncrementer

使用标准的数据库序列产生主键值

AbstractColumnMaxValueIncrementer

使用一张模拟序列的表产生主键值

其中MSQL的实现

MySQLMaxValueIncrementer

MySQLMaxValueIncrementer 的配置使用

MySQLDataFieldMaxValueIncrementer

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
import org.springframework.jdbc.support.incrementer.MySQLMaxValueIncrementer;

@Configuration
public class MySQLDataFieldMaxValueIncrementer {
	
	@Bean
	public DataFieldMaxValueIncrementer dataFieldMaxValueIncrementer (@Autowired DataSource dataSource) {
		MySQLMaxValueIncrementer mySQLMaxValueIncrementer  = new MySQLMaxValueIncrementer();
		/**
		 * 数据源
		 */
		mySQLMaxValueIncrementer.setDataSource(dataSource);
		/**
		 * 维护序列的表名
		 */
		mySQLMaxValueIncrementer.setIncrementerName("id_table");
		/**
		 * 维护序列表中的列名
		 */
		mySQLMaxValueIncrementer.setColumnName("id");
		/**
		 * 字符串结果的填充长度,不足长度会在前面填充0
		 */
		mySQLMaxValueIncrementer.setPaddingLength(10);
		/**
		 * 是否每次操作都是使用新的链接,默认为true
		 */
		mySQLMaxValueIncrementer.setUseNewConnection(false);
		/**
		 * 设置缓存主键的个数,当内存中主键值用完后,递增器将一次性获取cacheSize个主键
		 */
		mySQLMaxValueIncrementer.setCacheSize(1);
		
		return mySQLMaxValueIncrementer;
	}
}

表结构

CREATE TABLE `id_table` (
  `id` int(10) unsigned NOT NULL COMMENT 'id',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

数据表创建后id不能为null,必须先初始化一个值(建议:0),不然多次获取返回的结果都是:0

使用

@Autowired
private DataFieldMaxValueIncrementer dataFieldMaxValueIncrementer;

@Test
public void test () {
	int val = this.dataFieldMaxValueIncrementer.nextIntValue();
	System.out.println(val); // 1
		
	String strVal = this.dataFieldMaxValueIncrementer.nextStringValue();		
	System.out.println(strVal); // 0000000002
}