|
|
|
@ -225,48 +225,59 @@ public class MySQLService { |
|
|
|
/** |
|
|
|
* 根据ID列表批量删除数据 |
|
|
|
* 使用IN语句一次性删除,提高效率 |
|
|
|
* @return 失败的ID列表(如果全部成功则返回空列表) |
|
|
|
*/ |
|
|
|
public void deleteByIds(String schema, String table, List<Long> ids) throws SQLException { |
|
|
|
public List<Long> deleteByIds(String schema, String table, List<Long> ids) { |
|
|
|
if (ids == null || ids.isEmpty()) { |
|
|
|
return; |
|
|
|
return new ArrayList<>(); |
|
|
|
} |
|
|
|
|
|
|
|
int batchSize = 1000; |
|
|
|
int totalDeleted = 0; |
|
|
|
List<Long> failedIds = new ArrayList<>(); |
|
|
|
|
|
|
|
// 分批删除,每批1000个ID
|
|
|
|
for (int i = 0; i < ids.size(); i += batchSize) { |
|
|
|
int end = Math.min(i + batchSize, ids.size()); |
|
|
|
List<Long> batchIds = ids.subList(i, end); |
|
|
|
try (Connection conn = DriverManager.getConnection(MYSQL_URL, DB_USER, DB_PASSWORD)) { |
|
|
|
// 分批删除,每批1000个ID
|
|
|
|
for (int i = 0; i < ids.size(); i += batchSize) { |
|
|
|
int end = Math.min(i + batchSize, ids.size()); |
|
|
|
List<Long> batchIds = ids.subList(i, end); |
|
|
|
|
|
|
|
// 构建IN子句的占位符字符串:?, ?, ?, ...
|
|
|
|
String placeholders = String.join(",", Collections.nCopies(batchIds.size(), "?")); |
|
|
|
String sql = String.format("DELETE FROM %s.%s WHERE id IN (%s)", schema, table, placeholders); |
|
|
|
// logger.info("deleteByIds sql: {}, batch ids count: {}", sql, batchIds.size());
|
|
|
|
|
|
|
|
try (Connection conn = DriverManager.getConnection(MYSQL_URL, DB_USER, DB_PASSWORD); |
|
|
|
PreparedStatement ps = conn.prepareStatement(sql)) { |
|
|
|
|
|
|
|
// 逐个设置ID参数值
|
|
|
|
for (int j = 0; j < batchIds.size(); j++) { |
|
|
|
ps.setLong(j + 1, batchIds.get(j)); |
|
|
|
} |
|
|
|
int deleted = ps.executeUpdate(); |
|
|
|
totalDeleted += deleted; |
|
|
|
logger.info("[{}.{}] 批次删除 {} 条记录,累计 {} 条", schema, table, deleted, totalDeleted); |
|
|
|
} |
|
|
|
|
|
|
|
// 每批之间稍作停顿,减少锁冲突
|
|
|
|
if (i + batchSize < ids.size()) { |
|
|
|
try { |
|
|
|
Thread.sleep(20); |
|
|
|
} catch (InterruptedException e) { |
|
|
|
Thread.currentThread().interrupt(); |
|
|
|
// 构建IN子句的占位符字符串:?, ?, ?, ...
|
|
|
|
String placeholders = String.join(",", Collections.nCopies(batchIds.size(), "?")); |
|
|
|
String sql = String.format("DELETE FROM %s.%s WHERE id IN (%s)", schema, table, placeholders); |
|
|
|
logger.info("deleteByIds sql: {}, batch ids count: {}", sql, batchIds.size()); |
|
|
|
|
|
|
|
try (PreparedStatement ps = conn.prepareStatement(sql)) { |
|
|
|
// 逐个设置ID参数值
|
|
|
|
for (int j = 0; j < batchIds.size(); j++) { |
|
|
|
ps.setLong(j + 1, batchIds.get(j)); |
|
|
|
} |
|
|
|
int deleted = ps.executeUpdate(); |
|
|
|
totalDeleted += deleted; |
|
|
|
logger.info("[{}.{}] 批次删除 {} 条记录,累计 {} 条", schema, table, deleted, totalDeleted); |
|
|
|
} |
|
|
|
|
|
|
|
// 每批之间稍作停顿,减少锁冲突
|
|
|
|
if (i + batchSize < ids.size()) { |
|
|
|
try { |
|
|
|
Thread.sleep(20); |
|
|
|
} catch (InterruptedException e) { |
|
|
|
Thread.currentThread().interrupt(); |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (Exception e) { |
|
|
|
logger.error("[{}.{}] 批次删除失败,添加到失败列表:{}", schema, table, batchIds.size(), e); |
|
|
|
failedIds.addAll(batchIds); |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (Exception e) { |
|
|
|
logger.error("[{}.{}] 获取数据库连接失败,所有批次都失败", schema, table, e); |
|
|
|
failedIds.addAll(ids); |
|
|
|
} |
|
|
|
|
|
|
|
logger.info("[{}.{}] 总删除 {} 条记录", schema, table, totalDeleted); |
|
|
|
logger.info("[{}.{}] 总删除 {} 条记录,失败 {} 条", schema, table, totalDeleted, failedIds.size()); |
|
|
|
return failedIds; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
|