package cn.net.communion.dbdatasync.dbhelper.impl; import cn.net.communion.dbdatasync.dbhelper.DbHelper; import cn.net.communion.dbdatasync.entity.JobInfo; import org.apache.log4j.Logger; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; public class PostgreSql implements DbHelper { private Logger logger = Logger.getLogger(PostgreSql.class); @Override public String assembleSQL(String srcSql, Connection conn, JobInfo jobInfo) throws SQLException { String[] fields = jobInfo.getDestTableFields().split(","); String destTable = jobInfo.getDestTable(); PreparedStatement pst = conn.prepareStatement(srcSql); ResultSet rs = pst.executeQuery(); StringBuilder sql = new StringBuilder(); sql.append("INSERT INTO ").append(destTable).append(" (").append(jobInfo.getDestTableFields()).append(") VALUES "); long count = 0; while (rs.next()) { sql.append("("); for (int index = 0; index < fields.length; index++) { String fieldName = fields[index].trim(); String value = rs.getString(fieldName); if (value == null) { sql.append("NULL"); // 显式处理 NULL 值 } else if (isGeometryField(fieldName)) { // 处理几何类型字段,使用 ST_GeomFromText 函数 logger.debug("Processing geometry field: " + fieldName + " with value: " + value); sql.append(handleGeometryData(value)); } else { sql.append("'").append(value).append("'"); // 字符串值加引号 } if (index < fields.length - 1) { sql.append(", "); } } sql.append("),"); count++; } if (rs != null) { rs.close(); } if (pst != null) { pst.close(); } if (count > 0) { sql = new StringBuilder(sql.substring(0, sql.length() - 1)); // 删除最后一个逗号 return sql.toString(); } return null; } /** * 判断是否为几何类型字段 * * @param fieldName 字段名 * @return 是否为几何类型字段 */ private boolean isGeometryField(String fieldName) { // 常见的几何类型字段名 return fieldName.equalsIgnoreCase("geom") || fieldName.contains("geometry") || fieldName.contains("geom_"); } /** * 处理几何类型数据 * * @param value 几何数据值 * @return 处理后的几何数据 */ private String handleGeometryData(String value) { logger.debug("原始几何数据值: " + value); if (value == null || value.isEmpty()) { logger.debug("几何数据为空,返回 NULL"); return "NULL"; } // 尝试不同的几何数据格式处理 try { // 直接尝试使用 ST_GeomFromText 函数来转换几何数据 // 不再检查是否为标准的 WKT 格式,因为 MySQL 的 ST_AsText 函数已经保证返回标准的 WKT 格式 logger.debug("尝试使用 ST_GeomFromText 函数转换几何数据: " + value.substring(0, Math.min(value.length(), 50)) + "..."); return "ST_GeomFromText('" + value + "')"; } catch (Exception e) { logger.error("处理几何数据时出错: " + e.getMessage() + ", 原始值: " + value); return "NULL"; // 出错时返回 NULL } } @Override public void executeSQL(String sql, Connection conn) throws SQLException { logger.debug("Executing SQL: " + sql); try (PreparedStatement pst = conn.prepareStatement(sql)) { pst.execute(); conn.commit(); } } // 辅助方法:设置参数 private void setParameters(PreparedStatement pst, List params) throws SQLException { for (int i = 0; i < params.size(); i++) { pst.setObject(i + 1, params.get(i)); } } // 辅助方法:序列化 SQL 和参数 private String serializeSqlWithParams(List sqlStatements, List> paramLists) { StringBuilder result = new StringBuilder(); for (int i = 0; i < sqlStatements.size(); i++) { result.append(sqlStatements.get(i)).append("; "); } return result.toString(); } }