zoukankan      html  css  js  c++  java
  • 批次号/订单号生成

    概述

    在系统内部或与其他系统进行对接对编码有一定自定义规则,包括批次号、订单号,比如 PCH20170727152245000001 编码规范 = 开头字母 + 年月日时分秒 + 序号 ,使用存储过程和不使用存储过程两种方式,数据都是存在 mysql 数据库中。

    详细

    更多个人文章请点击

    一、准备工作

    1、订单号数据存储在 Mysql 数据库中,需要安装 Mysql 数据库。

    2、使用数据库存储过程生成编码和不使用存储过程在代码中生成编码,相同的是编码都是保存在数据库中。

    二、程序实现

    1、程序截图

    1501347344494015101.png

    2、实现思路

    使用存储过程:在存储过程中进行查询和插入

    不使用存储过程:在代码中先查询出来再进行插入

    都是在数据库进行查询,然后插入

    3、主要代码

    存储过程如下:

    BEGIN
    
    -- 当前日期
    DECLARE
        currentDate VARCHAR (15);
    
    -- 离现在最近的满足条件的编码
    DECLARE
        oldCode VARCHAR (25) DEFAULT '';
    
    -- oldCode的流水号
    DECLARE
        maxNo INT DEFAULT 0;
    
    IF num = 4 THEN
        -- yyyy
        SELECT
            DATE_FORMAT(NOW(),'%Y') INTO currentDate;
    
    ELSEIF num = 6 THEN
        -- yyyymm
        SELECT
            DATE_FORMAT(NOW(),'%Y%m') INTO currentDate;
    
    ELSEIF num = 8 THEN
        -- yyyymmdd
        SELECT
            DATE_FORMAT(NOW(),'%Y%m%d') INTO currentDate;
    
    ELSEIF num = 12 THEN
        -- yyyymmddHHii
        SELECT
            DATE_FORMAT(NOW(),'%Y%m%d%H%i') INTO currentDate;
    
    ELSEIF num = 14 THEN
        -- yyyymmddHHiiss
        SELECT
            DATE_FORMAT(NOW(),'%Y%m%d%H%i%s') INTO currentDate;
    
    END
    IF;
    
    -- 显示最后一条数据
    SELECT
        IFNULL(code,'') INTO oldCode
    FROM
        code_test
    WHERE
        SUBSTRING(code,1,preLen) = pre
    AND SUBSTRING(code,(preLen + 1),num) = currentDate
    AND LENGTH(code) = preLen + num + noLen
    ORDER BY
        id DESC
    LIMIT 1;
    
    -- 编码不为''截取编码的最后noLen位
    IF oldCode != '' THEN
    
    SET maxNo = CONVERT(
        SUBSTRING(oldCode, - noLen),
        DECIMAL
    );
    
    END
    IF;
    
    -- 如果流水号不足noLen位,用0填充左边
    SELECT
        CONCAT(
            pre,
            currentDate,
            LPAD((maxNo + 1), noLen, '0')
    ) INTO newCode;
    
    -- 插入数据
    INSERT INTO
        code_test (code)
    VALUES
        (newCode);
    
    SELECT
        newCode;
    
    END

    入参为:

    IN pre VARCHAR(32), IN preLen INT, IN num INT, IN noLen INT, OUT newCode VARCHAR(32)

    不使用存储过程代码如下:

        //代码同步,防止高并发
        private final static ReentrantLock lock;
        static{
            lock = new ReentrantLock();
        }
        
        /**
         * 不使用存储过程
         */
        @Test
        public void codeTest2(){
            Map<String, Object> map = new HashMap<String, Object>();
    
            String pre = "PCH";
            Integer preLen = 3;
            Integer num = 4;
            Integer noLen = 4;
            
            Date curr = new Date();
            SimpleDateFormat formatter = null;
    
            switch (num) {
            case 4:
                formatter = new SimpleDateFormat("yyyy");
                break;
            case 6:
                formatter = new SimpleDateFormat("yyyyMM");
                break;
            case 8:
                formatter = new SimpleDateFormat("yyyyMMdd");
                break;
            case 12:
                formatter = new SimpleDateFormat("yyyyMMddHHmm");
                break;
            case 14:
                formatter = new SimpleDateFormat("yyyyMMddHHmmss");
                break;
    
            default:
                break;
            }
    
            String currentDate = formatter.format(curr);
    
            map.put("pre", pre);
            map.put("preLen", preLen);
            map.put("num", num);
            map.put("noLen", noLen);
            map.put("currentDate", currentDate);
    
            lock.lock();
    
            String newCode = "";
            String newNo = "";
    
            try {
    
                String oldCode = codeTestDao.getOldCode(map);
    
                if (StringUtils.isEmpty(oldCode)) {
                    newNo = "1";
                } else {
                    Integer maxNo = Integer.parseInt(oldCode.substring(oldCode.length() - noLen));
                    newNo = String.valueOf(maxNo + 1);
                }
    
                int length = newNo.length();
                
                if(length > noLen){
                    System.out.println("新流水号位数超限");
                }
                
                for (int i = 0; i < noLen - length; i++) {
                    newNo = "0".concat(newNo);
                }
    
                newCode = pre + currentDate + newNo;
    
                CodeTest codeTest = new CodeTest();
                codeTest.setCode(newCode);
    
                codeTestDao.saveSelective(codeTest);
    
            } finally {
                lock.unlock();
            }
    
            System.out.println("生成的编码为:"+newCode);
        }

    三、运行效果

    1、将 db 文件夹下的 test.sql 导入数据库

    2、修改 jdbc.properties 文件中 mysql 连接

    3、执行 CodeJunitTest 类下的 两个测试方法

    1501347916264090866.png

    注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

  • 相关阅读:
    The XOR Largest Pair
    似乎在梦中见过的样子 (KMP)
    Censoring(栈+KMP)
    KMP解决最小循环节问题
    收集雪花 (贪心+双指针+离散化)
    「POI2010」反对称 Antisymmetry (manacher算法)
    A Horrible Poem (字符串hash+数论)
    leetcode103——二叉树的锯齿形层次遍历
    leetcode102 ——二叉树的层序遍历
    二叉树——100 相同的树(easy)
  • 原文地址:https://www.cnblogs.com/demodashi/p/8486507.html
Copyright © 2011-2022 走看看