Java生成独一无二的工单号实例

 更新时间:2024年09月04日 10:04:29   作者:码农研究僧  
这篇文章主要介绍了Java生成独一无二的工单号实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

Java生成独一无二的工单号

此文主要以Demo为例,对此直奔主题

以下Demo有参考价值

Demo

接口文件

/**
 * 使用redis生成分布式ID
 */
public interface IdGeneratorService {

	/**
	 * @param biz 业务名称
	 */
	long generatorId(String biz);

	/**
	 *
	 * @return
	 */
	long generatorId();

	/**
	 * 返回工单号 customizerStr-日期-序号
	 * @param customizerStr 自定义参数
	 */
	String  generatorOrderNo(String customizerStr);
}

其生成的工单函数

如下:

import com.google.common.base.Strings;

import org.springblade.equipment.service.IdGeneratorService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class RedisIdGeneratorService implements IdGeneratorService {

	private static final String keyPrefix = "smart";

	/**
	 * JedisClient对象
	 */
	@Autowired
	private RedisTemplate<String, Object> redisTemplate;


	/**
	 * @Description
	 * @author butterfly
	 */
	private String getIDPrefix() {
		Date date = new Date();
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int year = c.get(Calendar.YEAR);
		int day = c.get(Calendar.DAY_OF_YEAR); // 今天是第多少天
		int hour = c.get(Calendar.HOUR_OF_DAY);
		int minute = c.get(Calendar.MINUTE);
		int second = c.get(Calendar.SECOND);
		String dayFmt = String.format("%1$03d", day); // 0补位操作 必须满足三位
		String hourFmt = String.format("%1$02d", hour);  // 0补位操作 必须满足2位
		String minuteFmt = String.format("%1$02d", minute);  // 0补位操作 必须满足2位
		String secondFmt = String.format("%1$02d", second);  // 0补位操作 必须满足2位
		StringBuffer prefix = new StringBuffer();
		prefix.append((year - 2000)).append(dayFmt).append(hourFmt).append(minuteFmt).append(secondFmt);
		return prefix.toString();
	}

	/**
	 * 自定义工单前缀
	 */
	private String getOrderNoPrefix(String customizerStr){
		StringBuffer prefix = new StringBuffer();
		LocalDate now = LocalDate.now();
		prefix.append(customizerStr).append("-").append(now.getYear()).append(now.getMonthValue()).append(now.getDayOfMonth());
		return prefix.toString();
	}

	/**
	 * @author butterfly
	 */
	private long incrDistrId(String biz) {
		String prefix = getIDPrefix();
		String orderId = null;
		String key = "#{biz}:id:".replace("#{biz}", biz).concat(prefix); // 00001
		try {
			ValueOperations<String, Object> valueOper = redisTemplate.opsForValue();
			Long index = valueOper.increment(key, 1);
			orderId = prefix.concat(String.format("%1$05d", index)); // 补位操作 保证满足5位
		} catch (Exception ex) {
			log.error("分布式订单号生成失败异常。。。。。", ex);
		} finally {
			redisTemplate.expire(key, 600, TimeUnit.SECONDS);//保留10分钟内的key
		}
		if (Strings.isNullOrEmpty(orderId)) return 0;
		return Long.parseLong(orderId);
	}

	/**
	 * @Description 生成分布式ID
	 * @author butterfly
	 */
	@Override
	public long generatorId(String biz) {
		// 转成数字类型,可排序
		return incrDistrId(biz);
	}

	@Override
	public long generatorId() {
		return incrDistrId(keyPrefix);
	}

	/**
	 * 获得前缀
	 * 去redis查看是否有对应的值
	 * 有的话取回来新增 001-》002
	 * 没有的直接插入,值为001
	 * 设置过期时间24小时
	 * @param customizerStr 自定义参数
	 * @return
	 */
	@Override
	public String generatorOrderNo(String customizerStr) {
		String orderNoPrefix = this.getOrderNoPrefix(customizerStr);
		String key = orderNoPrefix;
		String value ="";
		try{
			ValueOperations<String, Object> valueOper = redisTemplate.opsForValue();
			Object o = valueOper.get(key);
			//没有的直接插入,值为001
			if(o==null){
				valueOper.set(key,1);
				value="001";
			}else{
				//有的话取回来新增 001-》002
				Integer oldValue = Integer.valueOf(o.toString());
				int newValue = oldValue + 1;
				valueOper.set(key,newValue);
				//其中0表示补零而不是补空格,6表示至少6位
				value=String.format("%03d",newValue);
			}
		}catch (Exception e){
			log.error("工单no生成失败,reason:"+e);
		}finally {
			redisTemplate.expire(key,24,TimeUnit.HOURS);
		}
		return key+"-"+value;
	}


}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java Object类和包装类深入解读

    Java Object类和包装类深入解读

    Object类是一个特殊的类,是所有类的父类,如果一个类没有用extends明确指出继承于某个类,那么它默认继承Object类,所谓包装类,就是能够直接将简单类型的变量表示为一个类,在执行变量类型的相互转换时,我们会大量使用这些包装类
    2022-02-02
  • Java 多线程的同步代码块详解

    Java 多线程的同步代码块详解

    这篇文章主要介绍了Java 多线程的同步代码块,使用synchronized关键字创建线程同步方法是实现线程同步的关键,需要的朋友可以参考下
    2021-10-10
  • springboot Actuator的指标监控可视化功能详解

    springboot Actuator的指标监控可视化功能详解

    SpringBoot Actuator是springboot为简化我们对微服务项目的监控功能抽取出来的模块,使得我们每个微服务快速引用即可获得生产界别的应用监控、审计等功能。这篇文章主要介绍了springboot Actuator的指标监控可视化,需要的朋友可以参考下
    2021-08-08
  • java实现简单银行ATM系统

    java实现简单银行ATM系统

    这篇文章主要为大家详细介绍了java实现简单银行ATM系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • Java使用Swing实现一个模拟电脑计算器

    Java使用Swing实现一个模拟电脑计算器

    Java Swing 是一个用于创建 Java GUI(图形用户界面)的框架,它提供了一系列的 GUI 组件和工具,可以用于创建桌面应用程序,包括按钮、文本框、标签、表格等等,本文给大家介绍了Java使用Swing实现一个模拟计算器,感兴趣的同学可以自己动手尝试一下
    2024-05-05
  • 灵活控制任务执行时间的Cron表达式范例

    灵活控制任务执行时间的Cron表达式范例

    这篇文章主要为大家介绍了灵活控制任务执行时间的Cron表达式范例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • 4个Java8中你需要知道的函数式接口分享

    4个Java8中你需要知道的函数式接口分享

    Java 8 中提供了许多函数式接口,包括Function、Consumer、Supplier、Predicate 等等。本文主要来和大家介绍一下它们的具体使用,需要的可以参考一下
    2023-04-04
  • Java中Jackson的多态反序列化详解

    Java中Jackson的多态反序列化详解

    这篇文章主要介绍了Java中Jackson的多态反序列化详解,多态序列化与反序列化,主要是借助于Jackson的@JsonTypeInfo与@JsonSubTypes注解实现,下面将通过几个例子来简述其运用,需要的朋友可以参考下
    2023-11-11
  • idea创建的idea项目时springframework出现红色的原因和解决方法

    idea创建的idea项目时springframework出现红色的原因和解决方法

    当使用 IntelliJ IDEA 创建 Spring Framework 项目时,springframework 出现红色可能是因为相关的 Spring Framework 依赖没有正确加载或项目的配置有问题,本文给大家介绍了一些常见的原因和解决方法,需要的朋友可以参考下
    2023-09-09
  • 关于@PropertySource配置的用法解析

    关于@PropertySource配置的用法解析

    这篇文章主要介绍了关于@PropertySource配置的用法解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03

最新评论