You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

202 lines
8.4 KiB

8 months ago
package com.dashboard.aws.lambda.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.*;
8 months ago
import java.time.LocalDate;
8 months ago
import java.util.*;
public class MySQLService {
private static final Logger logger = LoggerFactory.getLogger(MySQLService.class);
private static final String MYSQL_URL = System.getenv("DB_URL"); // 统一实例URL
private static final String DB_USER = System.getenv("DB_USER");
private static final String DB_PASSWORD = System.getenv("DB_PASSWORD");
/**
* 获取符合条件的企业ID
*/
// public List<Long> getActiveCompanyIds() throws SQLException {
// String sql = """
// SELECT id FROM data_center_new.basic_company
// WHERE flag != 1
// AND (parent_id = -1 OR parent_id = 1)
// """;
//
// try (Connection conn = DriverManager.getConnection(MYSQL_URL, DB_USER, DB_PASSWORD);
// PreparedStatement ps = conn.prepareStatement(sql);
// ResultSet rs = ps.executeQuery()) {
//
// List<Long> ids = new ArrayList<>();
// while (rs.next()) {
// ids.add(rs.getLong("id"));
// }
// return ids;
// }
// }
8 months ago
8 months ago
public List<Map<String, Object>> queryOldData(String schema, String table, long startTs, long endTs) throws SQLException {
String sql = String.format("SELECT * FROM %s.%s WHERE upload_at >= ? AND upload_at < ?", schema, table);
logger.info("query sql: {}, start: {}, end: {}", sql, startTs, endTs);
8 months ago
try (Connection conn = DriverManager.getConnection(MYSQL_URL, DB_USER, DB_PASSWORD);
PreparedStatement ps = conn.prepareStatement(sql)) {
8 months ago
ps.setLong(1, startTs);
ps.setLong(2, endTs);
8 months ago
ResultSet rs = ps.executeQuery();
ResultSetMetaData meta = rs.getMetaData();
List<Map<String, Object>> list = new ArrayList<>();
while (rs.next()) {
Map<String, Object> row = new LinkedHashMap<>();
for (int i = 1; i <= meta.getColumnCount(); i++) {
row.put(meta.getColumnName(i), rs.getObject(i));
}
list.add(row);
}
return list;
}
}
8 months ago
public void deleteOldData(String schema, String table, long startTs, long endTs) throws SQLException {
String sql = String.format("DELETE FROM %s.%s WHERE upload_at >= ? AND upload_at < ?", schema, table);
logger.info("deleteOldData sql: {}, start: {}, end: {}", sql, startTs, endTs);
8 months ago
try (Connection conn = DriverManager.getConnection(MYSQL_URL, DB_USER, DB_PASSWORD);
PreparedStatement ps = conn.prepareStatement(sql)) {
8 months ago
ps.setLong(1, startTs);
ps.setLong(2, endTs);
8 months ago
int deleted = ps.executeUpdate();
logger.info("[{}.{}] 删除 {} 条记录", schema, table, deleted);
}
}
8 months ago
public int insertRows(String schema, String table, List<Map<String, String>> rows) throws SQLException {
if (rows == null || rows.isEmpty()) return 0;
Map<String, String> first = rows.get(0);
List<String> columns = new ArrayList<>(first.keySet());
String columnStr = String.join(",", columns);
String placeholders = String.join(",", Collections.nCopies(columns.size(), "?"));
String sql = String.format("INSERT INTO %s.%s (%s) VALUES (%s)", schema, table, columnStr, placeholders);
8 months ago
// logger.info("insert sql: {}", sql);
8 months ago
int total = 0;
try (Connection conn = DriverManager.getConnection(MYSQL_URL, DB_USER, DB_PASSWORD);
PreparedStatement ps = conn.prepareStatement(sql)) {
8 months ago
for (Map<String, String> row : rows) {
for (int i = 0; i < columns.size(); i++) {
ps.setString(i + 1, row.getOrDefault(columns.get(i), null));
}
ps.addBatch();
}
int[] results = ps.executeBatch();
for (int r : results) total += r;
}
return total;
}
8 months ago
public int deleteBeforeDate(String schema, String table, LocalDate fileDate) {
// 计算比较值: yyyyMMdd 格式的整数(例如 20251008)
int cutoff = fileDate.getYear() * 10000 + fileDate.getMonthValue() * 100 + fileDate.getDayOfMonth();
String sql = String.format(
"DELETE FROM %s.%s WHERE (COALESCE(date_year,0) * 10000 + COALESCE(date_month,0) * 100 + COALESCE(date_day,0)) < ?",
schema, table
);
logger.info("deleteBeforeDate sql: {}, cutoff:{}", sql, cutoff);
try (Connection conn = DriverManager.getConnection(MYSQL_URL, DB_USER, DB_PASSWORD);
8 months ago
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, cutoff);
int deleted = ps.executeUpdate();
logger.info("deleteBeforeDate: schema={}, table={}, cutoff={}, deleted={}", schema, table, cutoff, deleted);
return deleted;
} catch (SQLException e) {
logger.error("deleteBeforeDate failed for {}/{} cutoff={}", schema, table, cutoff, e);
return 0;
}
}
/**
* 根据ID列表批量删除数据
* 使用IN语句一次性删除提高效率
*/
public void deleteByIds(String schema, String table, List<Long> ids) throws SQLException {
if (ids == null || ids.isEmpty()) {
return;
}
// 构建IN子句的占位符字符串:?, ?, ?, ...
String placeholders = String.join(",", Collections.nCopies(ids.size(), "?"));
String sql = String.format("DELETE FROM %s.%s WHERE id IN (%s)", schema, table, placeholders);
logger.info("deleteByIds sql: {}, ids count: {}", sql, ids.size());
try (Connection conn = DriverManager.getConnection(MYSQL_URL, DB_USER, DB_PASSWORD);
PreparedStatement ps = conn.prepareStatement(sql)) {
// 逐个设置ID参数值
for (int i = 0; i < ids.size(); i++) {
ps.setLong(i + 1, ids.get(i));
}
int deleted = ps.executeUpdate();
logger.info("[{}.{}] 删除 {} 条记录", schema, table, deleted);
}
}
/**
* 查询ID大于指定值的前N条数据 upload_at + id 升序
* 用于分页分批处理数据
* @param lastId 上次处理的最大ID不包含为null时从第一条开始查询
* @param lastUploadAt 上次处理的最大 upload_at不包含
* @param cutoffUploadAt 截止时间只处理 upload_at < cutoffUploadAt 的数据
*/
public List<Map<String, Object>> queryFirstNByIdGreaterThan(String schema, String table, int limit, Long lastId, Long lastUploadAt, Long cutoffUploadAt) throws SQLException {
String sql;
if (lastId == null) {
// 第一次查询
sql = String.format("SELECT * FROM %s.%s WHERE upload_at < ? ORDER BY upload_at ASC, id ASC LIMIT ?", schema, table);
} else {
// 后续查询,从上次之后开始
sql = String.format("SELECT * FROM %s.%s WHERE (upload_at > ? OR (upload_at = ? AND id > ?)) AND upload_at < ? ORDER BY upload_at ASC, id ASC LIMIT ?", schema, table);
}
logger.info("queryFirstNByIdGreaterThan sql: {}, limit: {}, lastId: {}, lastUploadAt: {}, cutoffUploadAt: {}",
sql, limit, lastId, lastUploadAt, cutoffUploadAt);
try (Connection conn = DriverManager.getConnection(MYSQL_URL, DB_USER, DB_PASSWORD);
PreparedStatement ps = conn.prepareStatement(sql)) {
int paramIndex = 1;
if (lastId != null) {
ps.setLong(paramIndex++, lastUploadAt);
ps.setLong(paramIndex++, lastUploadAt);
ps.setLong(paramIndex++, lastId);
}
ps.setLong(paramIndex++, cutoffUploadAt);
ps.setInt(paramIndex, limit);
ResultSet rs = ps.executeQuery();
ResultSetMetaData meta = rs.getMetaData();
List<Map<String, Object>> list = new ArrayList<>();
// 将结果集转换为Map列表
while (rs.next()) {
Map<String, Object> row = new LinkedHashMap<>();
for (int i = 1; i <= meta.getColumnCount(); i++) {
row.put(meta.getColumnName(i), rs.getObject(i));
}
list.add(row);
}
return list;
}
}
8 months ago
}