ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java环境下,订单号或者流水号的生成方法(1)

2019-07-01 18:55:23  阅读:1264  来源: 互联网

标签:ServiceException name 订单号 return 流水号 java billType throws String


方法一:

(一).订单号、流水号要求:

  1. 单数据库下支持高并发
  2. 唯一的新单号,不保证连续性
  3. 不保存数据库内唯一,保证表内唯一

 (二).设计思路

  1. 如何保证数据唯一?

       先看下单号样例:A04190701000001 。

       A04:组织代码,190701:当前年月日,000001:可变长度流水号。

       通过组织代码+当前年月日+定长流水号,保证单表内唯一。

     2.如何保证单表为唯一?

       数据库中记录的形式。数据库中将存在流水生成记录表,记录如下字段:

       name(PO对象class名_组织代码_当前年月日),value(当前生成次数)。

       生成sql存储过程,获取流水序号。

(三).代码实现

/**
 * 生成序列号的工具。 <br>
 * 可支持单数据库的并发操作。
 */
public class SequenceGenerator {
  private static final SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
  private static final int DEFAULT_FLOW_NO_LEN = 6;

  /**
   * 生成定长序列号。
   * 
   * @param name
   *          名称
   * @param len
   *          长度
   * @return
   * @throws ServiceException
   */
  public static String nextValue(String name, int len) throws ServiceException {
    Assert.assertArgumentNotNull(name, "name");

    int value = nextValue(name);
    return String.format("%0" + len + "d", value);
  }

  /**
   * 生成序列号。
   * 
   * @param name
   *          序列名称。
   * @return
   * @throws ServiceException
   */
  public static int nextValue(String name) throws ServiceException {
    Assert.assertArgumentNotEmpty(name, "name");

    String sql = "select _nextval(?) v";
    ICommonDao commonDao = ApplicationContextUtil.getBean(ICommonDao.class);
    Map<String, Object> results = commonDao.findOneForJdbc(sql, name);
    if (results.size() <= 0) {
      throw new ServiceException("生成序列号失败");
    }

    Object value = results.get("v");
    if (value == null) {
      throw new ServiceException("生成序列号失败");
    }
    return (Integer) value;
  }

  /**
   * 生成单号。 <br>
   * 默认6位流水号
   * 
   * @param billClass
   *          单据对象类。
   * @return 唯一的新单号,但不保证连续性。
   * @throws ServiceException
   */
  public static String nextBillNumber(Class<?> billClass) throws ServiceException {
    return nextBillNumber(billClass.getSimpleName(), DEFAULT_FLOW_NO_LEN);
  }

  /**
   * 生成单号。 <br>
   * 默认6位流水号
   * 
   * @param billType
   *          单据类型,一般取实体短名称,禁止为null。
   * @return 唯一的新单号,但不保证连续性。
   * @throws ServiceException
   */
  public static String nextBillNumber(String billType) throws ServiceException {
    return nextBillNumber(billType, DEFAULT_FLOW_NO_LEN);
  }

  /**
   * 生成单号。
   * 
   * @param billType
   *          单据类型,一般取实体短名称,禁止为null。
   * @param flowNumLenth
   *          流水号长度。-1表示不固定长度。
   * @return 唯一的新单号,但不保证连续性。
   * @throws ServiceException
   */
  public static String nextBillNumber(String billType, int flowNumLenth) throws ServiceException {
    final String orgCode = "A04";
    return nextBillNumber(billType, orgCode, flowNumLenth);
  }

  /**
   * 生成单号。 <br>
   * 生成规格: 5位组织代码 + 6位日期(yyMMdd) + flowNumLenth位流水号。 其中,流水号每日重复计算。 <br>
   * 示例: 00001 161206 00001
   * 
   * @param billType
   *          单据类型,一般取实体短名称,禁止为null。
   * @param orgCode
   *          当前组织代码,可空。
   * @param flowNumLenth
   *          流水号长度。-1表示不固定长度。
   * @return 唯一的新单号,但不保证连续性。
   * @throws ServiceException
   */
  public static String nextBillNumber(String billType, String orgCode, int flowNumLenth)
      throws ServiceException {
    Assert.assertArgumentNotEmpty(billType, "billType");

    String suffix = StringUtils.trimToEmpty(orgCode);
    if (StringUtils.isNotBlank(suffix)) {
      suffix += "_";
    }
    final String dateStr = sdf.format(new Date());
    suffix += dateStr;

    // 取流水号
    final String key = billType + "_" + suffix;
    final int value = nextValue(key);
    String test = String.format("%s%" + (flowNumLenth < 0 ? "" : "0" + flowNumLenth) + "d",
        orgCode + dateStr, value);
    return test;
  }

  /**
   * 取当前组织代码
   * 
   * @return
   * @throws ServiceException
   */
  private static String getCurrentOrgCode() throws ServiceException {

  }

}
-- sql存储过程
begin  
  declare bExists int;
  
  select count(1) into bExists from wm_sequence where `_name` = in_name;
  if bExists = 0 then 
    INSERT INTO `wm_sequence`(`_name`, `_value`) VALUES (in_name, 0);
  end if;
  
  update wm_sequence SET _value = LAST_INSERT_ID(_value+1) where _name = in_name;
  return (select LAST_INSERT_ID());
end

 

标签:ServiceException,name,订单号,return,流水号,java,billType,throws,String
来源: https://blog.csdn.net/qinguanglong6606/article/details/94401480

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有