Quellcode durchsuchen

动态支持MySQL/Oracle

张泳健 vor 5 Jahren
Ursprung
Commit
e7c8d4acb8

+ 5 - 1
config/application-mysql.yml Datei anzeigen

@@ -1,4 +1,8 @@
1
-database:
1
+from-db:
2
+  url: jdbc:mysql:replication://192.168.10.210:6446,192.168.10.210:6447/fmmp?serverTimezone=Asia/Shanghai
3
+  user: root
4
+  password: R00T@mysql
5
+to-db:
2 6
   url: jdbc:mysql:replication://192.168.10.210:6446,192.168.10.210:6447/fmmp?serverTimezone=Asia/Shanghai
3 7
   user: root
4 8
   password: R00T@mysql

+ 5 - 1
config/application-oracle.yml Datei anzeigen

@@ -1,6 +1,10 @@
1
-database:
1
+from-db:
2 2
   url: jdbc:oracle:thin:@192.168.10.236:1521:orcl
3 3
   user: C##FMMP
4 4
   password: vcare~1(^_^)
5
+to-db:
6
+  url: jdbc:mysql:replication://192.168.10.210:6446,192.168.10.210:6447/fmmp?serverTimezone=Asia/Shanghai
7
+  user: root
8
+  password: R00T@mysql
5 9
 export:
6 10
   folder: ./logs/

+ 2 - 2
config/application.yml Datei anzeigen

@@ -1,3 +1,3 @@
1 1
 profile:
2
-  active: mysql
3
-#   active: oracle
2
+#  active: mysql
3
+   active: oracle

+ 3 - 0
import.sh Datei anzeigen

@@ -0,0 +1,3 @@
1
+#/bin/bash
2
+
3
+echo "test"

+ 0 - 6
pom.xml Datei anzeigen

@@ -99,12 +99,6 @@
99 99
             <artifactId>reflections</artifactId>
100 100
             <version>0.9.11</version>
101 101
         </dependency>
102
-
103
-        <dependency>
104
-            <groupId>org.apache.shardingsphere</groupId>
105
-            <artifactId>sharding-jdbc-core</artifactId>
106
-            <version>4.0.0-RC2</version>
107
-        </dependency>
108 102
         <dependency>
109 103
             <groupId>javax.persistence</groupId>
110 104
             <artifactId>persistence-api</artifactId>

+ 6 - 2
src/main/java/com/vcarecity/cvs/FileExporterApp.java Datei anzeigen

@@ -10,6 +10,9 @@ import com.vcarecity.cvs.properties.DbProperties;
10 10
 import com.vcarecity.cvs.starter.SQLStarter;
11 11
 import me.yuxiaoyao.config.loader.ConfigLoader;
12 12
 
13
+import java.util.Map;
14
+import java.util.concurrent.ConcurrentHashMap;
15
+
13 16
 /**
14 17
  * @author Kerry on 19/11/27
15 18
  */
@@ -17,6 +20,7 @@ import me.yuxiaoyao.config.loader.ConfigLoader;
17 20
 public class FileExporterApp {
18 21
 
19 22
     public static Injector injector;
23
+    public static Map<String, String[]> TABLE_COLUMN = new ConcurrentHashMap<>();
20 24
 
21 25
 
22 26
     public static void main(String[] args) throws Exception {
@@ -57,7 +61,7 @@ public class FileExporterApp {
57 61
 
58 62
 
59 63
     private static void jdbcArgs(String[] args, AppProperties properties) {
60
-        final DbProperties database = properties.getDatabase();
64
+        final DbProperties database = properties.getFromDb();
61 65
         for (String arg : args) {
62 66
             if (arg.startsWith("jdbc.url=")) {
63 67
                 database.setUrl(arg.substring("jdbc.url=".length()).trim());
@@ -67,6 +71,6 @@ public class FileExporterApp {
67 71
                 database.setPassword(arg.substring("jdbc.password=".length()).trim());
68 72
             }
69 73
         }
70
-        properties.setDatabase(database);
74
+        properties.setFromDb(database);
71 75
     }
72 76
 }

+ 76 - 0
src/main/java/com/vcarecity/cvs/core/ColumnUpdateMapper.java Datei anzeigen

@@ -0,0 +1,76 @@
1
+package com.vcarecity.cvs.core;
2
+
3
+import lombok.AllArgsConstructor;
4
+import lombok.Data;
5
+import lombok.NoArgsConstructor;
6
+
7
+import java.util.ArrayList;
8
+import java.util.HashSet;
9
+import java.util.List;
10
+import java.util.Set;
11
+
12
+/**
13
+ * @author Kerry on 19/11/29
14
+ */
15
+
16
+public class ColumnUpdateMapper {
17
+
18
+
19
+    @AllArgsConstructor
20
+    @NoArgsConstructor
21
+    @Data
22
+    private static class ColumnMapper {
23
+        private String origin;
24
+        private String update;
25
+    }
26
+
27
+    private static List<ColumnMapper> manualMapper;
28
+
29
+    private static List<String> MYSQL_KEY_WORD;
30
+
31
+    static {
32
+        manualMapper = new ArrayList<>();
33
+        manualMapper.add(new ColumnMapper("POSITION", "POSITIONS"));
34
+
35
+
36
+        Set<String> keyWord = new HashSet<>();
37
+        keyWord.add("POSITION");
38
+
39
+        MYSQL_KEY_WORD = new ArrayList<>(keyWord);
40
+    }
41
+
42
+
43
+    /**
44
+     * Oracle数据库的字段可能跟 MySQL 不一样,统一这里处理
45
+     *
46
+     * @param table
47
+     * @param headers
48
+     * @return
49
+     */
50
+    public static String[] updateColumnName(String table, String[] headers) {
51
+        // common mapper
52
+        for (int i = 0; i < headers.length; i++) {
53
+            final String h = headers[i].toUpperCase();
54
+            for (ColumnMapper columnMapper : manualMapper) {
55
+                if (columnMapper.getOrigin().equalsIgnoreCase(h)) {
56
+                    headers[i] = columnMapper.getUpdate();
57
+                    break;
58
+                }
59
+            }
60
+        }
61
+
62
+        // 关键字先处理下
63
+        for (int i = 0; i < headers.length; i++) {
64
+            final String h = headers[i].toUpperCase();
65
+            for (String s : MYSQL_KEY_WORD) {
66
+                if (s.equalsIgnoreCase(h)) {
67
+                    headers[i] = "`" + headers[i] + "`";
68
+                    break;
69
+                }
70
+            }
71
+        }
72
+
73
+        return headers;
74
+    }
75
+
76
+}

+ 33 - 0
src/main/java/com/vcarecity/cvs/event/ExportEventListener.java Datei anzeigen

@@ -0,0 +1,33 @@
1
+package com.vcarecity.cvs.event;
2
+
3
+/**
4
+ * @author Kerry on 19/11/29
5
+ */
6
+
7
+public interface ExportEventListener {
8
+
9
+    /**
10
+     * 导出之前
11
+     *
12
+     * @param filename
13
+     */
14
+    void beforeExport(String filename);
15
+
16
+    /**
17
+     * 导出成功
18
+     *
19
+     * @param filename
20
+     * @param table
21
+     * @param header
22
+     */
23
+    void exportSuccess(String filename, String table, String[] header);
24
+
25
+    /**
26
+     * 异常
27
+     *
28
+     * @param throwable
29
+     */
30
+    void exceptionCatch(Throwable throwable);
31
+
32
+
33
+}

+ 58 - 0
src/main/java/com/vcarecity/cvs/event/MySQLImportEvent.java Datei anzeigen

@@ -0,0 +1,58 @@
1
+package com.vcarecity.cvs.event;
2
+
3
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
4
+import com.google.inject.Inject;
5
+import com.vcarecity.cvs.core.ColumnUpdateMapper;
6
+import com.vcarecity.cvs.properties.AppProperties;
7
+import com.vcarecity.cvs.properties.DbProperties;
8
+import com.vcarecity.cvs.shell.MySQLImporter;
9
+import lombok.extern.slf4j.Slf4j;
10
+
11
+import java.util.concurrent.LinkedBlockingQueue;
12
+import java.util.concurrent.ThreadFactory;
13
+import java.util.concurrent.ThreadPoolExecutor;
14
+import java.util.concurrent.TimeUnit;
15
+import java.util.concurrent.atomic.AtomicInteger;
16
+
17
+/**
18
+ * @author Kerry on 19/11/29
19
+ */
20
+
21
+@Slf4j
22
+public class MySQLImportEvent implements ExportEventListener {
23
+
24
+    private AtomicInteger callIndex = new AtomicInteger(0);
25
+
26
+    private final DbProperties dbProperties;
27
+
28
+    @Inject
29
+    public MySQLImportEvent(AppProperties properties) {
30
+        this.dbProperties = properties.getToDb();
31
+    }
32
+
33
+    @Override
34
+    public void beforeExport(String filename) {
35
+        logger.info("MySQLImportEvent.beforeExport. filename = {}", filename);
36
+    }
37
+
38
+    @Override
39
+    public void exportSuccess(String filename, String table, String[] header) {
40
+        logger.info("MySQLImportEvent.exportSuccess. filename = {}", filename);
41
+
42
+        ThreadFactory factory = new ThreadFactoryBuilder().setNameFormat("export-" + (callIndex.incrementAndGet()) + "+-%d").build();
43
+
44
+        ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,
45
+                new LinkedBlockingQueue<>(1024), factory, new ThreadPoolExecutor.AbortPolicy());
46
+
47
+        // 列名不一样时,转换
48
+        final String[] newHeader = ColumnUpdateMapper.updateColumnName(table, header);
49
+        executor.execute(new MySQLImporter(dbProperties, filename, table, newHeader));
50
+        executor.shutdown();
51
+    }
52
+
53
+
54
+    @Override
55
+    public void exceptionCatch(Throwable throwable) {
56
+        logger.info("MySQLImportEvent.exceptionCatch. throwable = {}", throwable);
57
+    }
58
+}

+ 5 - 1
src/main/java/com/vcarecity/cvs/module/SQLModule.java Datei anzeigen

@@ -5,6 +5,8 @@ import com.google.inject.Inject;
5 5
 import com.google.inject.Provides;
6 6
 import com.google.inject.Singleton;
7 7
 import com.google.inject.assistedinject.FactoryModuleBuilder;
8
+import com.vcarecity.cvs.event.ExportEventListener;
9
+import com.vcarecity.cvs.event.MySQLImportEvent;
8 10
 import com.vcarecity.cvs.factory.ResultHandlerFactory;
9 11
 import com.vcarecity.cvs.properties.AppProperties;
10 12
 import com.vcarecity.cvs.properties.DbProperties;
@@ -24,6 +26,8 @@ public class SQLModule extends AbstractModule {
24 26
     @Override
25 27
     protected void configure() {
26 28
 
29
+        bind(ExportEventListener.class).to(MySQLImportEvent.class);
30
+
27 31
         install(new FactoryModuleBuilder()
28 32
                 .implement(ResultHandlerService.class, CSVResultHandlerServiceImpl.class)
29 33
                 .build(ResultHandlerFactory.class));
@@ -49,7 +53,7 @@ public class SQLModule extends AbstractModule {
49 53
     public HikariDataSource dataSource(AppProperties properties) {
50 54
         // @see https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration
51 55
 
52
-        final DbProperties database = properties.getDatabase();
56
+        final DbProperties database = properties.getFromDb();
53 57
         HikariConfig config = new HikariConfig();
54 58
         config.setJdbcUrl(database.getUrl());
55 59
         config.setUsername(database.getUser());

+ 10 - 1
src/main/java/com/vcarecity/cvs/properties/AppProperties.java Datei anzeigen

@@ -1,5 +1,6 @@
1 1
 package com.vcarecity.cvs.properties;
2 2
 
3
+import com.fasterxml.jackson.annotation.JsonProperty;
3 4
 import lombok.Data;
4 5
 
5 6
 /**
@@ -8,11 +9,19 @@ import lombok.Data;
8 9
 
9 10
 @Data
10 11
 public class AppProperties {
11
-    private DbProperties database;
12
+
13
+    @JsonProperty("from-db")
14
+    private DbProperties fromDb;
15
+
16
+    @JsonProperty("to-db")
17
+    private DbProperties toDb;
18
+
12 19
     private Export export;
13 20
 
14 21
     @Data
15 22
     public static class Export {
16 23
         private String folder;
17 24
     }
25
+
26
+
18 27
 }

+ 3 - 1
src/main/java/com/vcarecity/cvs/service/ResultHandlerService.java Datei anzeigen

@@ -12,10 +12,12 @@ public interface ResultHandlerService {
12 12
     /**
13 13
      * ins
14 14
      *
15
+     * @param table
16
+     * @param header
15 17
      * @param dataList
16 18
      * @throws Exception
17 19
      */
18
-    <T> void resultHandler(List<T> dataList) throws Exception;
20
+    <T> void resultHandler(String table, String[] header, List<T> dataList) throws Exception;
19 21
 
20 22
 
21 23
 }

+ 0 - 1
src/main/java/com/vcarecity/cvs/service/SQLQueryService.java Datei anzeigen

@@ -9,7 +9,6 @@ import java.util.List;
9 9
 
10 10
 public interface SQLQueryService {
11 11
 
12
-
13 12
     /**
14 13
      * query by page
15 14
      *

+ 52 - 17
src/main/java/com/vcarecity/cvs/service/impl/AbstractSQLQueryService.java Datei anzeigen

@@ -3,11 +3,18 @@ package com.vcarecity.cvs.service.impl;
3 3
 import com.vcarecity.cvs.core.AutoMapper;
4 4
 import com.vcarecity.cvs.service.SQLQueryService;
5 5
 import com.zaxxer.hikari.HikariDataSource;
6
+import lombok.AllArgsConstructor;
7
+import lombok.Data;
8
+import lombok.NoArgsConstructor;
6 9
 import lombok.extern.slf4j.Slf4j;
7 10
 
8 11
 import java.sql.*;
9 12
 import java.util.ArrayList;
10 13
 import java.util.List;
14
+import java.util.Set;
15
+import java.util.stream.Collectors;
16
+
17
+import static com.vcarecity.cvs.FileExporterApp.TABLE_COLUMN;
11 18
 
12 19
 /**
13 20
  * @author Kerry on 19/11/27
@@ -16,6 +23,9 @@ import java.util.List;
16 23
 @Slf4j
17 24
 public abstract class AbstractSQLQueryService implements SQLQueryService {
18 25
 
26
+    private boolean isFirst = true;
27
+
28
+
19 29
     protected final HikariDataSource dataSource;
20 30
 
21 31
     protected AbstractSQLQueryService(HikariDataSource dataSource) {
@@ -36,7 +46,7 @@ public abstract class AbstractSQLQueryService implements SQLQueryService {
36 46
 
37 47
         ResultSet resultSet = preparedStatement.executeQuery();
38 48
 
39
-        List<T> list = resultMapper(resultSet, clazz);
49
+        List<T> list = resultMapper(table, resultSet, clazz);
40 50
 
41 51
         logger.debug("query success. size = {}. usageTime = {} /ms", list.size(), (System.currentTimeMillis() - startTime));
42 52
 
@@ -67,39 +77,40 @@ public abstract class AbstractSQLQueryService implements SQLQueryService {
67 77
      */
68 78
     protected abstract PreparedStatement getPreparedStatement(Connection connection, String sql, int start, int pageCount) throws SQLException;
69 79
 
70
-    public <T> List<T> resultMapper(ResultSet resultSet, Class<T> clazz) throws SQLException {
80
+    public <T> List<T> resultMapper(String table, ResultSet resultSet, Class<T> clazz) throws SQLException {
71 81
         if (clazz == Object.class) {
72 82
             //noinspection unchecked
73
-            return (List<T>) resultSetToObject(resultSet);
83
+            return (List<T>) resultSetToObject(table, resultSet);
74 84
         }
75 85
         return autoMapper(resultSet, clazz);
76 86
     }
77 87
 
78
-    public List<Object[]> resultSetToObject(ResultSet resultSet) throws SQLException {
88
+    public List<Object[]> resultSetToObject(String table, ResultSet resultSet) throws SQLException {
79 89
         final ResultSetMetaData metaData = resultSet.getMetaData();
80 90
         final int columnCount = metaData.getColumnCount() - 1;
81 91
 
82 92
 
83
-        int skipRnIndex = -1;
84
-        int index = 0;
85
-        String[] header = new String[columnCount];
86
-        for (int i = 0; i < columnCount; i++) {
87
-            String s = metaData.getColumnName(i + 1);
88
-            if ("RN".equalsIgnoreCase(s)) {
89
-                skipRnIndex = i;
90
-            } else {
91
-                header[index++] = s;
92
-            }
93
-        }
93
+        final List<ColumnIndexName> columnWithObject = getColumnWithObject(metaData);
94
+        final Set<Integer> skipIndex = columnWithObject.stream().map(ColumnIndexName::getIndex).collect(Collectors.toSet());
94 95
 
95
-        logger.info("header = ({})", String.join(",", header));
96
+        final String[] header = columnWithObject.stream().map(ColumnIndexName::getName).toArray(String[]::new);
97
+
98
+
99
+        TABLE_COLUMN.put(table, header);
100
+
101
+
102
+        if (isFirst) {
103
+            final String join = String.join(",", header);
104
+            logger.info("header = ({})", join);
105
+            isFirst = false;
106
+        }
96 107
 
97 108
         List<Object[]> data = new ArrayList<>();
98 109
         while (resultSet.next()) {
99 110
             Object[] objects = new Object[columnCount];
100 111
             int cIndex = 0;
101 112
             for (int i = 0; i < columnCount; i++) {
102
-                if (i == skipRnIndex) {
113
+                if (!skipIndex.contains(i)) {
103 114
                     continue;
104 115
                 }
105 116
                 objects[cIndex++] = resultSet.getObject(i + 1);
@@ -109,6 +120,29 @@ public abstract class AbstractSQLQueryService implements SQLQueryService {
109 120
         return data;
110 121
     }
111 122
 
123
+
124
+    @NoArgsConstructor
125
+    @AllArgsConstructor
126
+    @Data
127
+    public static class ColumnIndexName {
128
+        private int index;
129
+        private String name;
130
+    }
131
+
132
+    /**
133
+     * @param metaData
134
+     * @return
135
+     */
136
+    protected List<ColumnIndexName> getColumnWithObject(ResultSetMetaData metaData) throws SQLException {
137
+        final int columnCount = metaData.getColumnCount();
138
+        List<ColumnIndexName> res = new ArrayList<>(columnCount);
139
+        for (int i = 0; i < columnCount; i++) {
140
+            String name = metaData.getColumnName(i + 1);
141
+            res.add(new ColumnIndexName(i, name));
142
+        }
143
+        return res;
144
+    }
145
+
112 146
     public <T> List<T> autoMapper(ResultSet resultSet, Class<T> clazz) throws SQLException {
113 147
         List<T> list = new ArrayList<>();
114 148
         while (resultSet.next()) {
@@ -119,4 +153,5 @@ public abstract class AbstractSQLQueryService implements SQLQueryService {
119 153
         }
120 154
         return list;
121 155
     }
156
+
122 157
 }

+ 23 - 4
src/main/java/com/vcarecity/cvs/service/impl/CSVResultHandlerServiceImpl.java Datei anzeigen

@@ -6,6 +6,7 @@ import com.google.inject.assistedinject.Assisted;
6 6
 import com.vcarecity.cvs.core.AutoMapper;
7 7
 import com.vcarecity.cvs.core.JavaMapColumn;
8 8
 import com.vcarecity.cvs.core.ReflectionUtil;
9
+import com.vcarecity.cvs.event.ExportEventListener;
9 10
 import com.vcarecity.cvs.service.ResultHandlerService;
10 11
 import lombok.extern.slf4j.Slf4j;
11 12
 import org.apache.commons.csv.CSVFormat;
@@ -37,15 +38,21 @@ public class CSVResultHandlerServiceImpl implements ResultHandlerService {
37 38
     private int counter;
38 39
     private int fileNameIndex = 0;
39 40
 
41
+    private File lastFile;
42
+
43
+    private String table;
44
+    private String[] lastHeader;
40 45
 
41 46
     /**
42 47
      * 分割文件行数
43 48
      */
44 49
     private static final int SPLIT_LINE_NUM = 200_0000;
45 50
 
51
+    private final ExportEventListener eventListener;
46 52
 
47 53
     @Inject
48
-    public CSVResultHandlerServiceImpl(@Assisted String filePattern) {
54
+    public CSVResultHandlerServiceImpl(ExportEventListener eventListener, @Assisted String filePattern) {
55
+        this.eventListener = eventListener;
49 56
         this.filePattern = filePattern;
50 57
         this.csvFormat = CSVFormat.MYSQL;
51 58
         this.counter = 0;
@@ -54,7 +61,12 @@ public class CSVResultHandlerServiceImpl implements ResultHandlerService {
54 61
     private File getFile() {
55 62
         final int index = fileNameIndex;
56 63
         fileNameIndex++;
57
-        return new File(filePattern + "-" + +index + ".csv");
64
+
65
+        lastFile = new File(filePattern + "-" + +index + ".csv");
66
+        // call back
67
+        eventListener.beforeExport(lastFile.getAbsolutePath());
68
+
69
+        return lastFile;
58 70
     }
59 71
 
60 72
 
@@ -62,6 +74,9 @@ public class CSVResultHandlerServiceImpl implements ResultHandlerService {
62 74
         synchronized (this) {
63 75
             if (counter % SPLIT_LINE_NUM == 0) {
64 76
                 try {
77
+                    if (lastFile != null) {
78
+                        eventListener.exportSuccess(this.lastFile.getAbsolutePath(), table, lastHeader);
79
+                    }
65 80
                     if (bufferedWriter != null) {
66 81
                         bufferedWriter.close();
67 82
                     }
@@ -72,20 +87,22 @@ public class CSVResultHandlerServiceImpl implements ResultHandlerService {
72 87
                     writer = new CSVPrinter(bufferedWriter, csvFormat);
73 88
                 } catch (IOException e) {
74 89
                     e.printStackTrace();
90
+                    eventListener.exceptionCatch(e);
75 91
                 }
76 92
             }
77 93
         }
78 94
     }
79 95
 
80 96
     @Override
81
-    public <T> void resultHandler(List<T> dataList) throws Exception {
97
+    public <T> void resultHandler(String table, String[] header, List<T> dataList) throws Exception {
98
+        this.table = table;
99
+        this.lastHeader = header;
82 100
         checkFile();
83 101
 
84 102
         logger.debug("start write to csv file size = {}", dataList.size());
85 103
 
86 104
         long startTime = System.currentTimeMillis();
87 105
 
88
-
89 106
         Class<?> cls = Object.class;
90 107
 
91 108
         for (T t : dataList) {
@@ -125,6 +142,7 @@ public class CSVResultHandlerServiceImpl implements ResultHandlerService {
125 142
     }
126 143
 
127 144
     public void close() throws IOException {
145
+        eventListener.exportSuccess(this.lastFile.getAbsolutePath(), table, this.lastHeader);
128 146
         bufferedWriter.close();
129 147
         writer.close();
130 148
     }
@@ -192,4 +210,5 @@ public class CSVResultHandlerServiceImpl implements ResultHandlerService {
192 210
         return localTime.format(TIME_FORMATTER);
193 211
     }
194 212
 
213
+
195 214
 }

+ 5 - 2
src/main/java/com/vcarecity/cvs/service/impl/MySQLResultHandlerServiceImpl.java Datei anzeigen

@@ -2,6 +2,7 @@ package com.vcarecity.cvs.service.impl;
2 2
 
3 3
 import com.google.inject.Inject;
4 4
 import com.google.inject.assistedinject.Assisted;
5
+import com.vcarecity.cvs.event.ExportEventListener;
5 6
 import com.vcarecity.cvs.service.ResultHandlerService;
6 7
 import com.zaxxer.hikari.HikariDataSource;
7 8
 import lombok.extern.slf4j.Slf4j;
@@ -19,17 +20,19 @@ import java.util.List;
19 20
 public class MySQLResultHandlerServiceImpl implements ResultHandlerService {
20 21
 
21 22
     private final HikariDataSource dataSource;
23
+    private final ExportEventListener eventListener;
22 24
     private final String sql;
23 25
 
24 26
     @Inject
25
-    public MySQLResultHandlerServiceImpl(HikariDataSource dataSource, @Assisted String sql) {
27
+    public MySQLResultHandlerServiceImpl(HikariDataSource dataSource, ExportEventListener eventListener, @Assisted String sql) {
26 28
         this.dataSource = dataSource;
29
+        this.eventListener = eventListener;
27 30
         this.sql = sql;
28 31
     }
29 32
 
30 33
 
31 34
     @Override
32
-    public <T> void resultHandler(List<T> dataList) throws Exception {
35
+    public <T> void resultHandler(String table, String[] header, List<T> dataList) throws Exception {
33 36
         logger.debug("start write to mysql size = {}, on = {}", dataList.size(), LocalDateTime.now());
34 37
         long startTime = System.currentTimeMillis();
35 38
         final Connection connection = dataSource.getConnection();

+ 17 - 0
src/main/java/com/vcarecity/cvs/service/impl/OracleQueryServiceImpl.java Datei anzeigen

@@ -6,7 +6,10 @@ import lombok.extern.slf4j.Slf4j;
6 6
 
7 7
 import java.sql.Connection;
8 8
 import java.sql.PreparedStatement;
9
+import java.sql.ResultSetMetaData;
9 10
 import java.sql.SQLException;
11
+import java.util.ArrayList;
12
+import java.util.List;
10 13
 
11 14
 /**
12 15
  * @author Kerry on 19/11/25
@@ -37,4 +40,18 @@ public class OracleQueryServiceImpl extends AbstractSQLQueryService {
37 40
         preparedStatement.setInt(2, (page - 1) * pageCount);
38 41
         return preparedStatement;
39 42
     }
43
+
44
+    @Override
45
+    protected List<ColumnIndexName> getColumnWithObject(ResultSetMetaData metaData) throws SQLException {
46
+        final int columnCount = metaData.getColumnCount();
47
+        List<ColumnIndexName> res = new ArrayList<>(columnCount);
48
+        for (int i = 0; i < columnCount; i++) {
49
+            String name = metaData.getColumnName(i + 1);
50
+            if ("RN".equalsIgnoreCase(name)) {
51
+                continue;
52
+            }
53
+            res.add(new ColumnIndexName(i, name));
54
+        }
55
+        return res;
56
+    }
40 57
 }

+ 81 - 0
src/main/java/com/vcarecity/cvs/shell/MySQLImporter.java Datei anzeigen

@@ -0,0 +1,81 @@
1
+package com.vcarecity.cvs.shell;
2
+
3
+import com.vcarecity.cvs.properties.DbProperties;
4
+import lombok.extern.slf4j.Slf4j;
5
+
6
+import java.io.File;
7
+import java.sql.Connection;
8
+import java.sql.DriverManager;
9
+import java.sql.PreparedStatement;
10
+import java.sql.SQLException;
11
+
12
+/**
13
+ * @author Kerry on 19/11/29
14
+ */
15
+
16
+@Slf4j
17
+public class MySQLImporter implements Runnable {
18
+
19
+    private final DbProperties dbProperties;
20
+
21
+    private final String filepath;
22
+    private final String table;
23
+    private final String[] header;
24
+
25
+    private static final String LOAD_DATA_SQL_TEP = "LOAD DATA INFILE '%s' " +
26
+            "INTO TABLE %s " +
27
+            "FIELDS " +
28
+            "TERMINATED BY '\\t' " +
29
+            "ENCLOSED BY '\\\"' " +
30
+            "ESCAPED BY '\\\\' " +
31
+            "LINES TERMINATED BY '\\n' (%s)";
32
+
33
+    public MySQLImporter(DbProperties dbProperties, String filepath, String table, String[] header) {
34
+        this.dbProperties = dbProperties;
35
+        this.filepath = filepath;
36
+        this.table = table;
37
+        this.header = header;
38
+    }
39
+
40
+    @Override
41
+    public void run() {
42
+        File file = new File(filepath);
43
+        if (!file.exists()) {
44
+            return;
45
+        }
46
+
47
+        final String sql = String.format(LOAD_DATA_SQL_TEP, filepath, table, String.join(",", this.header));
48
+
49
+        logger.info("sql = {}", sql);
50
+        try {
51
+            importData(sql);
52
+        } catch (SQLException e) {
53
+            e.printStackTrace();
54
+        }
55
+    }
56
+
57
+    private void execShell(String sql) {
58
+        //Runtime.getRuntime().exec()
59
+    }
60
+
61
+
62
+    private void importFromLocal(String sql) {
63
+        //if (statement.isWrapperFor(JdbcStatement.class)) {
64
+        //    final JdbcStatement unwrap = statement.unwrap(JdbcStatement.class);
65
+        //    unwrap.setLocalInfileInputStream();
66
+        //}
67
+    }
68
+
69
+
70
+    private void importData(String sql) throws SQLException {
71
+        try (final Connection connection = getConnection();
72
+             final PreparedStatement statement = connection.prepareStatement(sql)) {
73
+            statement.executeUpdate();
74
+        }
75
+    }
76
+
77
+    private Connection getConnection() throws SQLException {
78
+        return DriverManager.getConnection(dbProperties.getUrl(), dbProperties.getUser(), dbProperties.getPassword());
79
+    }
80
+
81
+}

+ 5 - 1
src/main/java/com/vcarecity/cvs/starter/SQLStarter.java Datei anzeigen

@@ -9,6 +9,8 @@ import lombok.extern.slf4j.Slf4j;
9 9
 import javax.inject.Inject;
10 10
 import java.util.List;
11 11
 
12
+import static com.vcarecity.cvs.FileExporterApp.TABLE_COLUMN;
13
+
12 14
 /**
13 15
  * @author Kerry on 19/11/20
14 16
  */
@@ -47,6 +49,7 @@ public class SQLStarter {
47 49
             //noinspection unchecked
48 50
             cls = (Class<T>) Object.class;
49 51
         }
52
+
50 53
         ResultHandlerService resultHandler = resultHandlerFactory.createResultHandler(properties);
51 54
 
52 55
 
@@ -59,7 +62,8 @@ public class SQLStarter {
59 62
 
60 63
         do {
61 64
             List<T> result = queryService.queryByPage(table, page, this.pageCount, cls);
62
-            resultHandler.resultHandler(result);
65
+            final String[] headers = TABLE_COLUMN.get(table);
66
+            resultHandler.resultHandler(table, headers, result);
63 67
             currentSize = result.size();
64 68
 
65 69
             page++;

+ 1 - 1
src/main/resources/logback-test.xml Datei anzeigen

@@ -27,7 +27,7 @@
27 27
         <appender-ref ref="FILE_APPENDER"/>
28 28
     </appender>
29 29
 
30
-    <logger name="com.vcarecity" level="DEBUG" additivity="false">
30
+    <logger name="com.vcarecity" level="INFO" additivity="false">
31 31
         <appender-ref ref="STDOUT"/>
32 32
     </logger>
33 33