日期+序列构建系统唯一序列号(二)
来源:互联网 发布:java项目目录结构 编辑:程序博客网 时间:2024/05/29 08:16
前一篇博客中介绍了如何简单构建时间+序号的唯一序列号,
本次介绍下构建带有按年、月、日复位的时间+序号的唯一序列号方法。
基本思路:
1、设计一张表存储序列号,字段要包含:序列号、复位标志、时间;
2、每次取序列号的时候,都需要拿当前时间和存储的时间比较;
3、判断复位标志,
如果是按年复位,比较的年不同则序列号清零;
如果是按月复位,比较的月不同则序列号清零;
如果是按日复位,比较的日不同则序列号清零;
如果比较的日期相同,则序列号+1后更新到表格,时间也要更新。
show code
一、建表sql
-- Create tablecreate table T_SERIAL( id VARCHAR2(32) not null, name VARCHAR2(50), scope VARCHAR2(50), serial VARCHAR2(10), formatter VARCHAR2(64), description VARCHAR2(100), subsys CHAR(1), st TIMESTAMP(6), revision INTEGER)tablespace USERS pctfree 10 initrans 1 maxtrans 255 storage ( initial 64K next 1M minextents 1 maxextents unlimited );-- Add comments to the table comment on table T_SERIAL is '序列号记录表';-- Add comments to the columns comment on column T_SERIAL.id is '物理主键';comment on column T_SERIAL.name is '序列号名称(英文或字母表示)';comment on column T_SERIAL.scope is '序列号取值范围';comment on column T_SERIAL.serial is '序列号';comment on column T_SERIAL.formatter is '序列号格式化位数(序列号补足位数前面补0)';comment on column T_SERIAL.description is '序列号中文描述';comment on column T_SERIAL.subsys is '序列号复位标志(1:按天复位 2:按月复位 3:按年复位)';comment on column T_SERIAL.st is '系统时间';comment on column T_SERIAL.revision is '序列版本号';-- Create/Recreate primary, unique and foreign key constraints alter table T_SERIAL add constraint PRIMARY_KEY_B3 primary key (ID) using index tablespace USERS pctfree 10 initrans 2 maxtrans 255 storage ( initial 64K next 1M minextents 1 maxextents unlimited );-- 插入序列号-- 发送流水号 按天复位 格式如:20170911000000001insert into T_SERIAL(id, name, scope, serial, formatter, description, subsys, st, revision) values(sys_guid(), 'FSLSH','' , '0', '%09d', '发送流水号', '1', sysdate, '0');-- 业务流水号 按月复位 格式如:201709000000001insert into T_SERIAL(id, name, scope, serial, formatter, description, subsys, st, revision) values(sys_guid(), 'YWLSH','' , '0', '%09d', '业务流水号', '2', sysdate, '0');-- 角色编号 按年复位 格式如:201700001insert into T_SERIAL(id, name, scope, serial, formatter, description, subsys, st, revision) values(sys_guid(), 'ROLECODE','' , '0', '%05d', '角色编号', '3', sysdate, '0');
二、表实例
package serial;import java.util.Date; public class CtlSerial{ private String id; private String name; private String scope; private String serial; private String formatter; private String description; private String subsys; private Date st; private int revision; public String getId(){ return this.id; } public void setId(String id) { this.id = id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public String getScope() { return this.scope; } public void setScope(String scope) { this.scope = scope; } public String getSerial() { return this.serial; } public void setSerial(String serial) { this.serial = serial; } public String getFormatter() { return this.formatter; } public void setFormatter(String formatter) { this.formatter = formatter; } public String getDescription() { return this.description; } public void setDescription(String description) { this.description = description; } public String getSubsys() { return this.subsys; } public void setSubsys(String subsys) { this.subsys = subsys; } public Date getSt() { return this.st; } public void setSt(Date st) { this.st = st; } public int getRevision() { return this.revision; } public void setRevision(int revision) { this.revision = revision; } public int getRevisionNext() { return (this.revision + 1); } }
三、业务序列号获取
package serial;import java.util.Calendar;import com.tienon.framework.supports.SpringContext;/** * @author leiwei * @Description 业务序列号获取,如业务流水号 获取方法Serial.getYWLSH() * @date 2016年10月10日 */public class Serial { static CtlSerialService ctlSerialService = SpringContext.getApplicationContext().getBean(CtlSerialService.class);public static final String YEAR = "3";public static final String MONTH = "2";public static final String DAY = "1";public static String getBusinessCode(String name){String busiCode = null;CtlSerial serial = ctlSerialService.getCtlSerial(name);try{ if(serial != null){String formatter = serial.getFormatter();if(formatter != null && !"".equals(formatter))busiCode = String.format(formatter, Integer.parseInt(serial.getSerial()));elsebusiCode = serial.getSerial();}String subsys = serial.getSubsys();//复位标识符if(subsys != null) {String prefix = "";//前缀Calendar calendar = Calendar.getInstance();int year = calendar.get(Calendar.YEAR);int month = calendar.get(Calendar.MONTH) + 1;String months = String.format("%02d", month);int day = calendar.get(Calendar.DAY_OF_MONTH);String days = String.format("%02d", day);if(YEAR.equals(subsys)) {//按年复位 格式:yyyy+序列号prefix = String.valueOf(year);} else if(MONTH.equals(subsys)){//按月复位 格式:yyyyMM+序列号prefix = String.valueOf(year) + months;} else if(DAY.equals(subsys)){//按日复位 格式:yyyyMMdd+序列号prefix = String.valueOf(year) + months + days;}busiCode = prefix + busiCode;}}catch(Exception e){throw new RuntimeException("序列号{"+name+"}格式化出错!", e);}return busiCode;}/** * 获取交易流水号 * @return */public static String getYWLSH(){return getBusinessCode("YWLSH");}}
四、处理序列号核心service
package serial;import java.util.Calendar;import java.util.Date;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ConcurrentMap;import javax.annotation.Resource;import org.apache.commons.lang3.StringUtils;public class CtlSerialService {@ResourceCtlSerialMapper ctlSerialMapper;public CtlSerial getCtlSerial(String name) {//每次查询序列号的时候都使用悲观锁防止并发问题s select ... from ... where ... for updateCtlSerial ctlSerial = this.ctlSerialMapper.selectByName(name);//如果该name对应的序列号不存在,则新增一条记录if (ctlSerial == null) {ctlSerial = new CtlSerial();ctlSerial.setId(UUID.randomUUID().toString().replace("-", ""));ctlSerial.setName(name);ctlSerial.setRevision(1);ctlSerial.setSerial("1");ctlSerial.setSt(new Date());this.ctlSerialMapper.insert(ctlSerial);}String subsys = ctlSerial.getSubsys();Date st = ctlSerial.getSt();if ((StringUtils.isNotEmpty(subsys)) && (null != st)) {Calendar bizCal = Calendar.getInstance();bizCal.setTime(st);Calendar sysCal = Calendar.getInstance();sysCal.setTime(new Date());if (("1".equals(subsys)) && (bizCal.get(5) != sysCal.get(5))){//日复位ctlSerial.setSerial("0");} else if (("2".equals(subsys)) && (bizCal.get(2) != sysCal.get(2))){//月复位ctlSerial.setSerial("0");} else if (("3".equals(subsys)) && (bizCal.get(1) != sysCal.get(1))){//年复位ctlSerial.setSerial("0");}}//序号加一后更新序号记录表long oldValue = Long.parseLong(ctlSerial.getSerial());long newValue = oldValue + 1L;ctlSerial.setSerial(Long.toString(newValue));ctlSerial.setSt(new Date());this.ctlSerialMapper.updateByPrimaryKey(ctlSerial);return ctlSerial;}}
package serial;public abstract interface CtlSerialMapper {public abstract int insert(CtlSerial paramCtlSerial);public abstract int updateByPrimaryKey(CtlSerial paramCtlSerial);public abstract CtlSerial selectByName(String paramString);}
<?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="serial.CtlSerialMapper"><resultMap id="BaseResultMap" type="serial.CtlSerial"><id column="ID" property="id" jdbcType="VARCHAR" /><result column="NAME" property="name" jdbcType="VARCHAR" /><result column="SCOPE" property="scope" jdbcType="VARCHAR" /><result column="SERIAL" property="serial" jdbcType="VARCHAR" /><result column="FORMATTER" property="formatter" jdbcType="VARCHAR" /><result column="DESCRIPTION" property="description" jdbcType="VARCHAR" /><result column="SUBSYS" property="subsys" jdbcType="CHAR" /><result column="ST" property="st" jdbcType="TIMESTAMP" /><result column="REVISION" property="revision" jdbcType="INTEGER" /></resultMap><sql id="Base_Column_List">ID, NAME, SCOPE, SERIAL, FORMATTER, DESCRIPTION, SUBSYS,ST, REVISION</sql><insert id="insert" parameterType="serial.CtlSerial">insert into SS_CTL_SERIAL (ID,NAME,SCOPE,SERIAL,FORMATTER,DESCRIPTION,SUBSYS,ST,REVISION) values (#{id,jdbcType=VARCHAR},#{name,jdbcType=VARCHAR},#{scope,jdbcType=VARCHAR},#{serial,jdbcType=VARCHAR},#{formatter,jdbcType=VARCHAR},#{description,jdbcType=VARCHAR},#{subsys,jdbcType=CHAR},#{st,jdbcType=TIMESTAMP},1)</insert><update id="updateByPrimaryKey" parameterType="serial.CtlSerial">updateSS_CTL_SERIAL setSERIAL = #{serial,jdbcType=VARCHAR},ST = #{st,jdbcType=TIMESTAMP},REVISION = #{revisionNext,jdbcType=INTEGER}whereID = #{id,jdbcType=VARCHAR}AND REVISION = #{revision,jdbcType=INTEGER}</update><select id="selectByName" resultMap="BaseResultMap">select *from SS_CTL_SERIALwhereNAME = #{name,jdbcType=VARCHAR}for update</select></mapper>
阅读全文
0 0
- 日期+序列构建系统唯一序列号(二)
- 日期+序列构建系统唯一序列号(一)
- Android获取唯一标识(唯一序列号)
- 获取Android唯一标识(唯一序列号)
- 如何获取Android唯一标识(唯一序列号)
- 如何获取Android唯一标识(唯一序列号)
- 如何获取Android唯一标识(唯一序列号)
- 获取Android设备唯一标识(唯一序列号)
- 如何获取Android手机的唯一标识(唯一序列号)
- 如何获取Android唯一标识(唯一序列号)
- 如何获取Android唯一标识(唯一序列号)
- 如何获取Android唯一标识(唯一序列号)
- 如何获取Android唯一标识(唯一序列号)
- 如何获取Android唯一标识(唯一序列号)
- 如何获取Android唯一标识(唯一序列号)
- 如何获取Android唯一标识(唯一序列号)
- 如何获取Android唯一标识(唯一序列号)
- Android_如何获取Android唯一标识(唯一序列号)
- 闭包的运用-点赞-计数器
- SprintBoot学习笔记004(dao层jpa接口)
- 计数排序
- 九度OJ——1201二叉排序树
- Tensorflow基础:模型持久化
- 日期+序列构建系统唯一序列号(二)
- QT(1):空工程建立程序方式与文本建立程序方式的运行
- flask 的url_for
- 大数据算法面试题
- inline关键字
- 创建一个类Student
- CorelDRAW画花即好看又简单的实现这些功能
- NOIP 2017 复习计划
- 【树链剖分】【bzoj2157】: 旅游