From 5ec2a62921dd38b5d1bcbf011dfffa5fa6f8fa22 Mon Sep 17 00:00:00 2001 From: phamvanlinh20111993 Date: Sun, 17 Sep 2023 22:34:30 +0700 Subject: [PATCH] release temp phase --- scripts-example.sql | 36 +++++ src/database/in/handle/AbstractSqlInsert.java | 6 + .../SimplePrepareStatementSqlInsert.java | 15 ++- src/database/in/handle/SimpleSqlInsert.java | 14 +- src/database/in/handle/SqlInsert.java | 2 +- src/excel/importer/ExcelImportSimple.java | 124 ++++++++++++++++++ src/excel/importer/main/Main.java | 40 +----- .../PriceTableKiotVietImportDataModel.java} | 5 +- .../model/PriceTableKiotVietTableModel.java | 41 ++++++ src/main/ExcelImportSimple.java | 37 ------ src/utils/ObjectUtils.java | 51 ++++++- 11 files changed, 292 insertions(+), 79 deletions(-) create mode 100644 scripts-example.sql create mode 100644 src/excel/importer/ExcelImportSimple.java rename src/{main/PriceTableKiotVietDataModel.java => excel/importer/model/PriceTableKiotVietImportDataModel.java} (92%) create mode 100644 src/excel/importer/model/PriceTableKiotVietTableModel.java delete mode 100644 src/main/ExcelImportSimple.java diff --git a/scripts-example.sql b/scripts-example.sql new file mode 100644 index 0000000..875a2a4 --- /dev/null +++ b/scripts-example.sql @@ -0,0 +1,36 @@ +create database fake; + +use fake; + +create table if not exists employee +( + userId varchar(100) NOT NULL, + name varchar (200), + department varchar(255), + ageName TINYINT +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + + +select * from employee; + +truncate table employee; + + + + +use fake; + DROP TABLE kiot_viet_price; +create table if not exists kiot_viet_price +( + code varchar(100) NOT NULL, + name varchar (200), + unit varchar(10) default "", + good_group varchar(50), + invent_num double, + cost_price decimal(14, 4), + last_cost_price decimal(14, 4), + market_cost_price decimal(14, 4) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +select * from kiot_viet_price; +truncate kiot_viet_price; \ No newline at end of file diff --git a/src/database/in/handle/AbstractSqlInsert.java b/src/database/in/handle/AbstractSqlInsert.java index 8d0dd8f..fc19101 100644 --- a/src/database/in/handle/AbstractSqlInsert.java +++ b/src/database/in/handle/AbstractSqlInsert.java @@ -5,6 +5,7 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; +import java.sql.Types; import javax.sql.DataSource; @@ -45,6 +46,11 @@ protected void extractEntity(R entity, PreparedStatement statement) throws SQLEx } protected void setPrepareStatement(PreparedStatement statement, Object value, int index) throws SQLException { + + if(value == null) { + statement.setNull(index, Types.NULL); + } + if (value instanceof String) { statement.setString(index, value.toString()); return; diff --git a/src/database/in/handle/SimplePrepareStatementSqlInsert.java b/src/database/in/handle/SimplePrepareStatementSqlInsert.java index 6414ec5..c8ead13 100644 --- a/src/database/in/handle/SimplePrepareStatementSqlInsert.java +++ b/src/database/in/handle/SimplePrepareStatementSqlInsert.java @@ -31,7 +31,7 @@ public SimplePrepareStatementSqlInsert(DataSource dataSource, TransactionIsolati @Override public String singleInsertValue(T entity) { - + logger.info("SimplePrepareStatementSqlInsert.singleInsertValue() start"); String sqlInsertStatement = this.createInsertPrefixCommand(entity) + SPACE + INSERT_VALUE_KEY + SPACE + this.createInsertSuffixCommand(entity); @@ -51,6 +51,7 @@ public String singleInsertValue(T entity) { rs = statement.executeUpdate(); conn.commit(); } catch (SQLException e) { + System.err.println("SimplePrepareStatementSqlInsert.class singleInsertValue(): " + e.getMessage()); logger.error("SimplePrepareStatementSqlInsert.class singleInsertValue(): {}", e.getMessage()); } finally { try { @@ -61,6 +62,7 @@ public String singleInsertValue(T entity) { conn.close(); } } catch (SQLException e1) { + System.err.println("SimplePrepareStatementSqlInsert.class singleInsertValue(): " + e1.getMessage()); logger.error("SimplePrepareStatementSqlInsert.class singleInsertValue(): {}", e1.getMessage()); } } @@ -68,11 +70,17 @@ public String singleInsertValue(T entity) { if (rs > -1) { return "Inserted " + rs; } + + logger.info("SimplePrepareStatementSqlInsert.singleInsertValue() end"); + return "fail single insert"; } @Override public String batchInsertValues(List entities, boolean isForceInsert) { + + logger.info("SimplePrepareStatementSqlInsert.batchInsertValues() start"); + if (entities == null || entities.size() == 0) { return EMPTY; } @@ -104,9 +112,11 @@ public String batchInsertValues(List entities, boolean isForceInsert) { try { conn.rollback(); } catch (SQLException e1) { + System.err.println("SimplePrepareStatementSqlInsert.class batchInsertValues(): " + e1.getMessage()); logger.error("SimplePrepareStatementSqlInsert.class batchInsertValues(): {}", e1.getMessage()); } } + System.err.println("SimplePrepareStatementSqlInsert.class batchInsertValues(): " + e.getMessage()); logger.error("SimplePrepareStatementSqlInsert.class batchInsertValues(): {}", e.getMessage()); } finally { try { @@ -117,10 +127,13 @@ public String batchInsertValues(List entities, boolean isForceInsert) { conn.close(); } } catch (SQLException e1) { + System.err.println("SimplePrepareStatementSqlInsert.class batchInsertValues(): " + e1.getMessage()); logger.error("SimplePrepareStatementSqlInsert.class batchInsertValues(): {}", e1.getMessage()); } } + logger.info("SimplePrepareStatementSqlInsert.batchInsertValues() ends"); + if (res != null) { return "Inserted " + Utils.sum(res); } diff --git a/src/database/in/handle/SimpleSqlInsert.java b/src/database/in/handle/SimpleSqlInsert.java index 4ba38ef..e253c66 100644 --- a/src/database/in/handle/SimpleSqlInsert.java +++ b/src/database/in/handle/SimpleSqlInsert.java @@ -10,12 +10,16 @@ import javax.sql.DataSource; import org.apache.commons.text.StringEscapeUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import database.in.utils.TransactionIsolationLevel; import database.in.utils.Utils; public class SimpleSqlInsert extends AbstractSqlInsert { - + + private static final Logger logger = LoggerFactory.getLogger(SimpleSqlInsert.class); + public SimpleSqlInsert(DataSource dataSource) { super(); this.dataSource = dataSource; @@ -29,6 +33,7 @@ public SimpleSqlInsert(DataSource dataSource, TransactionIsolationLevel transact @Override public String singleInsertValue(T entity) { + logger.info("SimpleSqlInsert.singleInsertValue() start"); String insertQuery = this.createInsertPrefixCommand(entity) + SPACE + INSERT_VALUE_KEY + SPACE + this.createInsertSuffixCommand(entity); @@ -65,12 +70,17 @@ public String singleInsertValue(T entity) { if (result > 0) { return "inserted " + result; } + + logger.info("SimpleSqlInsert.singleInsertValue() end"); return "fail single inserted"; } @Override public String batchInsertValues(List entities, boolean isForceInsert) { + + logger.info("SimpleSqlInsert.batchInsertValues() start"); + if (entities == null || entities.size() == 0) { return EMPTY; } @@ -122,6 +132,8 @@ public String batchInsertValues(List entities, boolean isForceInsert) { if (isForceInsert) { return "still insert despite some error"; } + + logger.info("SimpleSqlInsert.batchInsertValues() end"); return "fail batch inserted"; } diff --git a/src/database/in/handle/SqlInsert.java b/src/database/in/handle/SqlInsert.java index 6b44c2c..0de1a0d 100644 --- a/src/database/in/handle/SqlInsert.java +++ b/src/database/in/handle/SqlInsert.java @@ -11,7 +11,7 @@ public interface SqlInsert { public String INSERT_VALUE_KEY = "VALUES"; - public String SPACE = " "; + public String SPACE = Constants.BLANK; public String EMPTY = Constants.EMPTY; diff --git a/src/excel/importer/ExcelImportSimple.java b/src/excel/importer/ExcelImportSimple.java new file mode 100644 index 0000000..08c6321 --- /dev/null +++ b/src/excel/importer/ExcelImportSimple.java @@ -0,0 +1,124 @@ +package excel.importer; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.LinkedList; +import java.util.List; + +import org.apache.commons.dbcp2.BasicDataSource; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import database.in.handle.SimplePrepareStatementSqlInsert; +import database.in.handle.SqlInsert; +import database.in.utils.TransactionIsolationLevel; +import excel.importer.handle.DefaultTableExcelReader; +import excel.importer.handle.TableExcelReader; +import excel.importer.model.PriceTableKiotVietImportDataModel; +import excel.importer.model.PriceTableKiotVietTableModel; +import utils.ObjectUtils; + +public class ExcelImportSimple { + + private static final Logger logger = LoggerFactory.getLogger(ExcelImportSimple.class); + + private String pathFile; + + public ExcelImportSimple(String pathFile) { + this.pathFile = pathFile; + } + + /** + * + * @param fileName + * @return + */ + protected Workbook createWorkBook(String fileName) { + try { + InputStream file = new FileInputStream(new File(this.pathFile)); + Workbook workbook = pathFile.endsWith("xls") ? new HSSFWorkbook(file) : new XSSFWorkbook(file); + workbook.close(); + file.close(); + + return workbook; + } catch (FileNotFoundException e) { + logger.error("ExcelImportSimple.createWorkBook(): {}", e.getMessage()); + } catch (IOException e) { + logger.error("ExcelImportSimple.createWorkBook(): {}", e.getMessage()); + } + + return null; + } + + /** + * + * @return + */ + protected BasicDataSource defaultDataSource() { + BasicDataSource dataSource = new BasicDataSource(); + dataSource.setUrl("jdbc:mysql://localhost:3306/fake?useSSL=false"); + dataSource.setUsername("root"); + dataSource.setPassword("root"); + + dataSource.setMinIdle(5); + dataSource.setMaxIdle(10); + dataSource.setMaxTotal(25); + dataSource.setMaxWaitMillis(30000); + + return dataSource; + } + + /** + * + */ + public void importToDatabase() { + + logger.info("ExcelImportSimple.importToDatabase() start"); + + List models = List.of(new PriceTableKiotVietImportDataModel()); + + logger.info("ExcelImportSimple.importToDatabase() starting get data from excel"); + Workbook workbook = createWorkBook(pathFile); + if (workbook == null) + throw new NullPointerException("Workbook can not be null"); + + TableExcelReader excelReader = new DefaultTableExcelReader(workbook, models); + List> datas = excelReader.executeImport(); + + logger.info("ExcelImportSimple.importToDatabase() starting import data from excel to database"); + // import to database + SqlInsert sqlInsertCommand = new SimplePrepareStatementSqlInsert( + defaultDataSource(), TransactionIsolationLevel.TRANSACTION_REPEATABLE_READ); + // Get data from excel file + for (List tableRow : datas) { + + // work, good point, insert single data +// for (Object row : tableRow) { +// System.out.println("Data " + row.toString()); +// PriceTableKiotVietTableModel priceTableKiotVietTableModel = new PriceTableKiotVietTableModel(); +// priceTableKiotVietTableModel = ObjectUtils.updateProperties(priceTableKiotVietTableModel, row); +// // import to database +// String result = sqlInsertCommand.singleInsertValue(priceTableKiotVietTableModel); +// System.out.println("Result " + result); +// } + + // insert multi data with batch insert + List kiotVietTableModels = new LinkedList(); + for (Object row : tableRow) { + PriceTableKiotVietTableModel priceTableKiotVietTableModel = new PriceTableKiotVietTableModel(); + priceTableKiotVietTableModel = ObjectUtils.updateProperties(priceTableKiotVietTableModel, row); + kiotVietTableModels.add(priceTableKiotVietTableModel); + } + String result = sqlInsertCommand.batchInsertValues(kiotVietTableModels, true); + System.out.println("Result " + result); + } + + logger.info("ExcelImportSimple.importToDatabase() end"); + } +} diff --git a/src/excel/importer/main/Main.java b/src/excel/importer/main/Main.java index 4d1e454..46328e7 100644 --- a/src/excel/importer/main/Main.java +++ b/src/excel/importer/main/Main.java @@ -1,46 +1,16 @@ package excel.importer.main; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.List; - -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - -import excel.importer.handle.DefaultTableExcelReader; -import excel.importer.handle.TableExcelReader; -import main.PriceTableKiotVietDataModel; +import excel.importer.ExcelImportSimple; public class Main { public static void main(String[] args) { String path = "C:\\Users\\DELL\\eclipse-workspace\\SimpleImportExportExcel\\BangGia_KV14082023-213536-263.xlsx"; - FileInputStream file; - try { - file = new FileInputStream(new File(path)); - // Create Workbook instance holding reference to .xlsx file - XSSFWorkbook workbook = new XSSFWorkbook(file); - - List models = List.of(new PriceTableKiotVietDataModel()); - TableExcelReader excelImporter = new DefaultTableExcelReader(workbook, models); - - List> datas = excelImporter.executeImport(); - - for (List tableRow : datas) { - for (Object row : tableRow) { - System.out.println("Data " + row.toString()); - } - } - - workbook.close(); - file.close(); - } catch (FileNotFoundException e) { - System.out.println(e.getMessage()); - } catch (IOException e) { - System.out.println(e.getMessage()); - } + + ExcelImportSimple excelImportSimple = new ExcelImportSimple(path); + + excelImportSimple.importToDatabase(); } diff --git a/src/main/PriceTableKiotVietDataModel.java b/src/excel/importer/model/PriceTableKiotVietImportDataModel.java similarity index 92% rename from src/main/PriceTableKiotVietDataModel.java rename to src/excel/importer/model/PriceTableKiotVietImportDataModel.java index a12eca5..9f956fa 100644 --- a/src/main/PriceTableKiotVietDataModel.java +++ b/src/excel/importer/model/PriceTableKiotVietImportDataModel.java @@ -1,4 +1,4 @@ -package main; +package excel.importer.model; import java.math.BigDecimal; @@ -7,7 +7,6 @@ import excel.importer.annotation.MappingField; import excel.importer.utils.CellType; import input.validation.annotation.Max; -import input.validation.annotation.NotEmpty; import input.validation.annotation.NotNull; import input.validation.annotation.Size; import lombok.AllArgsConstructor; @@ -17,7 +16,7 @@ @Data @NoArgsConstructor @AllArgsConstructor -public class PriceTableKiotVietDataModel { +public class PriceTableKiotVietImportDataModel { @Size(size = 8) @NotNull diff --git a/src/excel/importer/model/PriceTableKiotVietTableModel.java b/src/excel/importer/model/PriceTableKiotVietTableModel.java new file mode 100644 index 0000000..9f173e4 --- /dev/null +++ b/src/excel/importer/model/PriceTableKiotVietTableModel.java @@ -0,0 +1,41 @@ +package excel.importer.model; + +import java.math.BigDecimal; + +import org.apache.commons.lang3.builder.ToStringBuilder; + +import database.in.annotation.Column; +import database.in.annotation.Table; +import lombok.Data; + +@Data +@Table(name = "kiot_viet_price") +public class PriceTableKiotVietTableModel { + @Column(name="code") + private String goodCode; + + @Column(name="name") + private String goodName; + + private String unit; + + @Column(name="good_group") + private String goodGroup; + + @Column(name="invent_num") + private Double inventoryNumber; + + @Column(name="cost_price") + private BigDecimal costPrice; + + @Column(name="last_cost_price") + private BigDecimal lastCostPrice; + + @Column(name="market_cost_price") + private BigDecimal marketCostPrice; + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} diff --git a/src/main/ExcelImportSimple.java b/src/main/ExcelImportSimple.java deleted file mode 100644 index fdab220..0000000 --- a/src/main/ExcelImportSimple.java +++ /dev/null @@ -1,37 +0,0 @@ -package main; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public abstract class ExcelImportSimple { - - private static final Logger logger = LoggerFactory.getLogger(ExcelImportSimple.class); - - private Workbook workbook; - - private String pathFile; - - public ExcelImportSimple(String pathFile, String sheetName) { - this.pathFile = pathFile; - } - - protected void createWorkBook(String fileName) { - try { - InputStream file = new FileInputStream(new File(this.pathFile)); - this.workbook = pathFile.endsWith("xls") ? new HSSFWorkbook(file) : new XSSFWorkbook(file); - } catch (FileNotFoundException e) { - logger.error("createWorkBook(): {}", e.getMessage()); - } catch (IOException e) { - logger.error("createWorkBook(): {}", e.getMessage()); - } - } -} diff --git a/src/utils/ObjectUtils.java b/src/utils/ObjectUtils.java index b8e636c..51c6c19 100644 --- a/src/utils/ObjectUtils.java +++ b/src/utils/ObjectUtils.java @@ -13,7 +13,6 @@ import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -151,4 +150,54 @@ private static Class getClass(String className, String packageName) { } return null; } + + /** + * Copy updatedObject to current Object + * + * @param currentObject + * @param updatedObject + * @param + * Object type T + * @param + * Object type K + * @return currentObject after mapping and update values with updatedObject + */ + public static T updateProperties(T currentObject, K updatedObject) { + Field[] currentObjectFields = currentObject.getClass().getDeclaredFields(); + Field[] updatedObjectFields = updatedObject.getClass().getDeclaredFields(); + + try { + for (Field currentObjectField : currentObjectFields) { + currentObjectField.setAccessible(true); + for (Field updatedObjectField : updatedObjectFields) { + updatedObjectField.setAccessible(true); + if (isSameField(currentObjectField, updatedObjectField) + && org.apache.commons.lang3.ObjectUtils.allNotNull(updatedObjectField.get(updatedObject))) { + currentObjectField.set(currentObject, updatedObjectField.get(updatedObject)); + break; + } + } + } + } catch (IllegalAccessException e) { + logger.debug("Can not copy field " + e.getMessage()); + } + + return currentObject; + } + + /** + * Check two is same name and same type + * + * @param field + * property of class + * @param compareField + * field to compare with field + * @return boolean + */ + private static boolean isSameField(Field field, Field compareField) { + return field.getName().equals(compareField.getName()) && + // check instance of or same type name Ex: Long with long is same type + (field.getType().isAssignableFrom(compareField.getType()) + || field.getType().getSimpleName().equalsIgnoreCase(compareField.getType().getSimpleName())); + } }