生成唯一识别并可展示的编码工具类——规定字符串+日期+n位顺序码

之前需求一直让列表里展示编码,我想的是编码展示有什么意义,后台挂关系也是随机数id,不可能展示出来,后台问了下旁边高级同事,这个需求很正常,然后就得到大神的点拨,自己再琢磨了下,写了下面的工具;

需求:"***"+日期+4位顺序码

这里我先说一下我生成唯一编码的思路:

1、先用工具生成"***"+日期字符串

2、从数据库中模糊查到包含"***"+日期字符串的所有编码字段,是一个数组

3、对数组进行排序,拿到最大值的那个编码

4、找到编码中顺序码的第一个非零数的索引

5、截取到顺序码的数字,给其加1,加1操作在工具类中体现

6、最后再拼接生成编码

工具类:

package com.sunyard.ec.promotion.util;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class CodeCreateTool {
	
	/*
	 * 时间格式20190429
	 */
    public static final String LONG_FORMATTER = "yyyyMMdd";
    
    /*
     * 预备补位0
     */
    public static final String CODE_BIT = "0000000000000000";  

	/*
	 * 编码前缀
	 */
	private String prefix; 
	
	/*
	 * 顺序号即是当前日期下的第几条数据
	 */
	private Integer sequence;
	
	/*
	 * 顺序码位数
	 */
	private Integer sequenceBit;
	
	
	public CodeCreateTool(String prefix){
		this.prefix = prefix;
	}

	/**
	 * 
	 * @param prefix   
	 * @param sequence  
	 * @param orderCodeBit  
	 */
	public CodeCreateTool(String prefix, Integer sequence,Integer sequenceBit){
		this.prefix = prefix;
		this.sequence = ++sequence;
		this.sequenceBit = sequenceBit;
	}
	
	/**
	 * 生成当天日期下的下一个编码
	 * @return
	 */
	public String nextNumber(){
		//拿到补位0字符串
		String zeroStr = CODE_BIT.substring(0, this.sequenceBit - (this.sequence+"").length());
		return firstStepNumber() + zeroStr + this.sequence;
	}
	
	/**
	 * 获取除n位顺序码之外的前半部分字符串
	 * @param prefix
	 * @return
	 */
	public String firstStepNumber(){
        return this.prefix + getDateStr(LONG_FORMATTER);
    }
	
	/**
	 * 获取当前日期的不含特殊符号字符串
	 * @param formatter
	 * @return
	 */
	public static String getDateStr(String formatter){
		return DateTimeFormatter.ofPattern(formatter).format(LocalDate.now()).replaceAll("-|:", "");
	}
	
    public Integer getSequence() {
		return sequence;
	}

	public void setSequence(Integer sequence) {
		this.sequence = ++ sequence;
	}

	
	public Integer getSequenceBit() {
		return sequenceBit;
	}

	public void setSequenceBit(Integer sequenceBit) {
		this.sequenceBit = sequenceBit;
	}

	public static void main(String[] args) {
    	//输出编码中除顺序码以外的部分,这里可用来取数据库中拿到该前缀为编码前缀的顺序码的最大值,从而成为获取最终编码构造方法的第二个参数
    	System.out.println(new CodeCreateTool("cj").firstStepNumber());
    	//数据最终编码
    	System.out.println(new CodeCreateTool("CJ",32,4).nextNumber());
    
	}
}

该工具的使用举例:在调用类中写如下方法

/**
	 * 
	 * @param pre  编码前缀
	 * @param codeFiled   数据库中编码字段名称
	 * @param sequenceBit 编码中最后放几位顺序码
	 * @return
	 */
	public  String  createCode(String pre, String codeFiled, Integer sequenceBit) {
		String nextCode ="";   //要生成的编码
		String numberStep = "";//编码除顺序码之外的前缀部分
		Integer sequence = 0;  //初始编码号
		CodeCreateTool codeCreateTool = new CodeCreateTool(pre);
		numberStep = codeCreateTool.firstStepNumber();
		//获取前缀为numberStep的所有编码
		Serializable[] codes = couponDao.listFile(new WherePrams().where("code", " like ", "%"+numberStep+"%"),codeFiled);
		if(codes != null && codes.length != 0){
			//升序排序
			Arrays.sort(codes);
			//获取最大的
			String maxCode = codes[codes.length-1]+"";
			//截取顺序码
			maxCode = maxCode.substring(maxCode.length()-sequenceBit);
			//找到顺序码的第一个非0数的索引
			Integer index = 0;
			for (int i = 0; i < maxCode.length(); i++) {
				if('0' != (maxCode.charAt(i))){
					index = i;
					break;
				}
			}
			codeCreateTool.setSequence(Integer.parseInt(maxCode.substring(index)));
			codeCreateTool.setSequenceBit(sequenceBit);
			nextCode = codeCreateTool.nextNumber();
		}else{
			codeCreateTool.setSequence(sequence);
			codeCreateTool.setSequenceBit(sequenceBit);
			nextCode = codeCreateTool.nextNumber();
		}
		return nextCode;
	}

 

调用上面生成code的方法

如果还有什么优化的,希望大家看到之后指正,感谢!!!

 


上面的工具是在借鉴别人工具基础上写的,别人的工具类是这么写的,下面这个工具存在删除某条数据后,编码重复的风险,因为生成编码时时查某前缀的记录数加1,一旦某条数据被删,则问题就会出现了

package com.sunyard.ec.order.util;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class OrderNumberTool {
	private String prefix; //前缀
	
	private Integer sequence;//顺序号
	
	public OrderNumberTool(String prefix){
		this.prefix = prefix;
	}
	
	public OrderNumberTool(String prefix, Integer sequence){
		this.prefix = prefix;
		this.sequence = ++sequence;
	}
	
	public void setSequence(Integer sequence){
		this.sequence = ++sequence;
	}
	
	public String nextNumber(){
        String number = "0000" + this.sequence;
        return this.prefix + getDateStr("YYYYMMDD") + number.substring(number.length() - 5);
    }
	
	public String firstStepNumber(){
        return this.prefix + getDateStr("YYYYMMDD");
    }
	
	public String getDateStr(String model){
		String s = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME).replaceAll("[^\\d]?", "");
		if("YMD".equals(model)){
			return s.substring(2, 8);
		} else if("YYYYMMDD".equals(model)){
			return s.substring(0, 8);
		} 
		return "";
	}
	
	
    public static void main(String[] args) {
		System.out.println("");
	}
}

 

你可能感兴趣的:(开发经验,后台)