参考:https://www.jianshu.com/p/331b872e9c8f

  1.建立一张存放的表

  

CREATE TABLE `sys_serial_number` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`module_name` varchar(50) DEFAULT NULL COMMENT '模块名称',
`module_code` varchar(50) DEFAULT NULL COMMENT '模块编码(唯一的)',
`config_templet` varchar(50) DEFAULT NULL COMMENT '订单前缀',
`max_serial` varchar(32) DEFAULT NULL COMMENT '存放当前序列号的值',
`pre_max_num` varchar(32) DEFAULT NULL COMMENT '预生成序列号存放到缓存的个数',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='序列自增长表';
package ch.service.sys;

import ch.common.util.CacheUtils;
import ch.dao.sys.SerialNumDao;
import ch.entity.sys.SystemSerialNumberEntity;
import ch.util.DateUtils;
import ch.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock; /**
* Description:
*
* @author cy
* @date 2019年05月07日 13:23
* version 1.0
*/
@Service
public class SerialNumberServiceImpl implements SerialNumService { @Autowired
private SerialNumDao serialNumDao; /** 日期格式 */
private String pattern = "yyyyMMddHHmmss"; /** 生成器锁 */
private final ReentrantLock lock = new ReentrantLock(); /** 流水号格式化器 */
private DecimalFormat format = new DecimalFormat(""); /** 预生成锁 */
private final ReentrantLock prepareLock = new ReentrantLock(); /** 最小值 */
private int min = ; /** 最大值 */
private long max = ; /** 已生成流水号(种子) */
private long seed = min; /** 预生成数量 */
private int prepare = ; /** 数据库存储的当前最大序列号 **/
long maxSerialInt = ; /** 当前序列号是否为个位数自增的模式 **/
private String isAutoIncrement = ""; /** 预生成流水号 */
HashMap<String, List<String>> prepareSerialNumberMap = new HashMap<>(); /**
* 查询单条序列号配置信息
* @param
* @return
*/
@Override
public SystemSerialNumberEntity find(SystemSerialNumberEntity entity) {
return null;
} /**
* 根据模块code生成预数量的序列号存放到Map中
* @param moduleCode 模块code
* @return
*/
@Transactional
public List<String> generatePrepareSerialNumbers(String moduleCode){
//临时List变量
List<String> resultList = new ArrayList<String>(prepare);
lock.lock();
// 查询数据库最大maxSerialInt
SystemSerialNumberEntity oneByCode = serialNumDao.findOneByCode(moduleCode);
if(oneByCode == null){
throw new RuntimeException("不存在模块code");
}
this.maxSerialInt = Long.valueOf(oneByCode.getMaxSerial());
this.prepare = Integer.valueOf(oneByCode.getPreMaxNum());
try {
for (int i = ; i < prepare; i++) {
maxSerialInt += ;
if(maxSerialInt > min && maxSerialInt < max){
seed = maxSerialInt;
}else {
// 如果动态数字长度大于模板中的长度 例:模板CF000 maxSerialInt 1000
seed = maxSerialInt = ;
}
// 动态数字生成拼接
String formatSerialNum = format.format(seed);
// 动态日期的生成拼接
if(StringUtils.isNotBlank(pattern)){
String date = DateUtils.getDate(pattern);
formatSerialNum = date + formatSerialNum;
}
if(StringUtils.isNotBlank(oneByCode.getConfigTemplet())){
formatSerialNum = oneByCode.getConfigTemplet() + formatSerialNum;
}
resultList.add(formatSerialNum);
}
//更新数据
oneByCode.setMaxSerial(maxSerialInt + "");
serialNumDao.update(oneByCode);
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
return resultList;
} /**
* 根据模块code生成序列号
* @param moduleCode 模块code
* @return 序列号
*/
@Override
@Transactional
public String generateSerialNumberByModelCode(String moduleCode) {
//预序列号加锁
prepareLock.lock();
try{
//判断内存中是否还有序列号
if(null != prepareSerialNumberMap.get(moduleCode) && prepareSerialNumberMap.get(moduleCode).size() > ){
//若有,返回第一个,并删除
return prepareSerialNumberMap.get(moduleCode).remove();
}
}catch (Exception e){
e.printStackTrace();
}finally {
//预序列号解锁
prepareLock.unlock();
}
List<String> resultList = generatePrepareSerialNumbers(moduleCode);
prepareLock.lock();
try {
prepareSerialNumberMap.put(moduleCode, resultList);
return prepareSerialNumberMap.get(moduleCode).remove();
} finally {
prepareLock.unlock();
}
} }

  

Java之流水号生成器实现的更多相关文章

  1. C# 流水号生成器开发

    前言 本文将使用一个Nuget公开的组件技术来实现一个流水号生成器,提供了一些简单的API,来方便的实现一个通用的流水号. 在visual studio 中的NuGet管理器中可以下载安装,也可以直接 ...

  2. Java设计模式:生成器模式

    问题的提出: 有些类很容易创建对象,直接调用其构造方法,例如Student student = new Student("1001","zhang",21); ...

  3. 结对编程1----基于java的四则运算生成器

    小组成员:王震(201421123054).王杰(201421123055) Coding地址:https://git.coding.net/a506504661/sssss.git 一.题目描述 我 ...

  4. Java设计模式-Builder生成器模式

    概念: 生成器模式也称之为建造者模式.生成器模式的意图在于将一个复杂的构建与其表示相分离,构建与产品分离. UML: Ibuild接口清晰地反映了创建产品Product的流程. 生成器模式涉及4个关键 ...

  5. 自定义java代码快捷生成器使用与问题解决

    对于很多的工作了有几年的开发人员来说,初期都是逐个单词语法的自己编写的.而一旦技术水平提高了到了一定的层次之后,在同时工作量的加大,要求我们必须加快提高工作效率.因此就可以利用必要的快捷开发手段和工具 ...

  6. java中生成流水号的一个例子(使用关系型数据库)

    在实际的开发中,可能会有根据一定的规则生成流水号的需求(比如根据根据公司编码和日期生成4位流水号)我们可以把公司和日期联合起来作为一个业务编码,把这个业务编码和序列的值存储到数据库中,每次需要生成流水 ...

  7. 【java】单实例下的 流水号【21位】

    单实例环境,不是分布式 需要流水号 /** * 流水号生成器 * * 年+天号+毫秒+随机数 * 2019+134+480+11位随机数 * 4+3+3+11 = 21位 * * * @author ...

  8. Spring Boot集成全局唯一ID生成器

    流水号生成器(全局唯一 ID生成器)是服务化系统的基础设施,其在保障系统的正确运行和高可用方面发挥着重要作用.而关于流水号生成算法首屈一指的当属 Snowflake雪花算法,然而 Snowflake本 ...

  9. Java二进制和位运算,这一万字准能喂饱你

    基础不牢,地动山摇.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习.关注公众号[BAT的乌托 ...

随机推荐

  1. python+selenium高亮显示正在操作的页面元素

    原文地址:https://blog.csdn.net/wxstar8/article/details/80801405 from selenium import webdriver import un ...

  2. UI控件初始化问题:initWithFrame和initWithCoder、aweakFromNib的执行

    在iOS学习和程序开发过程中,我们经常会遇到一些自定义UI控件或控制器在初始化时出现问题,尤其在大家刚开始接触时,几种初始化方法的作用以及调用的时机往往容易混淆,这也跟我们对iOS程序设计中,类的创建 ...

  3. Unity3D模型制作规范[转]

    本文提到的所有数字模型制作,全部是用3D MAX建立的模型,即使是不同的驱动引擎,对模型的要求基本是相同的.当一个VR模型制作完成时,它所包含的基本内容包括:场景尺寸.单位,模型归类塌陷.命名.节点编 ...

  4. XTU1267:Highway(LCA+树的直径)

    传送门 题意 有n个小镇,Bobo想要建造n-1条边,并且如果在u到v建边,那么花费是u到v的最短路长度(原图),问你最大的花费. 分析 比赛的时候没做出来,QAQ 我们首先要找到树的直径起点和终点, ...

  5. hdu2476【区间DP,未完待续】

    好难搞得东西.... 题意都懒得写了,看题解的巨巨莫怪啊,未完待续未完待续,回去睡觉.

  6. bzoj 3745: [Coci2015]Norma【分治】

    参考:https://blog.csdn.net/lych_cys/article/details/51203960 真的不擅长这种-- 分治,对于一个(l,r),先递归求出(l,mid),(mid+ ...

  7. bzoj 1176 [Balkan2007]Mokia 【CDQ分治】

    W过大,很难在线维护,考虑离线算法 给每个操作加一个时间属性n,显然,对于n=i的询问,对它有影响的修改只在n<i中,所以可以CDQ(因为是按时间序读进来的,所以不用排序了 对于统计矩形和,可以 ...

  8. mysql事务隔离级别实验

    一.实验数据: 建表语句: CREATE TABLE `isolation` ( `id` int(11) NOT NULL, `name` varchar(255) CHARACTER SET ut ...

  9. Python 爬虫面试题 170 道:2019 版

    引言 最近在刷面试题,所以需要看大量的 Python 相关的面试题,从大量的题目中总结了很多的知识,同时也对一些题目进行拓展了,但是在看了网上的大部分面试题不是很满意,一个是有些部分还是 Python ...

  10. 在 React项目中使用 bootstrap

    在使用create-react-app 创建的项目中使用 bootstrap; 安装react-bootstrap; npm install react-bootstrap --savenpm ins ...