最近又遇到需要根据日期生成流水号的业务,然后记录了几种生成方法,一个是通过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生成,在保存时会出现相同编号的问题。

java,mysql触发器,redis生成流水号(yyyyMM000)的更多相关文章

  1. 云服务器配置 docker java mysql mongodb redis nginx 环境

    磁盘挂载 fdisk -l #查看磁盘列表 mkfs.ext4 /dev/vdb #格式化磁盘 mount /dev/vdb /data #挂载磁盘在/data echo '/dev/vdb /dat ...

  2. JAVA通过Gearman实现MySQL到Redis的数据同步(异步复制)

    MySQL到Redis数据复制方案 无论MySQL还是Redis,自身都带有数据同步的机制,像比较常用的 MySQL的Master/Slave模式 ,就是由Slave端分析Master的binlog来 ...

  3. redis作为mysql的缓存服务器(读写分离,通过mysql触发器实现数据同步)

    一.redis简介Redis是一个key-value存储系统.和Memcached类似,为了保证效率,数据都是缓存在内存中.区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录 ...

  4. java中生成流水号的一个例子(使用关系型数据库)

    在实际的开发中,可能会有根据一定的规则生成流水号的需求(比如根据根据公司编码和日期生成4位流水号)我们可以把公司和日期联合起来作为一个业务编码,把这个业务编码和序列的值存储到数据库中,每次需要生成流水 ...

  5. Java工程师学习指南第7部分:重新学习MySQL与Redis

    本文整理了微信公众号[Java技术江湖]发表和转载过的Mysql和Redis相关优质文章,想看到更多Java技术文章,就赶紧关注本公众号吧吧. 大白话说说mysql 面试官:给我说说你平时是如何优化M ...

  6. 从零搭建java后台管理系统(二)mysql和redis安装

    接上篇开始安装mysql和redis 注意了,如果用阿里云服务器,外网访问的端口必须在安全组开启,否则外网访问不通 三.服务器安装redis和mysql 本次环境搭建将所有第三方服务会安装在阿里云服务 ...

  7. Java基础90 MySQL触发器

    1.创建触发器 CREATE TRIGGER trigger_name trigger_time trigger_event ON tbl_name FOR EACH ROW trigger_stmt ...

  8. SpringMVC+Mybatis+MySQL配置Redis缓存

    SpringMVC+Mybatis+MySQL配置Redis缓存 1.准备环境: SpringMVC:spring-framework-4.3.5.RELEASE-dist Mybatis:3.4.2 ...

  9. Docker运行Mysql,Redis,SpringBoot项目

    Docker运行Mysql,Redis,SpringBoot项目 1.docker运行mysql 1.1拉取镜像 1.2启动容器 1.3进入容器 1.4开启mysql 1.5设置远程连接 1.6查看版 ...

随机推荐

  1. android的ant编译打包

    Android本身是支持ant打包项目的,并且SDK中自带一个build.xml文件. 通过该文件,可以对文件进行编译.打包.安装等.并且支持多种方式打包,如debug或者release. 一般的,可 ...

  2. webstorm 使用指南

    1. webstrom打开多个项目 默认情况下一次只能打开一个项目,如果需要打开多个就按照下面的方法: Preferences -> Directories -> Add Content ...

  3. CDOJ 1263 The Desire of Asuna 贪心

    The Desire of Asuna Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Othe ...

  4. Python和Sublime的整合

    按照下面的方式也可以运行py代码,但是交互方式不是很好,主要简单介绍了一下Python和Sublime的整合 一  Ctrl + B 二 SublimeREPL 安装SublimeREPL 1.打开P ...

  5. 给string定义一个扩展方法

    创建一个 static 的类,并且里面的方法也必须是static的,第一个参数是被扩展的对象,必须标注为this,使用时,必须保证namespace using进来了. 实例: using Syste ...

  6. c++ 派生类的构造函数 与 基类构造函数的关系

    <面向对象程序设计基础(第二版>李师贤等,第254页:C++语言的基本规则是:创建一个派生类的对象时,如果基类带有构造函数,则先调用基类的构造函数,然后才调用派生类的构造函数. <T ...

  7. 【Spring】mvc:annotation-driven 使用

    关注此标签,是在项目中有使用 <!-- 解决@ResponseBody 的实现类其默认的编码是 iso-8859-1的问题 --> <mvc:annotation-driven> ...

  8. 【编程漫谈】PHP

    PHP是个很古老的脚本技术了,当年CGI比较让人诟病,于是PHP横空出世.PHP即写即用特性,吸引了一大批粉丝,而且类似C语言的编程风格,让那些C程序员非常容易地转到这个平台上来.当然PHP刚出来的时 ...

  9. GitHub-Microsoft:DotNet4

    ylbtech-GitHub-Microsoft:DotNet4 1.返回顶部 · dotnet-template-samples Samples showing how to create temp ...

  10. 能否保证service不被杀死?

    Service设置成START_STICKY kill 后会被重启(等待5秒左右),重传Intent,保持与重启前一样 提升service优先级 在AndroidManifest.xml文件中对于in ...