从InputStream中读取指定表列表的所有INSERT语句。 @param inputStream SQL文件的输入流。 @param tableNames 目标表的名称列表。目标表的名称列表(例如:["frontendapi", "frontendsettings"])。 @return 包含所有匹配的完整INSERT语句的列表。
(InputStream inputStream, List<String> tableNames)
| 114 | * @return 包含所有匹配的完整INSERT语句的列表。 |
| 115 | */ |
| 116 | public static List<String> readTableInsertStatements(InputStream inputStream, List<String> tableNames) { |
| 117 | List<String> insertStatements = new ArrayList<>(); |
| 118 | // 预处理表名,创建匹配前缀集合,并转换为大写以进行不敏感匹配 |
| 119 | Set<String> prefixes = tableNames.stream() |
| 120 | .map(name -> "INSERT INTO `" + name.toUpperCase() + "`") |
| 121 | .collect(Collectors.toSet()); |
| 122 | |
| 123 | // 如果表名在SQL中没有引号(例如:INSERT INTO TABLENAME...),需要添加额外的匹配 |
| 124 | Set<String> altPrefixes = tableNames.stream() |
| 125 | .map(name -> "INSERT INTO " + name.toUpperCase() + " ") |
| 126 | .collect(Collectors.toSet()); |
| 127 | |
| 128 | // 🎯 关键修改:使用 InputStreamReader 和 UTF-8 编码读取输入流 |
| 129 | try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) { |
| 130 | |
| 131 | String line; |
| 132 | StringBuilder currentStatement = new StringBuilder(); |
| 133 | boolean inBlock = false; |
| 134 | |
| 135 | while ((line = reader.readLine()) != null) { |
| 136 | String trimmedLine = line.trim(); |
| 137 | String upperLine = trimmedLine.toUpperCase();// 统一转大写,用于匹配 |
| 138 | |
| 139 | // 忽略空行或注释行 |
| 140 | if (trimmedLine.isEmpty() || trimmedLine.startsWith("#") || trimmedLine.startsWith("--")) { |
| 141 | continue; |
| 142 | } |
| 143 | |
| 144 | // 检查行是否是目标表的 INSERT 语句的开始 |
| 145 | if (isTargetInsert(upperLine, prefixes, altPrefixes)) { |
| 146 | inBlock = true; |
| 147 | } |
| 148 | |
| 149 | if (inBlock) { |
| 150 | currentStatement.append(trimmedLine).append(" "); |
| 151 | |
| 152 | // 检查语句是否以分号结束(我们假设SQL语句以分号结束) |
| 153 | if (trimmedLine.endsWith(";")) { |
| 154 | insertStatements.add(currentStatement.toString().trim()); |
| 155 | |
| 156 | // 重置状态 |
| 157 | currentStatement = new StringBuilder(); |
| 158 | inBlock = false; |
| 159 | } |
| 160 | } |
| 161 | } |
| 162 | |
| 163 | } catch (IOException e) { |
| 164 | if (logger.isErrorEnabled()) { |
| 165 | logger.error("读取SQL文件失败",e); |
| 166 | } |
| 167 | } |
| 168 | |
| 169 | return insertStatements; |
| 170 | } |
| 171 | |
| 172 | |
| 173 | /** |
no test coverage detected