更新开始时间2
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ public class CrawlerSchedule {
|
||||
|
||||
|
||||
// 每7秒执行一次爬取今日已经结算
|
||||
//@Scheduled(cron = "*/7 * * * * ?")
|
||||
@Scheduled(cron = "*/7 * * * * ?")
|
||||
public void executeSettlement() {
|
||||
System.out.println("开始爬取今日已经结算...");
|
||||
int retryCount = 0;
|
||||
|
||||
@@ -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用于调试
|
||||
*/
|
||||
|
||||
@@ -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日志] 批量参数%d:bet_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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 关闭数据库资源
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user