最近又遇到須要根據日期生成流水號的業務,而後記錄了幾種生成方法,一個是經過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拼接到一塊兒git
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');
主要利用 StringRedisTemplate 來操做redis,寫在業務層,須要使用直接注入就行。這是沒有詳細的說明配置StringRedisTemplate,下面代碼會有問題,只是知道有這個方法,有用的時候,本身去寫一下就行了。redis
/** * @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生成,在保存時會出現相同編號的問題。spring