zoukankan      html  css  js  c++  java
  • java,mysql触发器,redis生成流水号(yyyyMM000)

    最近又遇到需要根据日期生成流水号的业务,然后记录了几种生成方法,一个是通过java代码,一个是数据库的触发器,还有是通过redis。下面是代码:

    通过java生成简易流水:

        /**
         * 通过日期和生成的流水号拼接
         * @param maxCount 已经生成的个数
         * @return
         */
        public static String recountNew(int maxCount) {
            if (maxCount < 0) {
                return null;
            }
            //201707999
            String str = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMM"));
            String countStr = str + num(maxCount, 3, 3);
            System.out.println("合同编号: " + Long.valueOf(countStr));
            return countStr;
        }
    
        /**
         * 生成流水号
         * @param current 当前生成个数
         * @param max 最大整数位
         * @param min 最小整数位
         * @return 生成的流水号
         */
        public static String num(int current, int max, int min) {
            current++;
            NumberFormat numberFormat = NumberFormat.getInstance();
            //设置是否使用分组
            numberFormat.setGroupingUsed(false);
            //设置最大整数位数
            numberFormat.setMaximumIntegerDigits(max);
            //设置最小整数位数
            numberFormat.setMinimumIntegerDigits(min);
            return numberFormat.format(current);
        }
    

    通过数据触发器实现:

    主要逻辑:以201906001 为例,根据当前日期 201606 获取流水号最大的一个,保存到n。然后把流水号加1,再和当前日期201906拼接到一起

    		CREATE TABLE orders (
    			orders_id INT (10) PRIMARY KEY,
    			customer_name VARCHAR (100)
    		);
    
    		DROP TRIGGER tr_orders_id;
    
    		CREATE TRIGGER tr_orders_id BEFORE INSERT ON orders FOR EACH ROW
    		BEGIN
    			DECLARE
    				n INT;
    		SELECT
    			IFNULL(max(RIGHT(orders_id, 3)), 0) INTO n
    		FROM
    			orders
    		WHERE
    			mid(orders_id, 1, 6) = DATE_FORMAT(now(), '%Y%m');
    		SET NEW.orders_id = concat(
    			DATE_FORMAT(now(), '%Y%m'),
    			RIGHT (001 + n, 3)
    		);
    		END;
    
    		INSERT INTO orders VALUES (0, 'jack');
    		INSERT INTO orders VALUES (0, 'jack');
    
    

    redis实现(采用)

    主要利用 StringRedisTemplate 来操作redis,写在业务层,需要使用直接注入就行。这是没有详细的说明配置StringRedisTemplate,下面代码会有问题,只是知道有这个方法,有用的时候,自己去写一下就好了。

    
    /**
     * @version V1.0
     * @Authoer CX
     * @Since:2019/5/20
     */
    public interface NumberGenService {
    
        /**
         * 根据code生成编号
         * 例:NB000001
         * @param code 前缀
         * @return 编号
         */
        String generateNumber(String code);
    
        /**
         * 根据code及年月生成编号
         * 例子:NB201905000001
         * @param code 前缀
         * @return 编号
         */
        String generateNumberByMonth(String code);
    
    
        /**
         * 根据code及年月生成编号
         * 例子:NB20190508000001
         * @param code 前缀
         * @return 编号
         */
        String generateNumberByDay (String code);
    }
    
    import com.cloudkeeper.confinement.main.service.NumberGenService;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.stereotype.Service;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * @version V1.0
     * @Authoer CX
     * @Since:2019/5/20
     */
    @Service
    public class NumberGenServiceImpl implements NumberGenService {
    
        @Autowired
        private StringRedisTemplate stringRedisTemplate;
    
        private static final int LENGTH = 6;
    
        private static final String MONTH_FORMAT = "yyyyMM";
    
        private static final String DAY_FORMAT = "yyyyMMdd";
    
        public String generateNumber (String code) {
            return getNumber(code, "");
        }
    
        public String generateNumberByMonth (String code) {
            return getNumber(code, new SimpleDateFormat(MONTH_FORMAT).format(new Date()));
        }
    
        public String generateNumberByDay (String code) {
            return getNumber(code, new SimpleDateFormat(DAY_FORMAT).format(new Date()));
        }
    
    
        private String getNumber(String code, String month) {
            code += month;
            Long number = stringRedisTemplate.opsForValue().increment("" + ":" + code);
            return code + StringUtils.leftPad(number.toString(), LENGTH, '0');
        }
    
    }
    

    总结

    以上是总结的几种实现方式,公司采用的是通过redis的自增来实现的,可以避免并发时生成相同编号的问题。通过java生成,在保存时会出现相同编号的问题。

  • 相关阅读:
    Array,prototype.toString.call()
    js 中的delete运算符
    c#连接sql数据库以及操作数据库
    ArrayList集合
    查找出数据表中的重复值
    C#中的List<string>泛型类示例
    C#中的List<string>泛型类示例
    C#中Convert.ToInt32、int.TryParse、(int)和int.Parse四者的区别
    C#获取文件夹下的所有文件的方法
    从本地文件夹中读取文本文档,并将所有的文档内容合并到一个文本中
  • 原文地址:https://www.cnblogs.com/black-spike/p/10986260.html
Copyright © 2011-2022 走看看