1. 程式人生 > >產生自定義格式的自動增長序列號

產生自定義格式的自動增長序列號

更新時間 cal nod extends return trace primary png zed

產生自定義格式的自動增長序列號:

Java代碼 技術分享圖片
  1. /**
  2. * 自己維護的序列號,至少從1開始增長
  3. */
  4. public abstract class IncrementNumber {
  5. public IncrementNumber() {}
  6. public IncrementNumber(int interval, int maxNum) {
  7. this.interval = interval;
  8. this.maxNum = maxNum;
  9. }
  10. public synchronized int cal() throws Exception {
  11. if (serialNum == -1) {
  12. serialNum = initStartNum(); // 已經使用的序列號一定 小於 緩存的序列號
  13. intervalMax = serialNum + interval;
  14. updateStartNum(intervalMax);
  15. return serialNum;
  16. }
  17. if (isMax(serialNum)) { // 達到預定的最大值
  18. resetSerialNum();
  19. return serialNum;
  20. }
  21. serialNum++;
  22. if (serialNum >= (intervalMax - 1)) { // 到達區間最大值
  23. intervalMax += interval;
  24. updateStartNum(intervalMax);
  25. }
  26. return serialNum;
  27. }
  28. /**
  29. * 初始化序列號,從緩存系統中來,比如數據庫、文件等
  30. * @return 初始序列號
  31. * @throws Exception
  32. */
  33. public abstract int initStartNum() throws Exception;
  34. /**
  35. * 更新區間最大值到緩存系統,比如數據庫、文件中。
  36. * @param intervalMax 區間最大值
  37. * @throws Exception
  38. */
  39. public abstract void updateStartNum(int intervalMax) throws Exception;
  40. /**
  41. * 重置序列號,從1開始
  42. */
  43. protected void resetSerialNum() throws Exception {
  44. this.serialNum = 1;
  45. intervalMax = serialNum + interval;
  46. updateStartNum(intervalMax);
  47. }
  48. /**
  49. * 是否是最大值
  50. * @param num
  51. * @return
  52. */
  53. private boolean isMax(int num) {
  54. return num >= maxNum;
  55. }
  56. public int getInterval() {
  57. return this.interval;
  58. }
  59. public int getMaxNum() {
  60. return this.maxNum;
  61. }
  62. /** 區間最大值 */
  63. protected int intervalMax = 0;
  64. /** 每次增加量 */
  65. protected int interval = 20;
  66. /** 預定的最大值 */
  67. protected int maxNum = 9999;
  68. /** 序列號 */
  69. protected int serialNum = -1;
  70. }

使用方法:

Java代碼 技術分享圖片
  1. @Service
  2. @Transactional
  3. public class TableKeyManager extends IncrementNumber {
  4. public TableKeyManager() {
  5. super(100, 99999999);
  6. }
  7. @Override
  8. public int initStartNum() throws Exception {
  9. TableKey tableKey = tableKeyDao.getById(name);
  10. date = DateConvertUtils.getDayEnd(DateConvertUtils.parse(tableKey.getDate(), "yyMMdd"));
  11. dateEndMillis = date.getTime();
  12. prefix = tableKey.getDate();
  13. return (int) tableKey.getMaxNum();
  14. }
  15. @Override
  16. public void updateStartNum(int intervalMax) throws Exception {
  17. TableKey tableKey = tableKeyDao.getById(name);
  18. tableKey.setDate(DateConvertUtils.format(new Date(dateEndMillis), "yyMMdd"));
  19. tableKey.setMaxNum(intervalMax);
  20. tableKeyDao.update(tableKey);
  21. }
  22. public String getNum() {
  23. try {
  24. long now = System.currentTimeMillis();
  25. int no = 0;
  26. if (now > dateEndMillis) {
  27. date = DateConvertUtils.getDayEnd(new Date(now));
  28. dateEndMillis = date.getTime();
  29. prefix = DateConvertUtils.format(date, "yyMMdd");
  30. resetSerialNum();
  31. no = this.serialNum;
  32. } else {
  33. no = cal();
  34. }
  35. return prefix + ApplicationUtil.getFixedSizeNum(no, 8);
  36. } catch (Exception e) {
  37. e.printStackTrace();
  38. }
  39. throw new RuntimeException("生成序列號錯誤");
  40. }
  41. public void setName(String name) {
  42. this.name = name;
  43. }
  44. private String prefix = null;
  45. private long dateEndMillis = 0l;
  46. private Date date = null;
  47. private String name;
  48. @Autowired
  49. private TableKeyDao tableKeyDao;
  50. }

這種方法僅在初始化時查詢一次數據庫,在每次到達增長上限時,計數自動疊加一個步長,同時更新數據庫中的數據上限。

table_key的數據結構

Sql代碼 技術分享圖片
  1. CREATE TABLE `table_key` (
  2. `key_name` varchar(100) NOT NULL COMMENT ‘需要維護的key名稱‘,
  3. `cur_no` mediumtext COMMENT ‘當前數據編號‘,
  4. `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ‘數據編號更新時間‘,
  5. `create_time` datetime DEFAULT NULL COMMENT ‘記錄創建時間‘,
  6. PRIMARY KEY (`key_name`)
  7. ) ENGINE=InnoDB DEFAULT CHARSET=utf8

產生自定義格式的自動增長序列號