mirror of
https://gitee.com/lab1024/smart-admin.git
synced 2025-10-08 21:26:40 +08:00
id替换以及结构调整
This commit is contained in:
parent
2ace49012b
commit
3dc77a653e
@ -6,6 +6,11 @@ package net.lab1024.smartadmin.service.constant;
|
||||
*/
|
||||
public class CacheModuleConst {
|
||||
|
||||
public static class IdGenerator {
|
||||
public static final String ID_GENERATOR_CACHE = "id_generator_cache";
|
||||
}
|
||||
|
||||
|
||||
public static class Employee {
|
||||
/**
|
||||
* 某个部门下的员工缓存
|
||||
|
@ -8,6 +8,8 @@ import net.lab1024.smartadmin.service.common.domain.ResponseDTO;
|
||||
import net.lab1024.smartadmin.service.common.swagger.SwaggerTagConst;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorEnum;
|
||||
import net.lab1024.smartadmin.service.common.util.SmartBaseEnumUtil;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorStrategyTypeEnum;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.service.IdGeneratorService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
@ -33,7 +35,7 @@ public class IdGeneratorController extends SupportBaseController {
|
||||
if (null == idGeneratorEnum) {
|
||||
return ResponseDTO.error(UserErrorCode.PARAM_ERROR, "IdGenerator,不存在" + generatorId);
|
||||
}
|
||||
return ResponseDTO.ok(idGeneratorService.generate(idGeneratorEnum));
|
||||
return ResponseDTO.ok(idGeneratorService.generate(idGeneratorEnum, IdGeneratorStrategyTypeEnum.INTERN));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,136 +0,0 @@
|
||||
package net.lab1024.smartadmin.service.module.support.idgenerator;
|
||||
|
||||
import com.google.common.collect.Interner;
|
||||
import com.google.common.collect.Interners;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.lab1024.smartadmin.service.common.util.SmartRandomUtil;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorEnum;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorRuleTypeEnum;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorEntity;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorRecordEntity;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 全局id生成器
|
||||
*
|
||||
* @author zhuo
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class IdGeneratorService {
|
||||
|
||||
private static final Interner<Integer> POOL = Interners.newWeakInterner();
|
||||
|
||||
@Autowired
|
||||
private IdGeneratorDao idGeneratorDao;
|
||||
|
||||
@Autowired
|
||||
private IdGeneratorRecordDao idGeneratorRecordDao;
|
||||
|
||||
private Map<Integer, IdGeneratorEntity> idGeneratorMap;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
List<IdGeneratorEntity> idGeneratorEntityList = idGeneratorDao.selectList(null);
|
||||
idGeneratorMap = idGeneratorEntityList.stream().collect(Collectors.toMap(IdGeneratorEntity::getId, Function.identity()));
|
||||
log.info("##################### init IdGenerator #####################");
|
||||
}
|
||||
|
||||
/**
|
||||
* id生成
|
||||
*
|
||||
* @param idGeneratorEnum 类型
|
||||
* @return
|
||||
*/
|
||||
public String generate(IdGeneratorEnum idGeneratorEnum) {
|
||||
int generatorId = idGeneratorEnum.getValue();
|
||||
IdGeneratorEntity idGeneratorEntity = this.idGeneratorMap.get(generatorId);
|
||||
Assert.notNull(idGeneratorEntity, "IdGenerator不存在 " + idGeneratorEntity.getRuleType());
|
||||
|
||||
// 校验生成规则
|
||||
IdGeneratorRuleTypeEnum ruleTypeEnum = this.getIdGeneratorRuleTypeEnum(idGeneratorEntity.getRuleType());
|
||||
Assert.notNull(ruleTypeEnum, "IdGenerator rule type 不存在 " + idGeneratorEntity.getRuleType());
|
||||
|
||||
// 默认起始值
|
||||
Long startNumber = idGeneratorEntity.getInitNumber();
|
||||
|
||||
// 判断是否有循环规则
|
||||
String timeFormat = null;
|
||||
DateTimeFormatter timeFormatter = null;
|
||||
if (IdGeneratorRuleTypeEnum.YEAR_CYCLE == ruleTypeEnum || IdGeneratorRuleTypeEnum.MONTH_CYCLE == ruleTypeEnum || IdGeneratorRuleTypeEnum.DAY_CYCLE == ruleTypeEnum) {
|
||||
timeFormatter = DateTimeFormatter.ofPattern(ruleTypeEnum.getValue());
|
||||
timeFormat = LocalDateTime.now().format(timeFormatter);
|
||||
}
|
||||
|
||||
synchronized (POOL.intern(generatorId)) {
|
||||
// 获取最后一次生成记录
|
||||
boolean isFirst = false;
|
||||
IdGeneratorRecordEntity recordEntity = idGeneratorRecordDao.selectHistoryLastNumber(generatorId, timeFormat);
|
||||
if (recordEntity == null) {
|
||||
recordEntity = new IdGeneratorRecordEntity();
|
||||
recordEntity.setGeneratorId(generatorId);
|
||||
recordEntity.setTime(timeFormat);
|
||||
recordEntity.setLastNumber(startNumber);
|
||||
recordEntity.setCount(1L);
|
||||
idGeneratorRecordDao.insert(recordEntity);
|
||||
|
||||
isFirst = true;
|
||||
}
|
||||
|
||||
// 没有循环 或 在同个循环周期内,起始值 = 上次id
|
||||
if (IdGeneratorRuleTypeEnum.NO_CYCLE == ruleTypeEnum || Objects.equals(recordEntity.getUpdateTime().format(timeFormatter), timeFormat)) {
|
||||
startNumber = recordEntity.getLastNumber();
|
||||
}
|
||||
|
||||
// 在范围内随机生成此次增加的数值 更新id生成记录
|
||||
if (!isFirst) {
|
||||
startNumber += SmartRandomUtil.nextInt(1, idGeneratorEntity.getStepRandomRange());
|
||||
IdGeneratorRecordEntity updateRecordEntity = new IdGeneratorRecordEntity();
|
||||
updateRecordEntity.setId(recordEntity.getId());
|
||||
updateRecordEntity.setLastNumber(startNumber);
|
||||
updateRecordEntity.setCount(recordEntity.getCount() + 1);
|
||||
idGeneratorRecordDao.updateById(updateRecordEntity);
|
||||
}
|
||||
|
||||
// 默认 最低长度 1
|
||||
int minLength = NumberUtils.max(idGeneratorEntity.getMinLength(), 1);
|
||||
// id长度补位
|
||||
String finalId = String.format("%0" + minLength + "d", startNumber);
|
||||
if (null != timeFormat) {
|
||||
finalId = timeFormat + finalId;
|
||||
}
|
||||
// 前缀
|
||||
if (StringUtils.isNotBlank(idGeneratorEntity.getPrefix())) {
|
||||
finalId = idGeneratorEntity.getPrefix() + finalId;
|
||||
}
|
||||
return finalId;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询生成规则
|
||||
*
|
||||
* @param ruleType
|
||||
* @return 没有则返回null
|
||||
*/
|
||||
private IdGeneratorRuleTypeEnum getIdGeneratorRuleTypeEnum(String ruleType) {
|
||||
return Arrays.stream(IdGeneratorRuleTypeEnum.values())
|
||||
.filter(e -> StringUtils.equalsIgnoreCase(e.name(), ruleType))
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package net.lab1024.smartadmin.service.module.support.idgenerator.constant;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.lab1024.smartadmin.service.common.enumeration.BaseEnum;
|
||||
|
||||
/**
|
||||
* [ ]
|
||||
*
|
||||
* @author yandanyang
|
||||
* @date 2021/11/9 18:49
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum IdGeneratorStrategyTypeEnum implements BaseEnum {
|
||||
|
||||
INTERN(1, "string intern"),
|
||||
|
||||
REDIS(2, "redis"),
|
||||
|
||||
MYSQL_LOCK(2, "mysql排他锁"),
|
||||
;
|
||||
|
||||
private final Integer value;
|
||||
|
||||
private final String desc;
|
||||
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
package net.lab1024.smartadmin.service.module.support.idgenerator;
|
||||
package net.lab1024.smartadmin.service.module.support.idgenerator.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
@ -14,4 +15,10 @@ import org.springframework.stereotype.Component;
|
||||
@Component
|
||||
public interface IdGeneratorDao extends BaseMapper<IdGeneratorEntity> {
|
||||
|
||||
/**
|
||||
* 排他锁查询
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
IdGeneratorEntity selectForUpdate(@Param("id")Integer id);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package net.lab1024.smartadmin.service.module.support.idgenerator;
|
||||
package net.lab1024.smartadmin.service.module.support.idgenerator.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorRecordEntity;
|
@ -0,0 +1,37 @@
|
||||
package net.lab1024.smartadmin.service.module.support.idgenerator.service;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.lab1024.smartadmin.service.constant.CacheModuleConst;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorEnum;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.dao.IdGeneratorDao;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorEntity;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
*
|
||||
* [ ]
|
||||
*
|
||||
* @author yandanyang
|
||||
* @date
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class IdGeneratorCacheService {
|
||||
|
||||
@Autowired
|
||||
private IdGeneratorDao idGeneratorDao;
|
||||
|
||||
@Cacheable(CacheModuleConst.IdGenerator.ID_GENERATOR_CACHE)
|
||||
public IdGeneratorEntity getIdGeneratorEntity(Integer generatorId){
|
||||
return idGeneratorDao.selectById(generatorId);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package net.lab1024.smartadmin.service.module.support.idgenerator.service;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorEnum;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorStrategyTypeEnum;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.strategy.IdGeneratorStrategyFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 全局id生成器
|
||||
*
|
||||
* @author zhuo
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class IdGeneratorService {
|
||||
|
||||
@Autowired
|
||||
private IdGeneratorStrategyFactory idGeneratorStrategyFactory;
|
||||
|
||||
/**
|
||||
* 自定义生成策略生成
|
||||
*
|
||||
* @param idGeneratorEnum
|
||||
* @param strategyTypeEnum
|
||||
* @return
|
||||
*/
|
||||
public String generate(IdGeneratorEnum idGeneratorEnum, IdGeneratorStrategyTypeEnum strategyTypeEnum) {
|
||||
return idGeneratorStrategyFactory.getIdGeneratorStrategy(strategyTypeEnum).generate(idGeneratorEnum);
|
||||
}
|
||||
|
||||
/**
|
||||
* 简单的生成 依据 intern
|
||||
*
|
||||
* @param idGeneratorEnum
|
||||
* @return
|
||||
*/
|
||||
public String simpleGenerate(IdGeneratorEnum idGeneratorEnum) {
|
||||
return idGeneratorStrategyFactory.getIdGeneratorStrategy(IdGeneratorStrategyTypeEnum.INTERN).generate(idGeneratorEnum);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package net.lab1024.smartadmin.service.module.support.idgenerator.strategy;
|
||||
|
||||
import net.lab1024.smartadmin.service.common.util.SmartRandomUtil;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorEnum;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorRuleTypeEnum;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorStrategyTypeEnum;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorRecordEntity;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* [ ]
|
||||
*
|
||||
* @author yandanyang
|
||||
* @date 2021/11/9 18:48
|
||||
*/
|
||||
public interface IIdGeneratorStrategy {
|
||||
|
||||
/**
|
||||
* 策略类型
|
||||
* @return
|
||||
*/
|
||||
IdGeneratorStrategyTypeEnum getStrategyType();
|
||||
|
||||
/**
|
||||
* 生成
|
||||
* @param idGeneratorEnum
|
||||
* @return
|
||||
*/
|
||||
String generate(IdGeneratorEnum idGeneratorEnum);
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package net.lab1024.smartadmin.service.module.support.idgenerator.strategy;
|
||||
|
||||
import com.google.common.collect.Interner;
|
||||
import com.google.common.collect.Interners;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorEnum;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorStrategyTypeEnum;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorEntity;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.service.IdGeneratorCacheService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* [ ]
|
||||
*
|
||||
* @author yandanyang
|
||||
* @date 2021/11/9 18:48
|
||||
*/
|
||||
@Service
|
||||
public class IdGeneratorInternStrategy extends IdGeneratorStrategyBaseService {
|
||||
|
||||
private static final Interner<Integer> POOL = Interners.newWeakInterner();
|
||||
@Autowired
|
||||
private IdGeneratorCacheService idGeneratorCacheService;
|
||||
|
||||
/**
|
||||
* 策略类型
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public IdGeneratorStrategyTypeEnum getStrategyType() {
|
||||
return IdGeneratorStrategyTypeEnum.INTERN;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成
|
||||
*
|
||||
* @param idGeneratorEnum
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String generate(IdGeneratorEnum idGeneratorEnum) {
|
||||
IdGeneratorEntity idGeneratorEntity = idGeneratorCacheService.getIdGeneratorEntity(idGeneratorEnum.getValue());
|
||||
synchronized (POOL.intern(idGeneratorEntity.getId())) {
|
||||
return generate(idGeneratorEntity);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package net.lab1024.smartadmin.service.module.support.idgenerator.strategy;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.lab1024.smartadmin.service.common.exception.BusinessException;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorEnum;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorStrategyTypeEnum;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.dao.IdGeneratorDao;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorEntity;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* [ ]
|
||||
*
|
||||
* @author yandanyang
|
||||
* @date 2021/11/9 18:48
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class IdGeneratorMySqlStrategy extends IdGeneratorStrategyBaseService {
|
||||
|
||||
|
||||
@Autowired
|
||||
private IdGeneratorDao idGeneratorDao;
|
||||
|
||||
/**
|
||||
* 策略类型
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public IdGeneratorStrategyTypeEnum getStrategyType() {
|
||||
return IdGeneratorStrategyTypeEnum.MYSQL_LOCK;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成
|
||||
*
|
||||
* @param idGeneratorEnum
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Throwable.class)
|
||||
public String generate(IdGeneratorEnum idGeneratorEnum) {
|
||||
IdGeneratorEntity idGeneratorEntity = idGeneratorDao.selectForUpdate(idGeneratorEnum.getValue());
|
||||
if (idGeneratorEntity == null) {
|
||||
throw new BusinessException("IdGenerator, id 数据库不存在");
|
||||
}
|
||||
return generate(idGeneratorEntity);
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
package net.lab1024.smartadmin.service.module.support.idgenerator.strategy;
|
||||
|
||||
import com.google.common.collect.Interner;
|
||||
import com.google.common.collect.Interners;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.lab1024.smartadmin.service.common.domain.ResponseDTO;
|
||||
import net.lab1024.smartadmin.service.common.exception.BusinessException;
|
||||
import net.lab1024.smartadmin.service.common.util.SmartRandomUtil;
|
||||
import net.lab1024.smartadmin.service.constant.RedisKeyConst;
|
||||
import net.lab1024.smartadmin.service.constant.SwaggerTagConst;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorEnum;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorRuleTypeEnum;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorStrategyTypeEnum;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorEntity;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.service.IdGeneratorCacheService;
|
||||
import net.lab1024.smartadmin.service.module.support.redis.RedisService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.util.Strings;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* [ ]
|
||||
*
|
||||
* @author yandanyang
|
||||
* @date 2021/11/9 18:48
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class IdGeneratorRedisStrategy extends IdGeneratorStrategyBaseService {
|
||||
|
||||
private static final int MAX_GET_LOCK_COUNT = 5;
|
||||
|
||||
private static final long SLEEP_MILLISECONDS = 500L;
|
||||
|
||||
private static volatile long lastSleepMilliSeconds = SLEEP_MILLISECONDS;
|
||||
|
||||
@Autowired
|
||||
private IdGeneratorCacheService idGeneratorCacheService;
|
||||
@Autowired
|
||||
private RedisService redisService;
|
||||
|
||||
/**
|
||||
* 策略类型
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public IdGeneratorStrategyTypeEnum getStrategyType() {
|
||||
return IdGeneratorStrategyTypeEnum.REDIS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成
|
||||
*
|
||||
* @param idGeneratorEnum
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String generate(IdGeneratorEnum idGeneratorEnum) {
|
||||
IdGeneratorEntity idGeneratorEntity = idGeneratorCacheService.getIdGeneratorEntity(idGeneratorEnum.getValue());
|
||||
String lockKey = RedisKeyConst.Support.ID_GENERATOR + idGeneratorEnum.getValue();
|
||||
try {
|
||||
boolean lock = false;
|
||||
for (int i = 0; i < MAX_GET_LOCK_COUNT; i++) {
|
||||
try {
|
||||
lock = redisService.getLock(lockKey, 60 * 1000L);
|
||||
if (lock) {
|
||||
break;
|
||||
}
|
||||
Thread.sleep(Math.max(SLEEP_MILLISECONDS, lastSleepMilliSeconds));
|
||||
} catch (Throwable e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
if (!lock) {
|
||||
throw new BusinessException("系统繁忙");
|
||||
}
|
||||
long beginTime = System.currentTimeMillis();
|
||||
|
||||
String id = generate(idGeneratorEntity);
|
||||
lastSleepMilliSeconds = System.currentTimeMillis() - beginTime + 100;
|
||||
return id;
|
||||
} catch (Throwable e) {
|
||||
log.error(e.getMessage(), e);
|
||||
throw e;
|
||||
} finally {
|
||||
redisService.unLock(lockKey);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package net.lab1024.smartadmin.service.module.support.idgenerator.strategy;
|
||||
|
||||
import net.lab1024.smartadmin.service.common.util.SmartBaseEnumUtil;
|
||||
import net.lab1024.smartadmin.service.common.util.SmartRandomUtil;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorRuleTypeEnum;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.dao.IdGeneratorRecordDao;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorEntity;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorRecordEntity;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* [ ]
|
||||
*
|
||||
* @author yandanyang
|
||||
* @date 2021/11/9 19:12
|
||||
*/
|
||||
public abstract class IdGeneratorStrategyBaseService implements IIdGeneratorStrategy{
|
||||
|
||||
@Autowired
|
||||
private IdGeneratorRecordDao idGeneratorRecordDao;
|
||||
|
||||
|
||||
public String generate(IdGeneratorEntity idGeneratorEntity){
|
||||
// 校验生成规则
|
||||
IdGeneratorRuleTypeEnum ruleTypeEnum = SmartBaseEnumUtil.getEnumByName(idGeneratorEntity.getRuleType(),IdGeneratorRuleTypeEnum.class);
|
||||
// 默认起始值
|
||||
Long startNumber = idGeneratorEntity.getInitNumber();
|
||||
Integer generatorId = idGeneratorEntity.getId();
|
||||
// 判断是否有循环规则
|
||||
String timeFormat = null;
|
||||
DateTimeFormatter timeFormatter = null;
|
||||
if (IdGeneratorRuleTypeEnum.YEAR_CYCLE == ruleTypeEnum || IdGeneratorRuleTypeEnum.MONTH_CYCLE == ruleTypeEnum || IdGeneratorRuleTypeEnum.DAY_CYCLE == ruleTypeEnum) {
|
||||
timeFormatter = DateTimeFormatter.ofPattern(ruleTypeEnum.getValue());
|
||||
timeFormat = LocalDateTime.now().format(timeFormatter);
|
||||
}
|
||||
// 获取最后一次生成记录
|
||||
boolean isFirst = false;
|
||||
IdGeneratorRecordEntity recordEntity = idGeneratorRecordDao.selectHistoryLastNumber(generatorId, timeFormat);
|
||||
if (recordEntity == null) {
|
||||
recordEntity = new IdGeneratorRecordEntity();
|
||||
recordEntity.setGeneratorId(generatorId);
|
||||
recordEntity.setTime(timeFormat);
|
||||
recordEntity.setLastNumber(startNumber);
|
||||
recordEntity.setCount(1L);
|
||||
idGeneratorRecordDao.insert(recordEntity);
|
||||
|
||||
isFirst = true;
|
||||
}
|
||||
|
||||
// 没有循环 或 在同个循环周期内,起始值 = 上次id
|
||||
if (IdGeneratorRuleTypeEnum.NO_CYCLE == ruleTypeEnum || Objects.equals(recordEntity.getUpdateTime().format(timeFormatter), timeFormat)) {
|
||||
startNumber = recordEntity.getLastNumber();
|
||||
}
|
||||
// 在范围内随机生成此次增加的数值 更新id生成记录
|
||||
if (!isFirst) {
|
||||
startNumber += SmartRandomUtil.nextInt(1, idGeneratorEntity.getStepRandomRange());
|
||||
IdGeneratorRecordEntity updateRecordEntity = new IdGeneratorRecordEntity();
|
||||
updateRecordEntity.setId(recordEntity.getId());
|
||||
updateRecordEntity.setLastNumber(startNumber);
|
||||
updateRecordEntity.setCount(recordEntity.getCount() + 1);
|
||||
idGeneratorRecordDao.updateById(updateRecordEntity);
|
||||
}
|
||||
// 默认 最低长度 1
|
||||
int minLength = NumberUtils.max(idGeneratorEntity.getMinLength(), 1);
|
||||
// id长度补位
|
||||
String finalId = String.format("%0" + minLength + "d", startNumber);
|
||||
if (null != timeFormat) {
|
||||
finalId = timeFormat + finalId;
|
||||
}
|
||||
// 前缀
|
||||
if (StringUtils.isNotBlank(idGeneratorEntity.getPrefix())) {
|
||||
finalId = idGeneratorEntity.getPrefix() + finalId;
|
||||
}
|
||||
return finalId;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package net.lab1024.smartadmin.service.module.support.idgenerator.strategy;
|
||||
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorStrategyTypeEnum;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* [ ]
|
||||
*
|
||||
* @author yandanyang
|
||||
* @date 2021/11/9 18:48
|
||||
*/
|
||||
@Service
|
||||
public class IdGeneratorStrategyFactory {
|
||||
|
||||
@Autowired
|
||||
private List<IIdGeneratorStrategy> idGeneratorStrategyList;
|
||||
|
||||
/**
|
||||
* 获取某个策略
|
||||
* @param strategyTypeEnum
|
||||
* @return
|
||||
*/
|
||||
public IIdGeneratorStrategy getIdGeneratorStrategy(IdGeneratorStrategyTypeEnum strategyTypeEnum) {
|
||||
Optional<IIdGeneratorStrategy> idGeneratorStrategyOptional = idGeneratorStrategyList.stream().filter(e -> e.getStrategyType() == strategyTypeEnum).findFirst();
|
||||
if (!idGeneratorStrategyOptional.isPresent()) {
|
||||
return null;
|
||||
}
|
||||
return idGeneratorStrategyOptional.get();
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="net.lab1024.smartadmin.service.module.support.idgenerator.dao.IdGeneratorDao">
|
||||
|
||||
<!-- 查询最后生成记录 -->
|
||||
<select id="selectForUpdate" resultType="net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorEntity">
|
||||
select * from t_id_generator where id = #{id} for update
|
||||
</select>
|
||||
|
||||
</mapper>
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="net.lab1024.smartadmin.service.module.support.idgenerator.IdGeneratorRecordDao">
|
||||
<mapper namespace="net.lab1024.smartadmin.service.module.support.idgenerator.dao.IdGeneratorRecordDao">
|
||||
|
||||
<!-- 查询最后生成记录 -->
|
||||
<select id="selectHistoryLastNumber" resultType="net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorRecordEntity">
|
||||
|
@ -1,8 +1,8 @@
|
||||
package net.lab1024.smartadmin.service.module.support.idgenerator.service;
|
||||
|
||||
import net.lab1024.smartadmin.service.SmartAdminApplicationTest;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.IdGeneratorService;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorEnum;
|
||||
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorStrategyTypeEnum;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
@ -23,7 +23,7 @@ class IdGeneratorServiceTest extends SmartAdminApplicationTest {
|
||||
CountDownLatch countDownLatch = new CountDownLatch(thread);
|
||||
|
||||
Runnable task = () -> {
|
||||
String id = generatorService.generate(IdGeneratorEnum.CONTRACT);
|
||||
String id = generatorService.generate(IdGeneratorEnum.CONTRACT, IdGeneratorStrategyTypeEnum.MYSQL_LOCK);
|
||||
System.out.println(countDownLatch.getCount() + "生成id->" + id);
|
||||
countDownLatch.countDown();
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user