Browse Source

动态支持MySQL/Oracle

张泳健 5 years ago
parent
commit
e363fd42bf

+ 19 - 2
README.md View File

@@ -1,8 +1,25 @@
1
+# A
1 2
 
3
+## 打包
4
+```shell
5
+mvn clean compile package
6
+```
2 7
 
8
+## 使用
9
+```shell
10
+java -jar db-data-to-csv-1.0.0.jar -t=TABLE_NAME
11
+```
12
+参数说明:
13
+1. `-t=` / `--table=` 这两个指定导出的表名.
3 14
 
4 15
 
5
-````
16
+
17
+
18
+
19
+---
20
+
21
+
22
+```
6 23
 LOAD DATA INFILE '/var/lib/mysql-files/check_record_0006'
7 24
 INTO TABLE T_CHECK_RECORD_1
8 25
 FIELDS 
@@ -11,4 +28,4 @@ FIELDS
11 28
     ESCAPED BY '\\'
12 29
 LINES TERMINATED BY '\n'
13 30
 (CHECK_RECORD_ID,STAMP,USER_ID,CHECK_POINTS_ID,IS_NORMAL,IS_LATENT_DANGER,LATENT_DANGER_TYPE,LATENT_DANGER_DESC,UNDETECTED_NUM,LON,LAT,RULE_ID,IS_DEAL,STARTDATE,ENDDATE,VALID_CHECK,UPDATESTAMP);
14
-````
31
+```

config/application-dev.yml → config/application-mysql.yml View File

@@ -1,4 +1,6 @@
1 1
 database:
2 2
   url: jdbc:mysql:replication://192.168.10.210:6446,192.168.10.210:6447/fmmp?serverTimezone=Asia/Shanghai
3 3
   user: root
4
-  password: R00T@mysql
4
+  password: R00T@mysql
5
+export:
6
+  folder: ./

+ 6 - 0
config/application-oracle.yml View File

@@ -0,0 +1,6 @@
1
+database:
2
+  url: jdbc:oracle:thin:@192.168.10.236:1521:orcl
3
+  user: C##FMMP
4
+  password: vcare~1(^_^)
5
+export:
6
+  folder: ./

+ 2 - 1
config/application.yml View File

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

+ 147 - 12
pom.xml View File

@@ -7,20 +7,17 @@
7 7
     <groupId>com.vcarecity.csv</groupId>
8 8
     <artifactId>db-data-to-csv</artifactId>
9 9
     <version>1.0.0</version>
10
-    <build>
11
-        <plugins>
12
-            <plugin>
13
-                <groupId>org.apache.maven.plugins</groupId>
14
-                <artifactId>maven-compiler-plugin</artifactId>
15
-                <configuration>
16
-                    <source>8</source>
17
-                    <target>8</target>
18
-                </configuration>
19
-            </plugin>
20
-        </plugins>
21
-    </build>
22 10
 
23 11
 
12
+    <properties>
13
+        <sourceEncoding>UTF-8</sourceEncoding>
14
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
16
+        <compile.encoding>UTF-8</compile.encoding>
17
+        <compile.target>8</compile.target>
18
+        <compile.source>8</compile.source>
19
+    </properties>
20
+
24 21
     <dependencies>
25 22
 
26 23
         <dependency>
@@ -62,6 +59,13 @@
62 59
             <artifactId>HikariCP</artifactId>
63 60
             <version>3.4.1</version>
64 61
         </dependency>
62
+
63
+        <dependency>
64
+            <groupId>com.oracle</groupId>
65
+            <artifactId>ojdbc6</artifactId>
66
+            <version>12.1.0.2.0</version>
67
+        </dependency>
68
+
65 69
         <dependency>
66 70
             <groupId>com.google.inject</groupId>
67 71
             <artifactId>guice</artifactId>
@@ -91,6 +95,12 @@
91 95
         </dependency>
92 96
 
93 97
         <dependency>
98
+            <groupId>org.reflections</groupId>
99
+            <artifactId>reflections</artifactId>
100
+            <version>0.9.11</version>
101
+        </dependency>
102
+
103
+        <dependency>
94 104
             <groupId>org.apache.shardingsphere</groupId>
95 105
             <artifactId>sharding-jdbc-core</artifactId>
96 106
             <version>4.0.0-RC2</version>
@@ -103,4 +113,129 @@
103 113
 
104 114
     </dependencies>
105 115
 
116
+
117
+    <build>
118
+        <plugins>
119
+            <plugin>
120
+                <groupId>org.apache.maven.plugins</groupId>
121
+                <artifactId>maven-compiler-plugin</artifactId>
122
+                <version>3.8.0</version>
123
+                <configuration>
124
+                    <source>1.8</source>
125
+                    <target>1.8</target>
126
+                    <encoding>UTF-8</encoding>
127
+                </configuration>
128
+            </plugin>
129
+            <plugin>
130
+                <groupId>org.apache.maven.plugins</groupId>
131
+                <artifactId>maven-surefire-plugin</artifactId>
132
+                <version>2.22.0</version>
133
+                <configuration>
134
+                    <skipTests>true</skipTests>
135
+                </configuration>
136
+            </plugin>
137
+            <plugin>
138
+                <groupId>org.apache.maven.plugins</groupId>
139
+                <artifactId>maven-source-plugin</artifactId>
140
+                <version>3.0.1</version>
141
+                <executions>
142
+                    <execution>
143
+                        <id>attach-sources</id>
144
+                        <phase>verify</phase>
145
+                        <goals>
146
+                            <goal>jar-no-fork</goal>
147
+                        </goals>
148
+                    </execution>
149
+                </executions>
150
+            </plugin>
151
+
152
+            <plugin>
153
+                <artifactId>maven-resources-plugin</artifactId>
154
+                <version>3.1.0</version>
155
+
156
+                <configuration>
157
+                    <encoding>UTF-8</encoding>
158
+                </configuration>
159
+
160
+                <executions>
161
+                    <execution>
162
+                        <id>copy-resource-config</id>
163
+                        <phase>package</phase>
164
+                        <goals>
165
+                            <goal>copy-resources</goal>
166
+                        </goals>
167
+
168
+                        <configuration>
169
+                            <outputDirectory>${project.build.directory}/config</outputDirectory>
170
+                            <resources>
171
+                                <resource>
172
+                                    <directory>/config</directory>
173
+                                </resource>
174
+                            </resources>
175
+                        </configuration>
176
+                    </execution>
177
+
178
+                </executions>
179
+            </plugin>
180
+
181
+            <plugin>
182
+                <artifactId>maven-assembly-plugin</artifactId>
183
+                <version>3.1.0</version>
184
+                <configuration>
185
+                    <archive>
186
+                        <manifest>
187
+                            <mainClass>com.vcarecity.cvs.FileExporterApp</mainClass>
188
+                        </manifest>
189
+                    </archive>
190
+                    <descriptorRefs>
191
+                        <descriptorRef>jar-with-dependencies</descriptorRef>
192
+                    </descriptorRefs>
193
+                </configuration>
194
+                <executions>
195
+                    <execution>
196
+                        <id>make-assembly</id>
197
+                        <phase>package</phase>
198
+                        <goals>
199
+                            <goal>single</goal>
200
+                        </goals>
201
+                    </execution>
202
+                </executions>
203
+            </plugin>
204
+
205
+            <plugin>
206
+                <groupId>org.apache.maven.plugins</groupId>
207
+                <artifactId>maven-jar-plugin</artifactId>
208
+                <version>3.1.0</version>
209
+                <configuration>
210
+                    <archive>
211
+                        <manifest>
212
+                            <addClasspath>true</addClasspath>
213
+                            <classpathPrefix>lib/</classpathPrefix>
214
+                            <mainClass>com.vcarecity.cvs.FileExporterApp</mainClass>
215
+                        </manifest>
216
+                    </archive>
217
+                </configuration>
218
+            </plugin>
219
+
220
+
221
+            <plugin>
222
+                <groupId>org.apache.maven.plugins</groupId>
223
+                <artifactId>maven-dependency-plugin</artifactId>
224
+                <version>3.1.1</version>
225
+                <executions>
226
+
227
+                    <execution>
228
+                        <id>copy-dependencies</id>
229
+                        <phase>package</phase>
230
+                        <goals>
231
+                            <goal>copy-dependencies</goal>
232
+                        </goals>
233
+                        <configuration>
234
+                            <outputDirectory>${project.build.directory}/lib</outputDirectory>
235
+                        </configuration>
236
+                    </execution>
237
+                </executions>
238
+            </plugin>
239
+        </plugins>
240
+    </build>
106 241
 </project>

+ 72 - 0
src/main/java/com/vcarecity/cvs/FileExporterApp.java View File

@@ -0,0 +1,72 @@
1
+package com.vcarecity.cvs;
2
+
3
+import com.google.inject.Guice;
4
+import com.google.inject.Injector;
5
+import com.vcarecity.cvs.core.ReflectionUtil;
6
+import com.vcarecity.cvs.module.PropertiesModule;
7
+import com.vcarecity.cvs.module.SQLModule;
8
+import com.vcarecity.cvs.properties.AppProperties;
9
+import com.vcarecity.cvs.properties.DbProperties;
10
+import com.vcarecity.cvs.starter.SQLStarter;
11
+import me.yuxiaoyao.config.loader.ConfigLoader;
12
+
13
+/**
14
+ * @author Kerry on 19/11/27
15
+ */
16
+
17
+public class FileExporterApp {
18
+
19
+    public static Injector injector;
20
+
21
+
22
+    public static void main(String[] args) throws Exception {
23
+
24
+        ReflectionUtil.initTableClassMapper("com.vcarecity.cvs.entity");
25
+
26
+        AppProperties appProperties = ConfigLoader.parseConfig(args, AppProperties.class, null);
27
+        jdbcArgs(args, appProperties);
28
+
29
+        String table = getTableByArgs(args);
30
+        if (table == null || table.length() == 0) {
31
+            throw new Error("table name must not be null or empty!");
32
+        }
33
+        Class<?> tableClass = ReflectionUtil.getTableClass(table);
34
+
35
+        String basePath = table;
36
+        final AppProperties.Export export = appProperties.getExport();
37
+        if (export != null) {
38
+            basePath = export.getFolder() + table;
39
+        }
40
+
41
+        injector = Guice.createInjector(new PropertiesModule(appProperties), new SQLModule());
42
+
43
+        final SQLStarter instance = injector.getInstance(SQLStarter.class);
44
+        instance.exportData(table, basePath, tableClass);
45
+    }
46
+
47
+    private static String getTableByArgs(String[] args) {
48
+        for (String arg : args) {
49
+            if (arg.startsWith("--table=")) {
50
+                return arg.substring("--table=".length()).trim();
51
+            } else if (arg.startsWith("-t=")) {
52
+                return arg.substring("-t=".length()).trim();
53
+            }
54
+        }
55
+        return null;
56
+    }
57
+
58
+
59
+    private static void jdbcArgs(String[] args, AppProperties properties) {
60
+        final DbProperties database = properties.getDatabase();
61
+        for (String arg : args) {
62
+            if (arg.startsWith("jdbc.url=")) {
63
+                database.setUrl(arg.substring("jdbc.url=".length()).trim());
64
+            } else if (arg.startsWith("jdbc.user=")) {
65
+                database.setUser(arg.substring("jdbc.user=".length()).trim());
66
+            } else if (arg.startsWith("jdbc.password=")) {
67
+                database.setPassword(arg.substring("jdbc.password=".length()).trim());
68
+            }
69
+        }
70
+        properties.setDatabase(database);
71
+    }
72
+}

+ 0 - 32
src/main/java/com/vcarecity/cvs/MySQLCSVWriter.java View File

@@ -1,32 +0,0 @@
1
-package com.vcarecity.cvs;
2
-
3
-import com.google.inject.Guice;
4
-import com.google.inject.Injector;
5
-import com.vcarecity.cvs.module.MySQLModule;
6
-import com.vcarecity.cvs.module.PropertiesModule;
7
-import com.vcarecity.cvs.properties.AppProperties;
8
-import me.yuxiaoyao.config.loader.ConfigLoader;
9
-import org.slf4j.Logger;
10
-import org.slf4j.LoggerFactory;
11
-
12
-/**
13
- * @author Kerry on 19/11/20
14
- */
15
-
16
-public class MySQLCSVWriter {
17
-    private static Logger logger = LoggerFactory.getLogger(MySQLCSVWriter.class);
18
-    public static Injector injector;
19
-
20
-    public static void main(String[] args) throws Exception {
21
-        final AppProperties appProperties = ConfigLoader.parseConfig(args, AppProperties.class, null);
22
-        injector = Guice.createInjector(new PropertiesModule(appProperties), new MySQLModule());
23
-
24
-        //final TestInsertData testInsertData = injector.getInstance(TestInsertData.class);
25
-        //testInsertData.ins();
26
-
27
-        final MySQLStarter instance = injector.getInstance(MySQLStarter.class);
28
-        instance.run();
29
-
30
-
31
-    }
32
-}

+ 15 - 0
src/main/java/com/vcarecity/cvs/annotation/Tables.java View File

@@ -0,0 +1,15 @@
1
+package com.vcarecity.cvs.annotation;
2
+
3
+import java.lang.annotation.ElementType;
4
+import java.lang.annotation.Retention;
5
+import java.lang.annotation.RetentionPolicy;
6
+import java.lang.annotation.Target;
7
+
8
+/**
9
+ * @author Kerry on 19/11/27
10
+ */
11
+@Target({ElementType.TYPE})
12
+@Retention(RetentionPolicy.RUNTIME)
13
+public @interface Tables {
14
+    String[] value();
15
+}

+ 49 - 3
src/main/java/com/vcarecity/cvs/core/ReflectionUtil.java View File

@@ -1,11 +1,13 @@
1 1
 package com.vcarecity.cvs.core;
2 2
 
3
+import com.vcarecity.cvs.annotation.Tables;
4
+import org.reflections.Reflections;
5
+
3 6
 import javax.persistence.Column;
7
+import javax.persistence.Table;
4 8
 import javax.persistence.Transient;
5 9
 import java.lang.reflect.Field;
6
-import java.util.ArrayList;
7
-import java.util.List;
8
-import java.util.Map;
10
+import java.util.*;
9 11
 import java.util.concurrent.ConcurrentHashMap;
10 12
 
11 13
 /**
@@ -48,4 +50,48 @@ public class ReflectionUtil {
48 50
         }
49 51
     }
50 52
 
53
+    private static Map<String, Class<?>> classMap = new HashMap<>();
54
+
55
+    public static void initTableClassMapper(String... pkgs) {
56
+
57
+        Map<String, Class<?>> tableMap = new HashMap<>();
58
+        Map<String, Class<?>> tablesMap = new HashMap<>();
59
+
60
+        for (String pkg : pkgs) {
61
+            Reflections reflections = new Reflections(pkg);
62
+
63
+            Set<Class<?>> classSet = reflections.getTypesAnnotatedWith(Table.class);
64
+            for (Class<?> cls : classSet) {
65
+                final Table table = cls.getAnnotation(Table.class);
66
+                final String name = table.name();
67
+                if (tableMap.containsKey(name)) {
68
+                    throw new RuntimeException("tableName= " + name + " has more Class.[" + tableMap.get(name) + "," + cls + "]");
69
+                }
70
+                tableMap.put(name, cls);
71
+            }
72
+
73
+            Set<Class<?>> tablesSet = reflections.getTypesAnnotatedWith(Tables.class);
74
+            for (Class<?> cls : tablesSet) {
75
+                final Tables tables = cls.getAnnotation(Tables.class);
76
+                final String[] value = tables.value();
77
+                for (String name : value) {
78
+                    if (tablesMap.containsKey(name)) {
79
+                        throw new RuntimeException("tableName= " + name + " has more Class.[" + tablesMap.get(name) + "," + cls + "]");
80
+                    }
81
+                    tablesMap.put(name, cls);
82
+                }
83
+            }
84
+        }
85
+
86
+        classMap.putAll(tableMap);
87
+        classMap.putAll(tablesMap);
88
+
89
+    }
90
+
91
+
92
+    @SuppressWarnings("unchecked")
93
+    public static <T> Class<T> getTableClass(String table) {
94
+        return (Class<T>) classMap.get(table);
95
+    }
96
+
51 97
 }

+ 4 - 0
src/main/java/com/vcarecity/cvs/entity/CheckRecordEntity.java View File

@@ -1,8 +1,10 @@
1 1
 package com.vcarecity.cvs.entity;
2 2
 
3
+import com.vcarecity.cvs.annotation.Tables;
3 4
 import lombok.Data;
4 5
 
5 6
 import javax.persistence.Column;
7
+import javax.persistence.Table;
6 8
 import java.sql.Timestamp;
7 9
 
8 10
 
@@ -10,6 +12,8 @@ import java.sql.Timestamp;
10 12
  * @author Kerry on 19/11/21
11 13
  */
12 14
 
15
+@Tables({"T_CHECK_RECORD", "T_CHECK_RECORD_1"})
16
+@Table(name = "T_CHECK_RECORD")
13 17
 @Data
14 18
 public class CheckRecordEntity {
15 19
 

src/main/java/com/vcarecity/cvs/module/MySQLModule.java → src/main/java/com/vcarecity/cvs/module/SQLModule.java View File

@@ -12,6 +12,7 @@ import com.vcarecity.cvs.service.ResultHandlerService;
12 12
 import com.vcarecity.cvs.service.SQLQueryService;
13 13
 import com.vcarecity.cvs.service.impl.CSVResultHandlerServiceImpl;
14 14
 import com.vcarecity.cvs.service.impl.MySQLQueryServiceImpl;
15
+import com.vcarecity.cvs.service.impl.OracleQueryServiceImpl;
15 16
 import com.zaxxer.hikari.HikariConfig;
16 17
 import com.zaxxer.hikari.HikariDataSource;
17 18
 
@@ -19,10 +20,9 @@ import com.zaxxer.hikari.HikariDataSource;
19 20
  * @author Kerry on 19/11/20
20 21
  */
21 22
 
22
-public class MySQLModule extends AbstractModule {
23
+public class SQLModule extends AbstractModule {
23 24
     @Override
24 25
     protected void configure() {
25
-        bind(SQLQueryService.class).to(MySQLQueryServiceImpl.class);
26 26
 
27 27
         install(new FactoryModuleBuilder()
28 28
                 .implement(ResultHandlerService.class, CSVResultHandlerServiceImpl.class)
@@ -30,6 +30,19 @@ public class MySQLModule extends AbstractModule {
30 30
 
31 31
     }
32 32
 
33
+
34
+    @Inject
35
+    @Provides
36
+    public SQLQueryService sqlQueryService(HikariDataSource dataSource) {
37
+        final String url = dataSource.getJdbcUrl();
38
+        if (url.startsWith("jdbc:mysql")) {
39
+            return new MySQLQueryServiceImpl(dataSource);
40
+        } else if (url.startsWith("jdbc:oracle")) {
41
+            return new OracleQueryServiceImpl(dataSource);
42
+        }
43
+        throw new Error("not support this jdbc driver class = " + dataSource.getDriverClassName());
44
+    }
45
+
33 46
     @Provides
34 47
     @Singleton
35 48
     @Inject
@@ -41,6 +54,7 @@ public class MySQLModule extends AbstractModule {
41 54
         config.setJdbcUrl(database.getUrl());
42 55
         config.setUsername(database.getUser());
43 56
         config.setPassword(database.getPassword());
57
+
44 58
         config.addDataSourceProperty("cachePrepStmts", "true");
45 59
         config.addDataSourceProperty("prepStmtCacheSize", "250");
46 60
         config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");

+ 6 - 0
src/main/java/com/vcarecity/cvs/properties/AppProperties.java View File

@@ -9,4 +9,10 @@ import lombok.Data;
9 9
 @Data
10 10
 public class AppProperties {
11 11
     private DbProperties database;
12
+    private Export export;
13
+
14
+    @Data
15
+    public static class Export {
16
+        private String folder;
17
+    }
12 18
 }

+ 4 - 5
src/main/java/com/vcarecity/cvs/service/SQLQueryService.java View File

@@ -13,15 +13,14 @@ public interface SQLQueryService {
13 13
     /**
14 14
      * query by page
15 15
      *
16
-     * @param sql
17
-     * @param start
18
-     * @param pageCount
16
+     * @param table
17
+     * @param page      页面
18
+     * @param pageCount 一页的数量
19 19
      * @param clazz
20 20
      * @param <T>
21 21
      * @return
22 22
      * @throws SQLException
23 23
      */
24
-    <T> List<T> queryByPage(String sql, int start, int pageCount, Class<T> clazz) throws SQLException;
25
-
24
+    <T> List<T> queryByPage(String table, int page, int pageCount, Class<T> clazz) throws SQLException;
26 25
 
27 26
 }

+ 122 - 0
src/main/java/com/vcarecity/cvs/service/impl/AbstractSQLQueryService.java View File

@@ -0,0 +1,122 @@
1
+package com.vcarecity.cvs.service.impl;
2
+
3
+import com.vcarecity.cvs.core.AutoMapper;
4
+import com.vcarecity.cvs.service.SQLQueryService;
5
+import com.zaxxer.hikari.HikariDataSource;
6
+import lombok.extern.slf4j.Slf4j;
7
+
8
+import java.sql.*;
9
+import java.util.ArrayList;
10
+import java.util.List;
11
+
12
+/**
13
+ * @author Kerry on 19/11/27
14
+ */
15
+
16
+@Slf4j
17
+public abstract class AbstractSQLQueryService implements SQLQueryService {
18
+
19
+    protected final HikariDataSource dataSource;
20
+
21
+    protected AbstractSQLQueryService(HikariDataSource dataSource) {
22
+        this.dataSource = dataSource;
23
+    }
24
+
25
+    @Override
26
+    public <T> List<T> queryByPage(String table, int page, int pageCount, Class<T> clazz) throws SQLException {
27
+
28
+        final String querySql = getQuerySql(table);
29
+
30
+        long startTime = System.currentTimeMillis();
31
+
32
+
33
+        final Connection connection = dataSource.getConnection();
34
+
35
+        final PreparedStatement preparedStatement = getPreparedStatement(connection, querySql, page, pageCount);
36
+
37
+        ResultSet resultSet = preparedStatement.executeQuery();
38
+
39
+        List<T> list = resultMapper(resultSet, clazz);
40
+
41
+        logger.debug("query success. size = {}. usageTime = {} /ms", list.size(), (System.currentTimeMillis() - startTime));
42
+
43
+        resultSet.close();
44
+        preparedStatement.close();
45
+        connection.close();
46
+
47
+        return list;
48
+    }
49
+
50
+    /**
51
+     * 组装表
52
+     *
53
+     * @param table
54
+     * @return
55
+     */
56
+    protected abstract String getQuerySql(String table);
57
+
58
+    /**
59
+     * get PreparedStatement
60
+     *
61
+     * @param connection
62
+     * @param sql
63
+     * @param start
64
+     * @param pageCount
65
+     * @return
66
+     * @throws SQLException
67
+     */
68
+    protected abstract PreparedStatement getPreparedStatement(Connection connection, String sql, int start, int pageCount) throws SQLException;
69
+
70
+    public <T> List<T> resultMapper(ResultSet resultSet, Class<T> clazz) throws SQLException {
71
+        if (clazz == Object.class) {
72
+            //noinspection unchecked
73
+            return (List<T>) resultSetToObject(resultSet);
74
+        }
75
+        return autoMapper(resultSet, clazz);
76
+    }
77
+
78
+    public List<Object[]> resultSetToObject(ResultSet resultSet) throws SQLException {
79
+        final ResultSetMetaData metaData = resultSet.getMetaData();
80
+        final int columnCount = metaData.getColumnCount() - 1;
81
+
82
+
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
+        }
94
+
95
+        logger.info("header = ({})", String.join(",", header));
96
+
97
+        List<Object[]> data = new ArrayList<>();
98
+        while (resultSet.next()) {
99
+            Object[] objects = new Object[columnCount];
100
+            int cIndex = 0;
101
+            for (int i = 0; i < columnCount; i++) {
102
+                if (i == skipRnIndex) {
103
+                    continue;
104
+                }
105
+                objects[cIndex++] = resultSet.getObject(i + 1);
106
+            }
107
+            data.add(objects);
108
+        }
109
+        return data;
110
+    }
111
+
112
+    public <T> List<T> autoMapper(ResultSet resultSet, Class<T> clazz) throws SQLException {
113
+        List<T> list = new ArrayList<>();
114
+        while (resultSet.next()) {
115
+            final T t = AutoMapper.autoMapper(resultSet, clazz);
116
+            if (t != null) {
117
+                list.add(t);
118
+            }
119
+        }
120
+        return list;
121
+    }
122
+}

+ 14 - 11
src/main/java/com/vcarecity/cvs/service/impl/CSVResultHandlerServiceImpl.java View File

@@ -54,7 +54,7 @@ public class CSVResultHandlerServiceImpl implements ResultHandlerService {
54 54
     private File getFile() {
55 55
         final int index = fileNameIndex;
56 56
         fileNameIndex++;
57
-        return new File(filePattern + index + ".csv");
57
+        return new File(filePattern + "-" + +index + ".csv");
58 58
     }
59 59
 
60 60
 
@@ -87,13 +87,14 @@ public class CSVResultHandlerServiceImpl implements ResultHandlerService {
87 87
 
88 88
         for (T t : dataList) {
89 89
             Object[] row;
90
-            if (cls.isArray()) {
91
-                // array
90
+
91
+            if (t.getClass().isArray()) {
92 92
                 row = (Object[]) t;
93
-            } else if (List.class.isAssignableFrom(cls)) {
93
+            } else if (List.class.isAssignableFrom(t.getClass())) {
94 94
                 // noinspection rawtypes
95 95
                 row = ((List) t).toArray();
96 96
             } else {
97
+                // auto mapper
97 98
                 row = resultMapper(t, cls);
98 99
             }
99 100
             Object[] handlerRow = toCsvContent(row);
@@ -103,13 +104,15 @@ public class CSVResultHandlerServiceImpl implements ResultHandlerService {
103 104
 
104 105
         counter += dataList.size();
105 106
 
106
-
107
-        // 输出Header
108
-        final List<JavaMapColumn> fieldColumnList = ReflectionUtil.getFieldColumnList(cls);
109
-        final List<String> collect = fieldColumnList.stream().map(JavaMapColumn::getColumn).collect(Collectors.toList());
110
-        final String join = String.join(",", collect.toArray(new String[]{}));
111
-
112
-        logger.debug("write to csv file usage time {} /ms. header = ({})", (System.currentTimeMillis() - startTime), join);
107
+        if (cls != Object.class) {
108
+            // 输出Header
109
+            final List<JavaMapColumn> fieldColumnList = ReflectionUtil.getFieldColumnList(cls);
110
+            final List<String> collect = fieldColumnList.stream().map(JavaMapColumn::getColumn).collect(Collectors.toList());
111
+            final String join = String.join(",", collect.toArray(new String[]{}));
112
+            logger.debug("write to csv file usage time {} /ms. header = ({})", (System.currentTimeMillis() - startTime), join);
113
+        } else {
114
+            logger.debug("write to csv file usage time {} /ms. ", (System.currentTimeMillis() - startTime));
115
+        }
113 116
     }
114 117
 
115 118
 

+ 14 - 29
src/main/java/com/vcarecity/cvs/service/impl/MySQLQueryServiceImpl.java View File

@@ -1,17 +1,12 @@
1 1
 package com.vcarecity.cvs.service.impl;
2 2
 
3 3
 import com.google.inject.Inject;
4
-import com.vcarecity.cvs.core.AutoMapper;
5
-import com.vcarecity.cvs.service.SQLQueryService;
6 4
 import com.zaxxer.hikari.HikariDataSource;
7 5
 import lombok.extern.slf4j.Slf4j;
8 6
 
9 7
 import java.sql.Connection;
10 8
 import java.sql.PreparedStatement;
11
-import java.sql.ResultSet;
12 9
 import java.sql.SQLException;
13
-import java.util.ArrayList;
14
-import java.util.List;
15 10
 
16 11
 /**
17 12
  * @author Kerry on 19/11/21
@@ -19,38 +14,28 @@ import java.util.List;
19 14
 
20 15
 
21 16
 @Slf4j
22
-public class MySQLQueryServiceImpl implements SQLQueryService {
23
-    private final HikariDataSource dataSource;
17
+public class MySQLQueryServiceImpl extends AbstractSQLQueryService {
18
+
19
+    private static final String PAGE_SQL = "select * from %s limit ?,?";
24 20
 
25 21
     @Inject
26 22
     public MySQLQueryServiceImpl(HikariDataSource dataSource) {
27
-        this.dataSource = dataSource;
23
+        super(dataSource);
28 24
     }
29 25
 
30 26
     @Override
31
-    public <T> List<T> queryByPage(String sql, int start, int pageCount, Class<T> clazz) throws SQLException {
32
-        final Connection connection = dataSource.getConnection();
33
-        final PreparedStatement preparedStatement = connection.prepareStatement(sql);
34
-        preparedStatement.setInt(1, start);
35
-        preparedStatement.setInt(2, pageCount);
36
-
37
-        List<T> list = new ArrayList<>(pageCount);
38
-        long startTime = System.currentTimeMillis();
39
-
40
-        logger.debug("start query: {},{},{}.start on = {}", sql, start, pageCount, startTime);
27
+    protected String getQuerySql(String table) {
28
+        return String.format(PAGE_SQL, table);
29
+    }
41 30
 
42
-        final ResultSet resultSet = preparedStatement.executeQuery();
43
-        while (resultSet.next()) {
44
-            // mapper
45
-            final T t = AutoMapper.autoMapper(resultSet, clazz);
46
-            if (t != null) {
47
-                list.add(t);
48
-            }
49
-        }
31
+    @Override
32
+    protected PreparedStatement getPreparedStatement(Connection connection, String sql, int page, int pageCount) throws SQLException {
50 33
 
51
-        logger.debug("start query: {},{},{}.usageTime= {}", sql, start, pageCount, (System.currentTimeMillis() - startTime));
52
-        connection.close();
34
+        logger.debug("start query: [{}]. pageInfo = {}/{}. time = {}", sql, page * pageCount, pageCount, System.currentTimeMillis());
53 35
 
54
-        return list;
36
+        final PreparedStatement preparedStatement = connection.prepareStatement(sql);
37
+        preparedStatement.setInt(1, page * pageCount);
38
+        preparedStatement.setInt(2, pageCount);
39
+        return preparedStatement;
55 40
     }
56 41
 }

+ 17 - 32
src/main/java/com/vcarecity/cvs/service/impl/OracleQueryServiceImpl.java View File

@@ -1,55 +1,40 @@
1 1
 package com.vcarecity.cvs.service.impl;
2 2
 
3 3
 import com.google.inject.Inject;
4
-import com.vcarecity.cvs.core.AutoMapper;
5
-import com.vcarecity.cvs.service.SQLQueryService;
6 4
 import com.zaxxer.hikari.HikariDataSource;
7 5
 import lombok.extern.slf4j.Slf4j;
8 6
 
9 7
 import java.sql.Connection;
10 8
 import java.sql.PreparedStatement;
11
-import java.sql.ResultSet;
12 9
 import java.sql.SQLException;
13
-import java.util.ArrayList;
14
-import java.util.List;
15 10
 
16 11
 /**
17 12
  * @author Kerry on 19/11/25
18 13
  */
19 14
 
20 15
 @Slf4j
21
-public class OracleQueryServiceImpl implements SQLQueryService {
22
-    private final HikariDataSource dataSource;
16
+public class OracleQueryServiceImpl extends AbstractSQLQueryService {
17
+
18
+    private static final String PAGE_SQL = "select * from (select ROWNUM as RN, T.* from %s T where ROWNUM <= ?) A where A.RN > ?";
23 19
 
24 20
     @Inject
25 21
     public OracleQueryServiceImpl(HikariDataSource dataSource) {
26
-        this.dataSource = dataSource;
22
+        super(dataSource);
23
+    }
24
+
25
+    @Override
26
+    protected String getQuerySql(String table) {
27
+        return String.format(PAGE_SQL, table);
27 28
     }
28 29
 
29 30
     @Override
30
-    public <T> List<T> queryByPage(String sql, int start, int pageCount, Class<T> clazz) throws SQLException {
31
-        final Connection connection = dataSource.getConnection();
32
-        final PreparedStatement preparedStatement = connection.prepareStatement(sql);
33
-        preparedStatement.setInt(1, start);
34
-        preparedStatement.setInt(2, pageCount);
35
-
36
-        List<T> list = new ArrayList<>(pageCount);
37
-        long startTime = System.currentTimeMillis();
38
-
39
-        logger.debug("start query: {},{},{}.start on = {}", sql, start, pageCount, startTime);
40
-
41
-        final ResultSet resultSet = preparedStatement.executeQuery();
42
-        while (resultSet.next()) {
43
-            // mapper
44
-            final T t = AutoMapper.autoMapper(resultSet, clazz);
45
-            if (t != null) {
46
-                list.add(t);
47
-            }
48
-        }
49
-
50
-        logger.debug("start query: {},{},{}.usageTime= {}", sql, start, pageCount, (System.currentTimeMillis() - startTime));
51
-        connection.close();
52
-
53
-        return list;
31
+    protected PreparedStatement getPreparedStatement(Connection connection, String sql, int page, int pageCount) throws SQLException {
32
+
33
+        logger.debug("start query: [{}]. pageInfo = {}/{}. time = {}", sql, (1 + page) * pageCount, page * pageCount, System.currentTimeMillis());
34
+
35
+        PreparedStatement preparedStatement = connection.prepareStatement(sql);
36
+        preparedStatement.setInt(1, page * pageCount);
37
+        preparedStatement.setInt(2, (page - 1) * pageCount);
38
+        return preparedStatement;
54 39
     }
55 40
 }

src/main/java/com/vcarecity/cvs/MySQLStarter.java → src/main/java/com/vcarecity/cvs/starter/SQLStarter.java View File

@@ -1,8 +1,6 @@
1
-package com.vcarecity.cvs;
1
+package com.vcarecity.cvs.starter;
2 2
 
3
-import com.vcarecity.cvs.entity.CheckRecordEntity;
4 3
 import com.vcarecity.cvs.factory.ResultHandlerFactory;
5
-import com.vcarecity.cvs.properties.AppProperties;
6 4
 import com.vcarecity.cvs.service.ResultHandlerService;
7 5
 import com.vcarecity.cvs.service.SQLQueryService;
8 6
 import com.vcarecity.cvs.service.impl.CSVResultHandlerServiceImpl;
@@ -16,49 +14,59 @@ import java.util.List;
16 14
  */
17 15
 
18 16
 @Slf4j
19
-public class MySQLStarter {
20
-    private final AppProperties properties;
17
+public class SQLStarter {
18
+
19
+    private static final int PAGE_COUNT = 10000;
20
+
21
+    private int pageCount = PAGE_COUNT;
22
+
21 23
     private final SQLQueryService queryService;
22 24
     private final ResultHandlerFactory resultHandlerFactory;
23 25
 
24 26
     @Inject
25
-    public MySQLStarter(AppProperties properties,
26
-                        SQLQueryService queryService,
27
-                        ResultHandlerFactory resultHandlerFactory) {
28
-
29
-        this.properties = properties;
27
+    public SQLStarter(SQLQueryService queryService,
28
+                      ResultHandlerFactory resultHandlerFactory) {
30 29
         this.queryService = queryService;
31 30
         this.resultHandlerFactory = resultHandlerFactory;
31
+    }
32 32
 
33
+    public void setPageCount(int pageCount) {
34
+        this.pageCount = pageCount;
33 35
     }
34 36
 
35
-    static final int PAGE_COUNT = 10000;
37
+    /**
38
+     * 导出数据
39
+     *
40
+     * @param table
41
+     * @param properties
42
+     * @throws Exception
43
+     */
44
+    public <T> void exportData(String table, String properties, Class<T> cls) throws Exception {
45
+
46
+        if (cls == null) {
47
+            //noinspection unchecked
48
+            cls = (Class<T>) Object.class;
49
+        }
50
+        ResultHandlerService resultHandler = resultHandlerFactory.createResultHandler(properties);
36 51
 
37
-    public void run() throws Exception {
38 52
 
39
-        logger.info("start query database...");
53
+        logger.info("start query database table = {}, file = {}, class = {}", table, properties, cls);
40 54
 
41 55
         long startTime = System.currentTimeMillis();
42 56
 
43
-
44
-        String sql = "select * from T_CHECK_RECORD limit ?,?";
45
-        // sql = "SELECT * FROM websites  limit ?,?";
46
-
47
-        String properties = "check_record.csv";
48
-
49 57
         int count = 0;
50 58
         int currentSize;
51 59
 
52
-
53
-        ResultHandlerService resultHandler = resultHandlerFactory.createResultHandler(properties);
60
+        int page = 1;
54 61
 
55 62
         do {
56
-            List<CheckRecordEntity> result = queryService.queryByPage(sql, count, PAGE_COUNT, CheckRecordEntity.class);
57
-            resultHandler.resultHandler(result, CheckRecordEntity.class);
63
+            List<T> result = queryService.queryByPage(table, page, this.pageCount, cls);
64
+            resultHandler.resultHandler(result, cls);
58 65
             currentSize = result.size();
59 66
             count += currentSize;
67
+            page++;
60 68
 
61
-        } while (currentSize == PAGE_COUNT);
69
+        } while (currentSize == this.pageCount);
62 70
 
63 71
         if (resultHandler instanceof CSVResultHandlerServiceImpl) {
64 72
             ((CSVResultHandlerServiceImpl) resultHandler).close();