Java通过Mysql数据库生成分布式唯一连续的ID

很多时候我们需要用到自定义的生成一段连续的ID,比如商品的订单号,下面我介绍一种通过数据库生成的一种唯一连续的ID

数据库表结构

CREATE TABLE `t_identity` (
  `id` decimal(18,0) NOT NULL,
  `name` varchar(50) DEFAULT NULL COMMENT '名称',
  `alias` varchar(50) DEFAULT NULL COMMENT '别名',
  `rule` varchar(50) DEFAULT NULL COMMENT '规则',
  `gen_type` int(1) DEFAULT NULL COMMENT '每天生成',
  `no_length` int(10) DEFAULT NULL COMMENT '流水号长度',
  `init_value` int(10) DEFAULT NULL COMMENT '初始值',
  `cur_value` int(10) DEFAULT NULL COMMENT '当前值',
  `step` int(5) DEFAULT NULL COMMENT '步长',
  `cur_date` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `renren_security`.`t_identity` (`id`, `name`, `alias`, `rule`, `gen_type`, `no_length`, `init_value`, `cur_value`, `step`, `cur_date`) VALUES ('100000000000000001', '进货单号', 'OrderNo', 'JH{yyyy}{MM}{DD}{HH}{II}{SS}{NO}', '1', '3', '1', '1', '1', '2018525');

先建立实体

DAO层


service层

package io.renren.modules.unique.service.impl;


import java.util.Date;
import java.util.Map;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;


import io.renren.common.exception.RRException;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;
import io.renren.modules.unique.dao.TIdentityDao;
import io.renren.modules.unique.entity.TIdentityEntity;
import io.renren.modules.unique.service.TIdentityService;




@Service("tIdentityService")
public class TIdentityServiceImpl extends ServiceImpl<TIdentityDao, TIdentityEntity> implements TIdentityService {
@Autowired
private TIdentityDao dao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Page<TIdentityEntity> page = this.selectPage(
                new Query<TIdentityEntity>(params).getPage(),
                new EntityWrapper<TIdentityEntity>()
        );


        return new PageUtils(page);
    }


    @Override
public String nextId(String alias) throws Exception {
TIdentityEntity identity = dao.getByAlias(alias);
String rule=identity.getRule();
int step=identity.getStep();
int genEveryDay=identity.getGenType();
Integer curValue=identity.getCurValue();
if(curValue==null) curValue=identity.getInitValue();
//每天都生成
if(genEveryDay==1){
String curDate=getCurDate();
String oldDate=identity.getCurDate();
if(!curDate.equals(oldDate)){
identity.setCurDate(curDate);
curValue=identity.getInitValue();
}
else{
curValue=curValue + step;
}
}
else{
curValue=curValue + step;
}
identity.setCurValue(curValue);
baseMapper.updateById(identity);

String rtn=getByRule(rule,identity.getNoLength(),curValue);

return rtn;
}




/**
* 返回当前日期。格式为 年月日。
* @return
*/
public static String getCurDate(){
Date date=new Date();
return (date.getYear() +1900) +"" +(date.getMonth() +1 )  +"" +date.getDate() ;

}

/**
* 根据规则返回需要显示的流水号。
* @param rule 流水号规则。
* @param length 流水号的长度。
* @param curValue 流水号的当前值。
* @return
*/
private String getByRule(String rule,int length,  int curValue){
Date date=new Date();

String year=(date.getYear() +1900) +"";
int month=date.getMonth() +1;
int day=date.getDate();
int hour = date.getHours();
int ii = date.getMinutes();
int ss = date.getSeconds();
String shortMonth="" + month;
String longMonth=(month<10)?"0" + month :"" + month;

String seqNo=getSeqNo(rule,curValue,length);

String shortDay="" + day;
String longDay=(day<10)?"0" + day :"" + day;

String shortHour = "" + hour;
String longHour = (hour < 10) ? "0" + hour : "" + hour;

String shortII = "" + ii;
String longII = (ii < 10) ? "0" + ii : "" + ii;

String shortSS = "" + ss;
String longSS = (ss < 10) ? "0" + ss : "" + ss;

String rtn=rule.replace("{yyyy}", year)
.replace("{MM}", longMonth)
.replace("{mm}", shortMonth)
.replace("{DD}", longDay)
.replace("{dd}", shortDay)
.replace("{HH}", longHour)
.replace("{hh}", shortHour)
.replace("{II}", longII)
.replace("{ii}", shortII)
.replace("{SS}", longSS)
.replace("{ss}", shortSS)
.replace("{NO}", seqNo)
.replace("{no}", seqNo );


return rtn;
}

/**
* 根据当前流水号的值和流水号显示的长度。
* <pre>
* 比如:当前流水号为55 ,显示长度为5那么这个方法返回:00055。
* </pre>
* @param curValue 当前流水号的值。
* @param length 显示的长度。
* @return
*/
private static String getSeqNo(String rule,int curValue,int length){
String tmp=curValue +"";
int len= 0 ;
if(rule.indexOf("no")>-1){
len = length;
}else{
len = length-tmp.length();
}
String rtn="";
switch (len) {
case 1:
rtn= "0";
break;
case 2:
rtn= "00";
break;
case 3:
rtn= "000";
break;
case 4:
rtn= "0000";
break;
case 5:
rtn= "00000";
break;
case 6:
rtn= "000000";
break;
case 7:
rtn= "0000000";
break;
case 8:
rtn= "00000000";
break;
case 9:
rtn= "000000000";
break;
case 10:
rtn= "0000000000";
break;
case 11:
rtn= "00000000000";
break;
case 12:
rtn= "000000000000";
break;
}
if(rule.indexOf("no")>-1){
return tmp + rtn;
}else{
return rtn + tmp;
}

}


@Override
public Long getMaxId(String column, String table) throws Exception {
return dao.getMaxId(column, table);
}

public static void main(String[] args){
Date dd = new Date();

System.out.println(dd.getHours());
System.out.println(dd.getMinutes());
System.out.println(dd.getSeconds());
}
           

}

测试类


猜你喜欢

转载自blog.csdn.net/yc_low_profile/article/details/80452278