更新开始时间2

This commit is contained in:
xuelijun
2026-01-23 17:09:48 +08:00
parent 89190309ef
commit 9e1d8308ca
6 changed files with 176 additions and 10 deletions

View File

@@ -18,7 +18,7 @@ public class CompletedToday {
private String betId; //
@Column(name = "time", nullable = false)
private String time; //
private Date time; //
//下注金额
@Column(name = "bet_amount", nullable = false)

View File

@@ -15,6 +15,7 @@ import java.util.Optional;
public interface CompletedTodayRepository extends JpaRepository<CompletedToday, Long> {
// 根据时间范围查询resultAmount的总和
//Double sumResultAmountByCreateTimeAfter(Date startTime);
@Query("SELECT SUM(ct.resultAmount) FROM CompletedToday ct WHERE ct.time > :startTime")
Double sumResultAmountByCreateTimeAfter(@Param("startTime") Date startTime);

View File

@@ -111,7 +111,7 @@ public class CrawlerSchedule {
// 每7秒执行一次爬取今日已经结算
//@Scheduled(cron = "*/7 * * * * ?")
@Scheduled(cron = "*/7 * * * * ?")
public void executeSettlement() {
System.out.println("开始爬取今日已经结算...");
int retryCount = 0;

View File

@@ -19,6 +19,9 @@ import us.codecraft.webmagic.selector.Html;
import java.io.File;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -289,14 +292,34 @@ public class CompletedTodayCrawler implements PageProcessor {
/**
* 转换数据结构以适应数据库
*/
/**
* 转换数据结构以适应数据库使用Java 8日期时间API
*/
private List<CompletedToday> convertForDatabase(List<Map<String, Object>> betList) {
List<CompletedToday> completedTodayList = new ArrayList<>();
// 根据你实际的日期字符串格式调整
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
for (Map<String, Object> bet : betList) {
CompletedToday completedToday = new CompletedToday();
completedToday.setBetId((String) bet.get("bet_id"));
completedToday.setTime((String) bet.get("time"));
// 转换String时间到Date
try {
String timeStr = (String) bet.get("time");
// 将LocalDateTime转换为Date
LocalDateTime localDateTime = LocalDateTime.parse(timeStr, formatter);
Date timeDate = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
completedToday.setTime(timeDate);
} catch (Exception e) {
// 处理日期解析异常,这里设置为当前时间作为默认值
completedToday.setTime(new Date());
// 也可以记录日志
System.err.println("日期解析失败: " + bet.get("time"));
}
completedToday.setBetAmount((Double)bet.get("bet_amount"));
completedToday.setResultAmount((Double) bet.get("result_amount"));
completedToday.setResult((String) bet.get("result"));
@@ -307,6 +330,7 @@ public class CompletedTodayCrawler implements PageProcessor {
}
/**
* 保存HTML用于调试
*/

View File

@@ -191,15 +191,16 @@ public class SQLiteUtil {
/**
* 批量插入今日完结数据
*/
public static boolean saveCompletedToday(List<CompletedToday> list) {
/* public static boolean saveCompletedToday(List<CompletedToday> list) {
if (list == null || list.isEmpty()) return false;
String sql = """
INSERT OR IGNORE INTO completed_today
(bet_id, time, bet_amount, result, result_amount, create_time, update_time)
VALUES (?, ?, ?, ?, ?, ?, ?)
VALUES (?, datetime(?), ?, ?, ?, ?, ?)
""";
// 使用ISO8601格式: yyyy-MM-dd HH:mm:ss
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try (Connection conn = getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
@@ -209,14 +210,18 @@ public class SQLiteUtil {
if (data == null || data.getBetId() == null) continue;
pstmt.setString(1, data.getBetId());
pstmt.setString(2, data.getTime());
// 核心修复:毫秒转秒+setLong传入适配datetime(?)无setString
if (data.getTime() != null) {
long secondTs = data.getTime().getTime() / 1000; // 毫秒→秒级时间戳
pstmt.setLong(2, secondTs);
} else {
long secondTs = System.currentTimeMillis() / 1000; // 空值兜底当前秒级时间
pstmt.setLong(2, secondTs);
}
pstmt.setDouble(3, data.getBetAmount() != null ? data.getBetAmount() : 0.0);
pstmt.setString(4, data.getResult() != null ? data.getResult() : "未知");
pstmt.setDouble(5, data.getResultAmount() != null ? data.getResultAmount() : 0.0);
// 使用ISO8601格式: yyyy-MM-dd HH:mm:ss
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 处理create_time
if (data.getCreateTime() != null) {
pstmt.setString(6, sdf.format(data.getCreateTime()));
@@ -242,8 +247,144 @@ public class SQLiteUtil {
e.printStackTrace();
return false;
}
}*/
/**
* 批量插入今日完结数据终极稳定版解决SQLite datetime()解析问题+非空约束+批量插入)
*/
public static boolean saveCompletedToday(List<CompletedToday> list) {
if (list == null || list.isEmpty()) {
System.out.println("[SQL日志] 待插入数据为空,直接返回");
return false;
}
// 核心删除datetime()函数,直接插入标准时间字符串
String sql = """
INSERT OR REPLACE INTO completed_today
(bet_id, time, bet_amount, result, result_amount, create_time, update_time)
VALUES (?, ?, ?, ?, ?, ?, ?)
""";
// 全局统一标准时间格式SQL兼容yyyy-MM-dd HH:mm:ss支持所有时间查询
SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
int validDataCount = 0;
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = getConnection();
if (conn == null) {
System.err.println("[SQL日志] 获取数据库连接失败!");
return false;
}
pstmt = conn.prepareStatement(sql);
conn.setAutoCommit(false); // 开启事务
// 打印基础信息
System.out.println("[SQL日志] 待执行SQL" + sql.replaceAll("\\s+", " "));
System.out.println("[SQL日志] 原始传入数据量:" + list.size());
for (CompletedToday data : list) {
// 过滤无效数据(含空串校验)
if (data == null || data.getBetId() == null || data.getBetId().trim().isEmpty()) {
System.out.println("[SQL日志] 过滤无效数据data为null 或 bet_id为null/空串");
continue;
}
validDataCount++;
// 1. bet_id唯一标识
pstmt.setString(1, data.getBetId().trim());
// 核心修复Java层格式化为标准时间字符串直接传入无datetime(),彻底解决非空)
String timeStr;
if (data.getTime() != null) {
timeStr = timeFormat.format(data.getTime());
} else {
timeStr = timeFormat.format(new Date()); // 空值兜底当前时间
}
pstmt.setString(2, timeStr);
// 3. 下注金额空值兜底0.0
Double betAmount = data.getBetAmount() != null ? data.getBetAmount() : 0.0;
pstmt.setDouble(3, betAmount);
// 4. 输赢结果:空值兜底"未知"
String result = data.getResult() != null ? data.getResult().trim() : "未知";
pstmt.setString(4, result);
// 5. 输赢金额空值兜底0.0
Double resultAmount = data.getResultAmount() != null ? data.getResultAmount() : 0.0;
pstmt.setDouble(5, resultAmount);
// 6. 创建时间:空值兜底当前时间
String createTime = data.getCreateTime() != null ? timeFormat.format(data.getCreateTime()) : timeFormat.format(new Date());
pstmt.setString(6, createTime);
// 7. 更新时间:空值兜底当前时间
String updateTime = data.getUpdateTime() != null ? timeFormat.format(data.getUpdateTime()) : timeFormat.format(new Date());
pstmt.setString(7, updateTime);
// 打印单条参数日志含最终存入的time字符串
System.out.printf("[SQL日志] 批量参数%dbet_id=%s, time=%s, bet_amount=%.2f, result=%s, result_amount=%.2f, create_time=%s, update_time=%s%n",
validDataCount, data.getBetId(), timeStr, betAmount, result, resultAmount, createTime, updateTime);
pstmt.addBatch();
}
// 校验有效数据量
if (validDataCount == 0) {
System.out.println("[SQL日志] 无有效批量数据,执行回滚");
conn.rollback();
return false;
}
System.out.println("[SQL日志] 有效批量数据量已加入Batch" + validDataCount);
// 执行批量插入并统计结果
int[] executeResults = pstmt.executeBatch();
int successCount = 0;
for (int res : executeResults) {
if (res == java.sql.Statement.SUCCESS_NO_INFO || res > 0) {
successCount++;
}
}
conn.commit(); // 提交事务
System.out.println("[SQL日志] 批量插入成功:总执行条数=" + executeResults.length + ",实际插入/替换条数=" + successCount);
return successCount > 0;
} catch (SQLException e) {
// 打印完整异常信息
System.err.println("[SQL异常] 批量插入失败,原因:");
System.err.println("错误码(ErrorCode)" + e.getErrorCode());
System.err.println("异常信息:" + e.getMessage());
e.printStackTrace();
// 异常回滚(判断自动提交模式)
try {
if (conn != null && !conn.getAutoCommit()) {
conn.rollback();
System.out.println("[SQL日志] 异常触发事务回滚成功");
}
} catch (SQLException ex) {
System.err.println("[SQL异常] 事务回滚失败:" + ex.getMessage());
ex.printStackTrace();
}
return false;
} finally {
// 手动关闭资源,恢复连接状态
try {
if (pstmt != null) pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (conn != null) {
conn.setAutoCommit(true); // 恢复自动提交
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 关闭数据库资源
*/