|
|
@@ -1,7 +1,10 @@
|
|
|
package com.siwei.apply.utils;
|
|
|
|
|
|
+import com.healthmarketscience.jackcess.Database;
|
|
|
+import com.healthmarketscience.jackcess.DatabaseBuilder;
|
|
|
import com.siwei.common.core.utils.StringUtils;
|
|
|
|
|
|
+import java.io.File;
|
|
|
import java.sql.*;
|
|
|
import java.util.*;
|
|
|
|
|
|
@@ -11,6 +14,115 @@ import java.util.*;
|
|
|
public class MdbUtil {
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
+ * 创建或打开 MDB 文件并写入数据
|
|
|
+ *
|
|
|
+ * @param mdbPath mdb文件地址
|
|
|
+ * @param tableName 表名
|
|
|
+ * @param columns 字段及类型列表
|
|
|
+ * @param dataList 数据列表
|
|
|
+ */
|
|
|
+ public static void writeMdbByTable(String mdbPath, String tableName, List<Map<String, String>> columns, List<Map<String, Object>> dataList) throws Exception {
|
|
|
+ File mdbFile = new File(mdbPath);
|
|
|
+ if (!mdbFile.exists()) {
|
|
|
+ // 创建父目录
|
|
|
+ File parentFile = mdbFile.getParentFile();
|
|
|
+ if (parentFile != null && !parentFile.exists()) {
|
|
|
+ parentFile.mkdirs();
|
|
|
+ }
|
|
|
+ // 创建新的 MDB 文件 (V2000 格式)
|
|
|
+ DatabaseBuilder.create(Database.FileFormat.V2000, mdbFile);
|
|
|
+ }
|
|
|
+
|
|
|
+ Properties prop = new Properties();
|
|
|
+ prop.put("charSet", "UTF-8");
|
|
|
+ String dbUrl = "jdbc:ucanaccess://" + mdbPath;
|
|
|
+
|
|
|
+ Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
|
|
|
+
|
|
|
+ try (Connection conn = DriverManager.getConnection(dbUrl, prop)) {
|
|
|
+ // 1. 检查表是否存在,如果不存在则创建
|
|
|
+ DatabaseMetaData metaData = conn.getMetaData();
|
|
|
+ try (ResultSet tables = metaData.getTables(null, null, tableName, new String[]{"TABLE"})) {
|
|
|
+ if (!tables.next()) {
|
|
|
+ StringBuilder createSql = new StringBuilder("CREATE TABLE ").append(tableName).append(" (");
|
|
|
+ for (int i = 0; i < columns.size(); i++) {
|
|
|
+ Map<String, String> col = columns.get(i);
|
|
|
+ String colName = col.get("column_name");
|
|
|
+ String dataType = col.get("data_type");
|
|
|
+
|
|
|
+ createSql.append("[").append(colName).append("] ");
|
|
|
+ createSql.append(mapPostgresToMdbType(dataType));
|
|
|
+
|
|
|
+ if (i < columns.size() - 1) {
|
|
|
+ createSql.append(", ");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ createSql.append(")");
|
|
|
+ try (Statement stmt = conn.createStatement()) {
|
|
|
+ stmt.executeUpdate(createSql.toString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 插入数据
|
|
|
+ if (dataList != null && !dataList.isEmpty()) {
|
|
|
+ StringBuilder insertSql = new StringBuilder("INSERT INTO ").append(tableName).append(" (");
|
|
|
+ StringBuilder valuesPlaceholder = new StringBuilder();
|
|
|
+
|
|
|
+ List<String> colNames = new ArrayList<>();
|
|
|
+ for (int i = 0; i < columns.size(); i++) {
|
|
|
+ String colName = columns.get(i).get("column_name");
|
|
|
+ colNames.add(colName);
|
|
|
+ insertSql.append("[").append(colName).append("]");
|
|
|
+ valuesPlaceholder.append("?");
|
|
|
+ if (i < columns.size() - 1) {
|
|
|
+ insertSql.append(", ");
|
|
|
+ valuesPlaceholder.append(", ");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ insertSql.append(") VALUES (").append(valuesPlaceholder).append(")");
|
|
|
+
|
|
|
+ try (PreparedStatement pstmt = conn.prepareStatement(insertSql.toString())) {
|
|
|
+ for (Map<String, Object> row : dataList) {
|
|
|
+ for (int i = 0; i < colNames.size(); i++) {
|
|
|
+ Object value = row.get(colNames.get(i));
|
|
|
+ // 处理特殊类型,如 geometry 存为文本
|
|
|
+ if (value != null && value.toString().contains("SRID")) {
|
|
|
+ pstmt.setObject(i + 1, value.toString());
|
|
|
+ } else {
|
|
|
+ if(Objects.isNull(value)){
|
|
|
+ value="";
|
|
|
+ }
|
|
|
+ pstmt.setObject(i + 1, value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ pstmt.addBatch();
|
|
|
+ }
|
|
|
+ pstmt.executeBatch();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String mapPostgresToMdbType(String pgType) {
|
|
|
+ if (pgType == null) return "TEXT(255)";
|
|
|
+ pgType = pgType.toLowerCase();
|
|
|
+ if (pgType.contains("char") || pgType.contains("text")) {
|
|
|
+ return "TEXT(255)";
|
|
|
+ } else if (pgType.contains("int")) {
|
|
|
+ return "INTEGER";
|
|
|
+ } else if (pgType.contains("numeric") || pgType.contains("decimal") || pgType.contains("double") || pgType.contains("float")) {
|
|
|
+ return "DOUBLE";
|
|
|
+ } else if (pgType.contains("date") || pgType.contains("time")) {
|
|
|
+ return "DATETIME";
|
|
|
+ } else if (pgType.contains("geometry")) {
|
|
|
+ return "MEMO"; // 空间数据存为长文本
|
|
|
+ }
|
|
|
+ return "TEXT(255)";
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
/**
|
|
|
* 读取.mdb文件下面的所有表名
|
|
|
*
|