Stellen Sie eine Frage
Wie verwende ich jAVA, um Seriennummern zu generieren und gleichzeitig Konfigurierbarkeit und hohe Parallelität zu unterstützen???
Lösen Sie das Problem
Gehen Sie davon aus, dass Ihr Projekt integriert wurde Caching-Technologie
Wenn Sie über eine bestimmte Java-Grundlage verfügen
Wenn...
Der folgende Code implementiert einen Seriennummerngenerator, der eine hohe Parallelität unterstützt, konfigurierbar und hochgradig ist Für die gleichzeitige Verwendung durch mehrere Module eines Projekts unterstützen Seriennummern das Caching, d. h., eine bestimmte Anzahl von Seriennummern wird vorab generiert und bei Bedarf im Cache gespeichert Nachdem die Seriennummern im Cache verwendet wurden, generieren Sie eine bestimmte Anzahl von Seriennummern neu und legen Sie sie in den Cache ab. Wiederholen Sie diesen Zyklus, um die Effizienz zu verbessern...
Gleichzeitig die Seriennummer Der Zahlengenerator ist threadsicher und durch Threadsperren geschützt. Verwenden Sie...
Datenbanktabellendesign
[code]CREATE TABLE sys_serial_number2 ( "id" varchar(32) COLLATE "default" NOT NULL, "module_name" varchar(50) COLLATE "default", "module_code" varchar(50) COLLATE "default", "config_templet" varchar(50) COLLATE "default", "max_serial" varchar(32) COLLATE "default", "pre_max_num" varchar(32) COLLATE "default", "is_auto_increment" char(1) COLLATE "default" )
Anleitung:
[code]module_name:模块名称 module_code:模块编码 config_templet:当前模块 使用的序列号模板 max_serial:存放当前序列号的值 pre_max_num:预生成序列号存放到缓存的个数 is_auto_increment:是否自动增长模式,0:否 1:是
Hinweis: Derzeit unterstützt die Seriennummernvorlage nur Buchstaben und dynamische Zahlen (0000 steht für 1-9999), und das Datum hat die Kombinationsform ${DATE}
is_auto_increment ist als 1 konfiguriert. Zu diesem Zeitpunkt lautet die von der Konfigurationsvorlage für CX000000 generierte Seriennummer: CX1, CX2, CX3… , CX00000003
Anweisungen zur Datenbankkonfiguration: Wenn Sie die Projektnummer des Projektmoduls benötigen, müssen Sie einen Datensatz in der Datenbanktabelle sys_serial_number konfigurieren:
[code]| id | module_name | module_code | config_templet | max_serial | pre_max_num | is_auto_increment |-------|--------------|--------------|-----------------|-------------|-------------|--------------------/ | xxxx | 项目 | PJ |CX00000000${DATE}| 2650 | 100 | 1
Entitätsdesign des Seriennummernmodells:
[code]package com.evada.de.serialnum.model; import com.evada.de.common.model.BaseModel; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; /** * 功能描述:序列号表模型 * * @author :Ay 2015/11/23 */ @Entity @Table(name="sys_serial_number") public class SystemSerialNumber extends BaseModel { /** * 模块名称 */ @Column(name = "module_name", columnDefinition = "VARCHAR") private String moduleName; /** * 模块编码 */ @Column(name = "module_code", columnDefinition = "VARCHAR") private String moduleCode; /** * 流水号配置模板 */ @Column(name = "config_templet", columnDefinition = "VARCHAR") private String configTemplet; /** * 序列号最大值 */ @Column(name = "max_serial", columnDefinition = "VARCHAR") private String maxSerial; /** * 是否自动增长标示 */ @Column(name = "is_auto_increment", columnDefinition = "VARCHAR") private String isAutoIncrement; public String getIsAutoIncrement() { return isAutoIncrement; } public void setIsAutoIncrement(String isAutoIncrement) { this.isAutoIncrement = isAutoIncrement; } /** * 预生成流水号数量 */ @Column(name = "pre_max_num", columnDefinition = "VARCHAR") private String preMaxNum; public String getPreMaxNum() { return preMaxNum; } public void setPreMaxNum(String preMaxNum) { this.preMaxNum = preMaxNum; } public String getModuleName() { return moduleName; } public void setModuleName(String moduleName) { this.moduleName = moduleName; } public String getModuleCode() { return moduleCode; } public void setModuleCode(String moduleCode) { this.moduleCode = moduleCode; } public String getConfigTemplet() { return configTemplet; } public void setConfigTemplet(String configTemplet) { this.configTemplet = configTemplet; } public String getMaxSerial() { return maxSerial; } public void setMaxSerial(String maxSerial) { this.maxSerial = maxSerial; } public SystemSerialNumber(String id){ this.id = id; } public SystemSerialNumber(String id,String moduleCode){ this.id = id; this.moduleCode = moduleCode; } public SystemSerialNumber(){} }Service-Implementierung:
[code]package com.evada.de.serialnum.service; import com.evada.de.serialnum.dto.SystemSerialNumberDTO; /** * 序列号service接口 * Created by huangwy on 2015/11/24. */ public interface ISerialNumService { public SystemSerialNumberDTO find(SystemSerialNumberDTO systemSerialNumberDTO); public String generateSerialNumberByModelCode(String moduleCode); /** * 设置最小值 * @param value 最小值,要求:大于等于零 * @return 流水号生成器实例 */ ISerialNumService setMin(int value); /** * 设置最大值 * @param value 最大值,要求:小于等于Long.MAX_VALUE ( 9223372036854775807 ) * @return 流水号生成器实例 */ ISerialNumService setMax(long value); /** * 设置预生成流水号数量 * @param count 预生成数量 * @return 流水号生成器实例 */ ISerialNumService setPrepare(int count); }Das Obige ist der Inhalt des Java-Seriennummerngenerators. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn).
[code]package com.evada.de.serialnum.service.impl; import com.evada.de.common.constants.SerialNumConstants; import com.evada.de.serialnum.dto.SystemSerialNumberDTO; import com.evada.de.serialnum.model.SystemSerialNumber; import com.evada.de.serialnum.repository.SerialNumberRepository; import com.evada.de.serialnum.repository.mybatis.SerialNumberDAO; import com.evada.de.serialnum.service.ISerialNumService; import com.evada.inno.common.util.BeanUtils; import com.evada.inno.common.util.DateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CachePut; import org.springframework.stereotype.Service; import java.text.DecimalFormat; import java.util.*; import java.util.concurrent.locks.ReentrantLock; /** * Created by Ay on 2015/11/24. */ @Service("serialNumberService") public class SerialNumberServiceImpl implements ISerialNumService { private static final Logger LOGGER = LoggerFactory.getLogger(SerialNumberServiceImpl.class); @Autowired private SerialNumberDAO serialNumberDAO; @Autowired private SerialNumberRepository serialNumberRepository; /** 格式 */ private String pattern = ""; /** 生成器锁 */ private final ReentrantLock lock = new ReentrantLock(); /** 流水号格式化器 */ private DecimalFormat format = null; /** 预生成锁 */ private final ReentrantLock prepareLock = new ReentrantLock(); /** 最小值 */ private int min = 0; /** 最大值 */ private long max = 0; /** 已生成流水号(种子) */ private long seed = min; /** 预生成数量 */ private int prepare = 0; /** 数据库存储的当前最大序列号 **/ long maxSerialInt = 0; /** 当前序列号是否为个位数自增的模式 **/ private String isAutoIncrement = "0"; SystemSerialNumberDTO systemSerialNumberDTO = new SystemSerialNumberDTO(); /** 预生成流水号 */ HashMap<String,List<String>> prepareSerialNumberMap = new HashMap<>(); /** * 查询单条序列号配置信息 * @param systemSerialNumberDTO * @return */ @Override public SystemSerialNumberDTO find(SystemSerialNumberDTO systemSerialNumberDTO) { return serialNumberDAO.find(systemSerialNumberDTO); } /** * 根据模块code生成预数量的序列号存放到Map中 * @param moduleCode 模块code * @return */ @CachePut(value = "serialNumber",key="#moduleCode") public List<String> generatePrepareSerialNumbers(String moduleCode){ //临时List变量 List<String> resultList = new ArrayList<String>(prepare); lock.lock(); try{ for(int i=0;i<prepare;i++){ maxSerialInt = maxSerialInt + 1; if(maxSerialInt > min && (maxSerialInt + "").length() < max ){ seed = maxSerialInt ; }else{ //如果动态数字长度大于模板中的长度 例:模板CF000 maxSerialInt 1000 seed = maxSerialInt = 0; //更新数据,重置maxSerialInt为0 systemSerialNumberDTO.setMaxSerial("0"); SystemSerialNumber systemSerialNumber = new SystemSerialNumber(); BeanUtils.copyProperties(systemSerialNumber,systemSerialNumberDTO); serialNumberRepository.save(systemSerialNumber); } //动态数字生成 String formatSerialNum = format.format(seed); //动态日期的生成 if(pattern.contains(SerialNumConstants.DATE_SYMBOL)){ String currentDate = DateUtils.format(new Date(),"yyyyMMdd"); formatSerialNum = formatSerialNum.replace(SerialNumConstants.DATE_SYMBOL,currentDate); } resultList.add(formatSerialNum); } //更新数据 systemSerialNumberDTO.setMaxSerial(maxSerialInt + ""); SystemSerialNumber systemSerialNumber = new SystemSerialNumber(); BeanUtils.copyProperties(systemSerialNumber,systemSerialNumberDTO); serialNumberRepository.save(systemSerialNumber); }finally{ lock.unlock(); } return resultList; } /** * 根据模块code生成序列号 * @param moduleCode 模块code * @return 序列号 */ public String generateSerialNumberByModelCode(String moduleCode){ //预序列号加锁 prepareLock.lock(); try{ //判断内存中是否还有序列号 if(null != prepareSerialNumberMap.get(moduleCode) && prepareSerialNumberMap.get(moduleCode).size() > 0){ //若有,返回第一个,并删除 return prepareSerialNumberMap.get(moduleCode).remove(0); } }finally { //预序列号解锁 prepareLock.unlock(); } systemSerialNumberDTO = new SystemSerialNumberDTO(); systemSerialNumberDTO.setModuleCode(moduleCode); systemSerialNumberDTO = serialNumberDAO.find(systemSerialNumberDTO); prepare = Integer.parseInt(systemSerialNumberDTO.getPreMaxNum().trim());//预生成流水号数量 pattern = systemSerialNumberDTO.getConfigTemplet().trim();//配置模板 String maxSerial = systemSerialNumberDTO.getMaxSerial().trim(); //存储当前最大值 isAutoIncrement = systemSerialNumberDTO.getIsAutoIncrement().trim(); maxSerialInt = Long.parseLong(maxSerial.trim());//数据库存储的最大序列号 max = this.counter(pattern,'0') + 1;//根据模板判断当前序列号数字的最大值 if(isAutoIncrement.equals("1")){ pattern = pattern.replace("0","#"); } format = new DecimalFormat(pattern); //生成预序列号,存到缓存中 List<String> resultList = generatePrepareSerialNumbers(moduleCode); prepareLock.lock(); try { prepareSerialNumberMap.put(moduleCode, resultList); return prepareSerialNumberMap.get(moduleCode).remove(0); } finally { prepareLock.unlock(); } } /** * 设置最小值 * * @param value 最小值,要求:大于等于零 * @return 流水号生成器实例 */ public ISerialNumService setMin(int value) { lock.lock(); try { this.min = value; }finally { lock.unlock(); } return this; } /** * 最大值 * * @param value 最大值,要求:小于等于Long.MAX_VALUE ( 9223372036854775807 ) * @return 流水号生成器实例 */ public ISerialNumService setMax(long value) { lock.lock(); try { this.max = value; }finally { lock.unlock(); } return this; } /** * 设置预生成流水号数量 * @param count 预生成数量 * @return 流水号生成器实例 */ public ISerialNumService setPrepare(int count) { lock.lock(); try { this.prepare = count; }finally { lock.unlock(); } return this; } /** * 统计某一个字符出现的次数 * @param str 查找的字符 * @param c * @return */ private int counter(String str,char c){ int count=0; for(int i = 0;i < str.length();i++){ if(str.charAt(i)==c){ count++; } } return count; } }