Browse Source

物料批量更新及新增方法过程优化

dongbw 7 years ago
parent
commit
cb93d73e1c

+ 6 - 0
src/main/java/com/uas/ps/product/RepositoryConfiguration.java

@@ -1,5 +1,6 @@
 package com.uas.ps.product;
 package com.uas.ps.product;
 
 
+import com.uas.ps.product.data.MyJdbcTemplate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
 import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Bean;
@@ -27,4 +28,9 @@ public class RepositoryConfiguration {
         return builder.dataSource(dataSource)
         return builder.dataSource(dataSource)
                 .packages("com.uas.ps.entity", "com.uas.ps.product.**.*").build();
                 .packages("com.uas.ps.entity", "com.uas.ps.product.**.*").build();
     }
     }
+
+    @Bean
+    public MyJdbcTemplate jdbcTemplate() {
+        return new MyJdbcTemplate(dataSource);
+    }
 }
 }

+ 6 - 13
src/main/java/com/uas/ps/product/controller/ProductController.java

@@ -165,23 +165,18 @@ public class ProductController {
     @HttpLog
     @HttpLog
     @RequestMapping(value = "/update/b2b", method = RequestMethod.POST)
     @RequestMapping(value = "/update/b2b", method = RequestMethod.POST)
     @ResponseBody
     @ResponseBody
-    public List<Long> updateB2bProdInfo(@RequestBody List<Product> data) throws UnsupportedEncodingException {
-        List<Product> productInfo = data;
-        List<Long> resultProducts = new ArrayList<>();
+    public List<Long> updateB2bProdInfo(@RequestBody List<Product> data) {
+        List<Long> ids = new ArrayList<>();
         try {
         try {
             waitSyncHelper.preWait("B2B");
             waitSyncHelper.preWait("B2B");
-            productInfo = productService.updateB2bProdInfo(productInfo);
+            ids = productService.update(data);
             waitSyncHelper.waitResponse();
             waitSyncHelper.waitResponse();
-            log(productInfo, "成功", "B2B批量更新物料信息成功,数据量:" + productInfo.size(), null, null);
+            log(data, "成功", "B2B批量更新物料信息成功,数据量:" + data.size(), null, null);
         } catch (Exception e) {
         } catch (Exception e) {
-            log(productInfo, "失败", "B2B批量更新物料信息失败,数据量:" + productInfo.size(), null, null);
+            log(data, "失败", "B2B批量更新物料信息失败,数据量:" + data.size(), null, null);
             e.printStackTrace();
             e.printStackTrace();
         }
         }
-        // B2B批量更新不返回  -- 2018年2月28日 10:22:20 因为个人物料库新增的物料单个操作很慢,所以批量操作也需要返回所有物料的id List
-        for (Product product : productInfo) {
-            resultProducts.add(product.getId());
-        }
-        return resultProducts;
+        return ids;
     }
     }
 
 
     /**
     /**
@@ -197,9 +192,7 @@ public class ProductController {
         long start = System.currentTimeMillis();
         long start = System.currentTimeMillis();
         ModelMap map = new ModelMap();
         ModelMap map = new ModelMap();
         try {
         try {
-            waitSyncHelper.preWait("B2B");
             map = productService.updateProdInfoAndAddToProductUser(data);
             map = productService.updateProdInfoAndAddToProductUser(data);
-            waitSyncHelper.waitResponse();
             log(data, "成功", "B2B批量导入个人产品成功,数据量:" + data.size(), null, null);
             log(data, "成功", "B2B批量导入个人产品成功,数据量:" + data.size(), null, null);
         } catch (Exception e) {
         } catch (Exception e) {
             log(data, "失败", "B2B批量导入个人产品失败,数据量:" + data.size(), null, null);
             log(data, "失败", "B2B批量导入个人产品失败,数据量:" + data.size(), null, null);

+ 93 - 0
src/main/java/com/uas/ps/product/data/MyJdbcTemplate.java

@@ -0,0 +1,93 @@
+package com.uas.ps.product.data;
+
+import org.springframework.dao.DataAccessException;
+import org.springframework.jdbc.core.BatchPreparedStatementSetter;
+import org.springframework.jdbc.core.InterruptibleBatchPreparedStatementSetter;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.ParameterDisposer;
+import org.springframework.jdbc.core.PreparedStatementCallback;
+import org.springframework.jdbc.core.PreparedStatementCreator;
+import org.springframework.jdbc.core.SqlProvider;
+import org.springframework.jdbc.support.JdbcUtils;
+import org.springframework.util.Assert;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by Pro1 on 2018/3/6.
+ */
+public class MyJdbcTemplate extends JdbcTemplate {
+
+    public MyJdbcTemplate(DataSource dataSource) {
+        super(dataSource);
+    }
+
+    public <T> T insertAndReturnKey(String sql, PreparedStatementCallback<T> action) throws DataAccessException {
+        return execute(new GenerateKeyStatementCreator(sql), action);
+    }
+
+    private static class GenerateKeyStatementCreator implements PreparedStatementCreator, SqlProvider {
+        private final String sql;
+
+        public GenerateKeyStatementCreator(String sql) {
+            Assert.notNull(sql, "SQL must not be null");
+            this.sql = sql;
+        }
+
+        public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
+            return con.prepareStatement(this.sql, PreparedStatement.RETURN_GENERATED_KEYS);
+        }
+
+        public String getSql() {
+            return this.sql;
+        }
+    }
+
+    public <T> List<T> batchInsert(String sql, final BatchPreparedStatementSetter pss) throws DataAccessException {
+        if (logger.isDebugEnabled()) {
+            logger.debug("Executing SQL batch insert [" + sql + "]");
+        }
+
+        return insertAndReturnKey(sql, new PreparedStatementCallback<List<T>>() {
+            @Override
+            public List<T> doInPreparedStatement(PreparedStatement ps) throws SQLException {
+                try {
+                    int batchSize = pss.getBatchSize();
+                    InterruptibleBatchPreparedStatementSetter ipss =
+                            (pss instanceof InterruptibleBatchPreparedStatementSetter ?
+                                    (InterruptibleBatchPreparedStatementSetter) pss : null);
+                    for (int i = 0; i < batchSize; i++) {
+                        pss.setValues(ps, i);
+                        if (ipss != null && ipss.isBatchExhausted(i)) {
+                            break;
+                        }
+                        ps.addBatch();
+                    }
+                    ps.executeBatch();
+                    ResultSet rs = null;
+                    try {
+                        rs = ps.getGeneratedKeys();
+                        List<T> generated = new ArrayList<T>();
+                        while (rs.next()) {
+                            generated.add((T) rs.getObject(1));
+                        }
+                        return generated;
+                    } finally {
+                        JdbcUtils.closeResultSet(rs);
+                    }
+                } finally {
+                    if (pss instanceof ParameterDisposer) {
+                        ((ParameterDisposer) pss).cleanupParameters();
+                    }
+                }
+            }
+        });
+    }
+
+}

+ 20 - 0
src/main/java/com/uas/ps/product/service/ProductService.java

@@ -55,6 +55,26 @@ public interface ProductService {
      */
      */
     ModelMap matchB2cAll(Long enUU);
     ModelMap matchB2cAll(Long enUU);
 
 
+    /**
+     * 批量更新物料
+     * @param data
+     * @return
+     */
+    List<Long> update(List<Product> data);
+
+    /**
+     * 批量新增物料资料
+     * @param newList 新增的物料资料
+     * @return 保存之后的idList
+     */
+    List<Long> insertAndReturnKey(List<Product> newList);
+
+    /**
+     * 批量更新物料资料
+     * @param newList 更新的物料资料
+     * @return 更新之后的idList
+     */
+    List<Long> updateAndReturnKey(List<Product> newList);
 
 
     /**
     /**
      * 分配个人物料
      * 分配个人物料

+ 120 - 8
src/main/java/com/uas/ps/product/service/impl/ProductServiceImpl.java

@@ -8,6 +8,7 @@ import com.uas.ps.entity.ProductMatchResult;
 import com.uas.ps.entity.ProductUsers;
 import com.uas.ps.entity.ProductUsers;
 import com.uas.ps.entity.Status;
 import com.uas.ps.entity.Status;
 import com.uas.ps.product.ProductConstant;
 import com.uas.ps.product.ProductConstant;
+import com.uas.ps.product.data.MyJdbcTemplate;
 import com.uas.ps.product.entity.Prod;
 import com.uas.ps.product.entity.Prod;
 import com.uas.ps.product.entity.ProductSaler;
 import com.uas.ps.product.entity.ProductSaler;
 import com.uas.ps.product.repository.ProductDao;
 import com.uas.ps.product.repository.ProductDao;
@@ -18,7 +19,7 @@ import com.uas.ps.product.sync.WaitSyncHelper;
 import com.uas.ps.properties.UrlProperties;
 import com.uas.ps.properties.UrlProperties;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.BatchPreparedStatementSetter;
 import org.springframework.jdbc.core.ParameterizedPreparedStatementSetter;
 import org.springframework.jdbc.core.ParameterizedPreparedStatementSetter;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
@@ -56,7 +57,7 @@ public class ProductServiceImpl implements ProductService {
     private UrlProperties urlProperties;
     private UrlProperties urlProperties;
 
 
     @Autowired
     @Autowired
-    private JdbcTemplate jdbcTemplate;
+    private MyJdbcTemplate jdbcTemplate;
 
 
     @Autowired
     @Autowired
     private WaitSyncHelper waitSyncHelper;
     private WaitSyncHelper waitSyncHelper;
@@ -293,7 +294,7 @@ public class ProductServiceImpl implements ProductService {
         ModelMap map = new ModelMap();
         ModelMap map = new ModelMap();
         List<Product> updateList = new ArrayList<>();
         List<Product> updateList = new ArrayList<>();
         try {
         try {
-            long start = System.currentTimeMillis();
+//            long start = System.currentTimeMillis();
 //            List<Product> products = updateB2bProdInfo(data);
 //            List<Product> products = updateB2bProdInfo(data);
 //            for (Product product : data) {
 //            for (Product product : data) {
 //                if (null != product.getId()) {
 //                if (null != product.getId()) {
@@ -306,24 +307,135 @@ public class ProductServiceImpl implements ProductService {
 //                }
 //                }
 //            }
 //            }
             waitSyncHelper.preWait("B2B");
             waitSyncHelper.preWait("B2B");
-            List<Product> products = productDao.save(data);
+//            List<Product> products = productDao.save(data);
+            List<Long> ids = update(data);
+            List<Product> products = productDao.findAll(ids);
             waitSyncHelper.waitResponse();
             waitSyncHelper.waitResponse();
-            System.out.println("更新完物料:" + (System.currentTimeMillis()  - start));
-            start = System.currentTimeMillis();
+//            System.out.println("更新完物料:" + (System.currentTimeMillis()  - start));
+//            start = System.currentTimeMillis();
             waitSyncHelper.preWait("B2B");
             waitSyncHelper.preWait("B2B");
             int sum = updateProductUser(products);
             int sum = updateProductUser(products);
             waitSyncHelper.waitResponse();
             waitSyncHelper.waitResponse();
-            System.out.println("保存完个人物料:" + (System.currentTimeMillis()  - start));
+//            System.out.println("保存完个人物料:" + (System.currentTimeMillis()  - start));
             map.put("success", "true");
             map.put("success", "true");
             map.put("result", sum);
             map.put("result", sum);
         } catch (Exception e) {
         } catch (Exception e) {
             e.printStackTrace();
             e.printStackTrace();
             map.put("success", "false");
             map.put("success", "false");
-            map.put("message", e.getMessage());
+            map.put("message", e.getCause() + e.getMessage());
         }
         }
         return map;
         return map;
     }
     }
 
 
+    /**
+     * 更新物料信息
+     * @param data 物料资料
+     * @return 保存之后的idList
+     */
+    @Override
+    public List<Long> update(List<Product> data) {
+        List<Product> newList = new ArrayList<>();
+        List<Product> updateList = new ArrayList<>();
+        List<Long> ids = new ArrayList<>();
+        for (Product product: data) {
+            if (null == product.getId()) {
+                newList.add(product);
+            } else {
+                updateList.add(product);
+                ids.add(product.getId());
+            }
+        }
+//        long start = System.currentTimeMillis();
+        if (!CollectionUtils.isEmpty(newList)) {
+            List<Long> newIds = insertAndReturnKey(newList);
+//            System.out.println("插入新数据,数据量:" + newIds.size() + "耗时:" + (System.currentTimeMillis() - start));
+//            start = System.currentTimeMillis();
+            ids.addAll(newIds);
+        }
+        if (!CollectionUtils.isEmpty(updateList)) {
+            updateAndReturnKey(updateList);
+//            System.out.println("update数据,数据量:" + updateList.size() + "耗时:" + (System.currentTimeMillis() - start));
+        }
+        return ids;
+    }
+
+    /**
+     * 批量新增物料资料
+     * @param newList 新增的物料资料
+     * @return 保存之后的idList
+     */
+    @Override
+    public List<Long> insertAndReturnKey(final List<Product> newList) {
+        return jdbcTemplate.batchInsert("insert into products(pr_enuu,pr_useruu,pr_code,pr_title,pr_spec,pr_cmpcode,pr_brand," +
+                "pr_unit,pr_minorder,pr_minpack,pr_leadtime,pr_ltinstock,pr_issale,pr_ispurchase,pr_sourceapp) " +
+                "select ?,?,?,?,?,?,?,?,?,?,?,?,?,?,? from dual where not exists(select pr_id from products where pr_enuu = ? and pr_code = ?)", new BatchPreparedStatementSetter() {
+            @Override
+            public void setValues(PreparedStatement ps, int i) throws SQLException {
+                Product product = newList.get(i);
+                ps.setLong(1, product.getEnUU());
+                ps.setLong(2, product.getUserUU());
+                ps.setString(3, product.getCode());
+                ps.setString(4, product.getTitle());
+                ps.setString(5, product.getSpec());
+                ps.setString(6, product.getCmpCode());
+                ps.setString(7, product.getBrand());
+                ps.setString(8, product.getUnit());
+                ps.setObject(9, product.getMinOrder());
+                ps.setObject(10, product.getMinPack());
+                ps.setObject(11, product.getLeadTime());
+                ps.setObject(12, product.getLtinstock());
+                ps.setShort(13, product.getIsSale());
+                ps.setShort(14, product.getIsPurchase());
+                ps.setString(15, product.getSourceApp());
+                ps.setLong(16, product.getEnUU());
+                ps.setString(17, product.getCode());
+            }
+
+            @Override
+            public int getBatchSize() {
+                return newList.size();
+            }
+        });
+    }
+
+    /**
+     * 批量更新物料资料
+     * @param updateList 更新的物料资料
+     * @return 更新之后的idList
+     */
+    @Override
+    public List<Long> updateAndReturnKey(final List<Product> updateList) {
+        return jdbcTemplate.batchInsert("update products set pr_enuu=?,pr_useruu=?,pr_code=?,pr_title=?,pr_spec=?,pr_cmpcode=?," +
+                "pr_brand=?,pr_unit=?,pr_minorder=?,pr_minpack=?,pr_leadtime=?,pr_ltinstock=?,pr_issale=?,pr_ispurchase=?,pr_sourceapp=? " +
+                "where pr_id=?", new BatchPreparedStatementSetter() {
+            @Override
+            public void setValues(PreparedStatement ps, int i) throws SQLException {
+                Product product = updateList.get(i);
+                ps.setLong(1, product.getEnUU());
+                ps.setLong(2, product.getUserUU());
+                ps.setString(3, product.getCode());
+                ps.setString(4, product.getTitle());
+                ps.setString(5, product.getSpec());
+                ps.setString(6, product.getCmpCode());
+                ps.setString(7, product.getBrand());
+                ps.setString(8, product.getUnit());
+                ps.setObject(9, product.getMinOrder());
+                ps.setObject(10, product.getMinPack());
+                ps.setObject(11, product.getLeadTime());
+                ps.setObject(12, product.getLtinstock());
+                ps.setShort(13, product.getIsSale());
+                ps.setShort(14, product.getIsPurchase());
+                ps.setString(15, product.getSourceApp());
+                ps.setLong(16, product.getId());
+            }
+
+            @Override
+            public int getBatchSize() {
+                return updateList.size();
+            }
+        });
+    }
+
 //    /**
 //    /**
 //     * 新增物料上传 -- 只能返回保存数量,得不到已保存物料信息,无法满足个人库新增需要
 //     * 新增物料上传 -- 只能返回保存数量,得不到已保存物料信息,无法满足个人库新增需要
 //     * @param products 新增物料列表
 //     * @param products 新增物料列表