Jelajahi Sumber

修改#20190521001 bug,分中心改上下架表的id类型为varchar

csk 6 tahun lalu
induk
melakukan
57454bbb60

+ 10 - 0
README.md

@@ -3,3 +3,13 @@
 
 新WMS数据抓到海关监管系统
 
+## bug
+1. \#20190521001
+    + big编号
+    ```
+    #20190521001
+    ```
+    + bug说明:
+        - 2019年5月21日分中心修改【acq_shelf_load】上下架表【id】字段类型为【varchar】
+        - 使用雪花算法作为增长id
+

+ 2 - 0
build.gradle

@@ -57,6 +57,8 @@ dependencies {
 	// Spring Boot
 	testCompile('org.springframework.boot:spring-boot-starter-test')
 
+	compile('org.springframework.boot:spring-boot-starter-tomcat')
+
 	compile('org.springframework.boot:spring-boot-starter-web')
 	compile('org.springframework.boot:spring-boot-starter-aop')
 

+ 4 - 0
src/main/java/com/emato/cus/supervise/biz/acqShelfLoad/down/AcqShelfLoadDownCusData.java

@@ -6,6 +6,7 @@ import com.emato.cus.supervise.domainCus.CusAcqShelfLoad04;
 import com.emato.cus.supervise.domainOms.OmsCusUnitCode;
 import com.emato.cus.supervise.mapperOms.OmsCusUnitCodeMapper;
 import com.emato.cus.supervise.service.cus.CusAcqShelfLoadService04;
+import com.emato.cus.supervise.util.snow.SnowflakeUtil;
 import com.google.common.collect.Lists;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -53,6 +54,9 @@ public class AcqShelfLoadDownCusData implements CusData {
             if(omsProductInfo != null) {
                 seat.setgUnit(omsProductInfo.getgUnitCode());
             }
+
+            // #20190521001
+            seat.setId(String.valueOf(SnowflakeUtil.getSnowNextId()));
         }
 
         int result = cusAcqShelfLoadService04.addCusAcqShelfLoad04(cusList);

+ 4 - 0
src/main/java/com/emato/cus/supervise/biz/acqShelfLoad/up/AcqShelfLoadUpCusData.java

@@ -7,6 +7,7 @@ import com.emato.cus.supervise.domainCus.CusAcqShelfLoad04;
 import com.emato.cus.supervise.domainOms.OmsCusUnitCode;
 import com.emato.cus.supervise.mapperOms.OmsCusUnitCodeMapper;
 import com.emato.cus.supervise.service.cus.CusAcqShelfLoadService04;
+import com.emato.cus.supervise.util.snow.SnowflakeUtil;
 import com.google.common.collect.Lists;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -52,6 +53,9 @@ public class AcqShelfLoadUpCusData implements CusData {
             if(omsProductInfo != null) {
                 seat.setgUnit(omsProductInfo.getgUnitCode());
             }
+
+            // #20190521001
+            seat.setId(String.valueOf(SnowflakeUtil.getSnowNextId()));
         }
 
         int result = cusAcqShelfLoadService04.addCusAcqShelfLoad04(cusList);

+ 25 - 0
src/main/java/com/emato/cus/supervise/config/SnowflakePropertiesConfiguration.java

@@ -0,0 +1,25 @@
+package com.emato.cus.supervise.config;
+
+import com.emato.cus.supervise.util.snow.DistributedSystemProperties;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 雪花算法生成ID
+ * 此配置类需要放在 <code>workerId</code>和<code>datacenterId</code> 定义所在的子模块
+ *
+ * @author Scott Chen
+ * @version 1.0
+ * 2017-11-26 16:06
+ */
+@Configuration
+public class SnowflakePropertiesConfiguration {
+
+    @Bean
+    @ConfigurationProperties("ds")
+    public DistributedSystemProperties distributedSystemProperties() {
+        return new DistributedSystemProperties();
+    }
+
+}

+ 71 - 0
src/main/java/com/emato/cus/supervise/util/SpringApplicationContextSupport.java

@@ -0,0 +1,71 @@
+package com.emato.cus.supervise.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * Spring Context
+ *
+ * @author Scott Chen
+ * @date 2017/2/27
+ *
+ */
+@Component
+public class SpringApplicationContextSupport implements ApplicationContextAware, DisposableBean {
+	private static final Logger logger = LoggerFactory.getLogger(SpringApplicationContextSupport.class);
+
+    /**
+     * Spring应用上下文
+     */
+	private static ApplicationContext applicationContext = null;
+
+
+	/**
+	 * 注入 {@Code ApplicationContext} 进来
+	 * {@link org.springframework.context.ApplicationContext}
+	 *
+	 * @param applicationContext
+	 * @throws BeansException
+	 */
+	@Override
+	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+		logger.info("注入 Inject ApplicationContext in SpringApplicationContextSupport");
+		SpringApplicationContextSupport.applicationContext = applicationContext;
+	}
+
+	@Override
+	public void destroy() throws Exception {
+		applicationContext = null;
+	}
+
+
+	public static ApplicationContext getApplicationContext() {
+		return applicationContext;
+	}
+
+	@SuppressWarnings("unchecked")
+	public static <T> T getBean(String name) {
+		return (T) applicationContext.getBean(name);
+	}
+
+	@SuppressWarnings("unchecked")
+	public static <T> T getBean(Class<T> requiredType) {
+		return applicationContext.getBean(requiredType);
+	}
+
+	@SuppressWarnings("unchecked")
+	public static <T> T getBean(String name, Class<T> requiredType) {
+		return applicationContext.getBean(name, requiredType);
+	}
+
+	@SuppressWarnings("unchecked")
+	public static <T> T getBean(String name, Object... args) {
+		return (T) applicationContext.getBean(name, args);
+	}
+
+}

+ 32 - 0
src/main/java/com/emato/cus/supervise/util/snow/DistributedSystemProperties.java

@@ -0,0 +1,32 @@
+package com.emato.cus.supervise.util.snow;
+
+import java.io.Serializable;
+
+/**
+ * @author Scott Chen
+ * @version 1.0
+ * 2017-11-26 16:16
+ */
+
+public class DistributedSystemProperties implements Serializable {
+    private static final long serialVersionUID = 2933157544322298616L;
+
+    private long workerId;
+    private long datacenterId;
+
+    public long getWorkerId() {
+        return workerId;
+    }
+
+    public void setWorkerId(long workerId) {
+        this.workerId = workerId;
+    }
+
+    public long getDatacenterId() {
+        return datacenterId;
+    }
+
+    public void setDatacenterId(long datacenterId) {
+        this.datacenterId = datacenterId;
+    }
+}

+ 28 - 0
src/main/java/com/emato/cus/supervise/util/snow/SnowflakeConfiguration.java

@@ -0,0 +1,28 @@
+package com.emato.cus.supervise.util.snow;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 雪花算法生成ID
+ *
+ * @author Scott Chen
+ * @version 1.0
+ * 2017-11-26 16:06
+ */
+@Configuration
+public class SnowflakeConfiguration {
+
+    @Autowired
+    private DistributedSystemProperties distributedSystemProperties;
+
+    @Bean
+    public SnowflakeIdWorker snowflakeIdWorker() {
+        return new SnowflakeIdWorker(
+                distributedSystemProperties.getWorkerId(),
+                distributedSystemProperties.getDatacenterId()
+        );
+    }
+
+}

+ 136 - 0
src/main/java/com/emato/cus/supervise/util/snow/SnowflakeIdWorker.java

@@ -0,0 +1,136 @@
+package com.emato.cus.supervise.util.snow;
+
+
+public class SnowflakeIdWorker {
+// ==============================Fields===========================================
+    /** 开始时间截 (2015-01-01) */
+    private final long twepoch = 1420041600000L;
+
+    /** 机器id所占的位数 */
+    private final long workerIdBits = 5L;
+
+    /** 数据标识id所占的位数 */
+    private final long datacenterIdBits = 5L;
+
+    /** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */
+    private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
+
+    /** 支持的最大数据标识id,结果是31 */
+    private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+
+    /** 序列在id中占的位数 */
+    private final long sequenceBits = 12L;
+
+    /** 机器ID向左移12位 */
+    private final long workerIdShift = sequenceBits;
+
+    /** 数据标识id向左移17位(12+5) */
+    private final long datacenterIdShift = sequenceBits + workerIdBits;
+
+    /** 时间截向左移22位(5+5+12) */
+    private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+
+    /** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */
+    private final long sequenceMask = -1L ^ (-1L << sequenceBits);
+
+    /** 工作机器ID(0~31) */
+    private long workerId;
+
+    /** 数据中心ID(0~31) */
+    private long datacenterId;
+
+    /** 毫秒内序列(0~4095) */
+    private long sequence = 0L;
+
+    /** 上次生成ID的时间截 */
+    private long lastTimestamp = -1L;
+
+    //==============================Constructors=====================================
+    /**
+     * 构造函数
+     * @param workerId 工作ID (0~31)
+     * @param datacenterId 数据中心ID (0~31)
+     */
+    public SnowflakeIdWorker(long workerId, long datacenterId) {
+        if (workerId > maxWorkerId || workerId < 0) {
+            throw new IllegalArgumentException(String.format("worderId is " + workerId + ", worker Id can't be greater than %d or less than 0", maxWorkerId));
+        }
+        if (datacenterId > maxDatacenterId || datacenterId < 0) {
+            throw new IllegalArgumentException(String.format("datacenterId is " + datacenterId + ", datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
+        }
+        this.workerId = workerId;
+        this.datacenterId = datacenterId;
+    }
+
+    // ==============================Methods==========================================
+    /**
+     * 获得下一个ID (该方法是线程安全的)
+     * @return SnowflakeId
+     */
+    public synchronized long nextId() {
+        long timestamp = timeGen();
+
+        //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
+        if (timestamp < lastTimestamp) {
+            throw new RuntimeException(
+                    String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
+        }
+
+        //如果是同一时间生成的,则进行毫秒内序列
+        if (lastTimestamp == timestamp) {
+            sequence = (sequence + 1) & sequenceMask;
+            //毫秒内序列溢出
+            if (sequence == 0) {
+                //阻塞到下一个毫秒,获得新的时间戳
+                timestamp = tilNextMillis(lastTimestamp);
+            }
+        }
+        //时间戳改变,毫秒内序列重置
+        else {
+            sequence = 0L;
+        }
+
+        //上次生成ID的时间截
+        lastTimestamp = timestamp;
+
+        //移位并通过或运算拼到一起组成64位的ID
+        return ((timestamp - twepoch) << timestampLeftShift) //
+                | (datacenterId << datacenterIdShift) //
+                | (workerId << workerIdShift) //
+                | sequence;
+    }
+
+    /**
+     * 阻塞到下一个毫秒,直到获得新的时间戳
+     * @param lastTimestamp 上次生成ID的时间截
+     * @return 当前时间戳
+     */
+    protected long tilNextMillis(long lastTimestamp) {
+        long timestamp = timeGen();
+        while (timestamp <= lastTimestamp) {
+            timestamp = timeGen();
+        }
+        return timestamp;
+    }
+
+    /**
+     * 返回以毫秒为单位的当前时间
+     * @return 当前时间(毫秒)
+     */
+    protected long timeGen() {
+        return System.currentTimeMillis();
+    }
+
+    //==============================Test=============================================
+    /** 测试 */
+    public static void main(String[] args) {
+        SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0, 0);
+        for (int i = 0; i < 100; i++) {
+            long id = idWorker.nextId();
+            System.out.println(Long.toBinaryString(id));
+            System.out.println(id);
+        }
+
+    }
+
+}

+ 35 - 0
src/main/java/com/emato/cus/supervise/util/snow/SnowflakeUtil.java

@@ -0,0 +1,35 @@
+package com.emato.cus.supervise.util.snow;
+
+
+import com.emato.cus.supervise.util.SpringApplicationContextSupport;
+
+/**
+ * 雪花算法工具类
+ * 公用类
+ *
+ * @author Scott Chen
+ * @since 1.0
+ * 2018-01-08 11:19
+ */
+public class SnowflakeUtil {
+
+    private static final ThreadLocal<SnowflakeIdWorker> snowflakeIdWorkerThreadLocal = new ThreadLocal<>();
+
+    private SnowflakeUtil() {
+        throw new RuntimeException("Illegal instance SnowflakeUtil");
+    }
+
+    private static SnowflakeIdWorker snowWorkerInstance() {
+        SnowflakeIdWorker snowflakeIdWorker = snowflakeIdWorkerThreadLocal.get();
+        if (snowflakeIdWorker == null) {
+            snowflakeIdWorker = SpringApplicationContextSupport.getBean("snowflakeIdWorker");
+            snowflakeIdWorkerThreadLocal.set(snowflakeIdWorker);
+        }
+        return snowflakeIdWorker;
+    }
+
+    public static long getSnowNextId() {
+        return snowWorkerInstance().nextId();
+    }
+
+}

+ 9 - 1
src/main/resources/application.yml

@@ -12,10 +12,18 @@ server:
 #  address: 127.0.0.1
   port: 6666
 
+
+# 分布式配置
+ds:
+  # 工作机ID (0~31)
+  worker-id: 1
+  # 数据中心ID (0~31)
+  datacenter-id: 1
+
 # 使用环境
 spring:
   profiles:
-    active: dev
+    active:
   aop:
     proxy-target-class: true
 

+ 3 - 2
src/main/resources/mybatis/mapperCus/cus-acq-shelf-load.xml

@@ -4,7 +4,7 @@
 <mapper namespace="com.emato.cus.supervise.mapperCus.CusAcqShelfLoadMapper04">
 
     <resultMap id="cusAcqInventoryInfo" type="com.emato.cus.supervise.domainCus.CusAcqShelfLoad04">
-        <id property="id" column="id"/>
+        <result property="id" column="id"/>
         <result property="goodsName" column="goods_name"/>
         <result property="codeTs" column="code_ts"/>
 
@@ -39,7 +39,7 @@
 
     <!-- 货物上下架数据 -->
     <insert id="addCusAcqShelfLoad04" parameterType="List">
-        INSERT INTO acq_shelf_load (goods_name, code_ts,
+        INSERT INTO acq_shelf_load (id, goods_name, code_ts,
                   form_no_dec, form_no,
                   sku_no, goods_id,
                   g_unit, g_qyt, legal_unit, legal_qyt,
@@ -49,6 +49,7 @@
                   creater_sn, create_time, moder_sn, mod_time) VALUES
         <foreach collection="list" item="item" index="idx" separator="," close=";">
             (
+              #{item.id, jdbcType=VARCHAR},
               #{item.goodsName, jdbcType=VARCHAR}, #{item.codeTs, jdbcType=VARCHAR},
               #{item.formNoDec, jdbcType=VARCHAR}, #{item.formNo, jdbcType=VARCHAR},
               #{item.skuNo, jdbcType=VARCHAR}, #{item.goodsId, jdbcType=VARCHAR},