diff --git a/src/main/java/com/tem/bocai/util/SQLiteUtil.java b/src/main/java/com/tem/bocai/util/SQLiteUtil.java new file mode 100644 index 0000000..6968fef --- /dev/null +++ b/src/main/java/com/tem/bocai/util/SQLiteUtil.java @@ -0,0 +1,389 @@ +package com.tem.bocai.util; + +import java.sql.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class SQLiteUtil { + private static final String DB_URL = "jdbc:sqlite:bocai.db"; + + static { + // 确保数据库驱动已加载 + try { + Class.forName("org.sqlite.JDBC"); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + + /** + * 获取数据库连接 + */ + public static Connection getConnection() throws SQLException { + return DriverManager.getConnection(DB_URL); + } + + /** + * 初始化数据库表结构 + */ + /*public static void initDatabase() { + Connection conn = null; + Statement stmt = null; + + try { + conn = getConnection(); + stmt = conn.createStatement(); + + // 开启事务 + conn.setAutoCommit(false); + *//* // 删除旧表 + stmt.execute("DROP TABLE IF EXISTS lottery_results"); + System.out.println("已删除旧表");*//* + // 检查表是否存在 + boolean tableExists = false; + try (ResultSet rs = conn.getMetaData().getTables(null, null, "lottery_results", null)) { + tableExists = rs.next(); + } + + if (tableExists) { + System.out.println("表已存在,检查列结构..."); + // checkAndUpdateTableStructure(conn); + } else { + System.out.println("表不存在,创建新表..."); + createTable(conn); + } + + // 提交事务 + conn.commit(); + System.out.println("数据库表初始化/更新成功"); + + } catch (SQLException e) { + try { + if (conn != null) conn.rollback(); + } catch (SQLException ex) { + ex.printStackTrace(); + } + e.printStackTrace(); + System.err.println("数据库表初始化失败: " + e.getMessage()); + } finally { + closeResources(null, stmt, conn); + } + }*/ + + /** + * 创建新表 + */ + private static void createTable(Connection conn) throws SQLException { + String createTableSQL = """ + CREATE TABLE lottery_results ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + time TEXT, + result TEXT, + winner INTEGER, + gd1 TEXT, + gd2 TEXT, + sum1 INTEGER, + sum2 INTEGER, + glh_result TEXT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) + """; + + try (Statement stmt = conn.createStatement()) { + stmt.execute(createTableSQL); + System.out.println("表创建成功"); + } + } + + /** + * 检查并更新表结构 + */ + private static void checkAndUpdateTableStructure(Connection conn) throws SQLException { + // 定义需要的列和类型 + String[][] requiredColumns = { + {"result", "TEXT"}, + {"winner", "INTEGER"}, + {"gd1", "TEXT"}, + {"gd2", "TEXT"}, + {"sum1", "INTEGER"}, + {"sum2", "INTEGER"}, + {"glh_result", "TEXT"}, + {"created_at", "TIMESTAMP"}, + {"updated_at", "TIMESTAMP"} + }; + + // 获取现有列 + List existingColumns = new ArrayList<>(); + try (ResultSet rs = conn.getMetaData().getColumns(null, null, "lottery_results", null)) { + while (rs.next()) { + existingColumns.add(rs.getString("COLUMN_NAME").toLowerCase()); + } + } + + // 添加缺失的列 + try (Statement stmt = conn.createStatement()) { + for (String[] column : requiredColumns) { + String columnName = column[0]; + String columnType = column[1]; + + if (!existingColumns.contains(columnName.toLowerCase())) { + String alterSQL = String.format( + "ALTER TABLE lottery_results ADD COLUMN %s %s", + columnName, columnType + ); + stmt.execute(alterSQL); + System.out.println("已添加列: " + columnName); + } + } + } + } + + /** + * 将爬虫数据写入SQLite数据库 + */ + public static void writeToSQLite(List> resultList) { + if (resultList == null || resultList.isEmpty()) { + System.out.println("没有数据需要写入"); + return; + } + + // 先初始化数据库 + //initDatabase(); + + String insertSQL = """ + INSERT OR REPLACE INTO lottery_results + (issue,time, result, winner, gd1, gd2, sum1, sum2, glh_result) + VALUES (?,?, ?, ?, ?, ?, ?, ?, ?) + """; + + Connection conn = null; + PreparedStatement pstmt = null; + + try { + conn = getConnection(); + conn.setAutoCommit(false); // 开启事务 + + pstmt = conn.prepareStatement(insertSQL); + + int batchCount = 0; + for (Map rowData : resultList) { + // 检查必要字段是否存在 + if (!rowData.containsKey("id") || !rowData.containsKey("result")) { + System.out.println("跳过缺失必要字段的数据: " + rowData); + continue; + } + + // 期数 + pstmt.setString(1, rowData.get("id").toString()); + + // 开奖时间 + if (rowData.containsKey("time")) { + pstmt.setString(2, rowData.get("time").toString()); + } else { + pstmt.setNull(2, Types.VARCHAR); + } + + // 开出号码(转换为逗号分隔的字符串) + try { + List resultNumbers = (List) rowData.get("result"); + String resultStr = String.join(",", resultNumbers.stream() + .map(String::valueOf) + .toArray(String[]::new)); + pstmt.setString(3, resultStr); + } catch (Exception e) { + System.out.println("result字段转换失败: " + rowData.get("result")); + pstmt.setNull(3, Types.VARCHAR); + } + + // winner + try { + Object winnerObj = rowData.get("winner"); + if (winnerObj instanceof Integer) { + pstmt.setInt(4, (Integer) winnerObj); + } else if (winnerObj instanceof String) { + pstmt.setInt(4, Integer.parseInt((String) winnerObj)); + } else { + pstmt.setNull(4, Types.INTEGER); + } + } catch (Exception e) { + pstmt.setNull(4, Types.INTEGER); + } + + // gd1 + if (rowData.containsKey("GD1")) { + pstmt.setString(5, rowData.get("GD1").toString()); + } else { + pstmt.setNull(5, Types.VARCHAR); + } + + // gd2 + if (rowData.containsKey("GD2")) { + pstmt.setString(6, rowData.get("GD2").toString()); + } else { + pstmt.setNull(6, Types.VARCHAR); + } + + // sum1 + try { + Object sum1Obj = rowData.get("sum1"); + if (sum1Obj instanceof Integer) { + pstmt.setInt(7, (Integer) sum1Obj); + } else if (sum1Obj instanceof String) { + pstmt.setInt(7, Integer.parseInt((String) sum1Obj)); + } else { + pstmt.setNull(7, Types.INTEGER); + } + } catch (Exception e) { + pstmt.setNull(7, Types.INTEGER); + } + + // sum2 + try { + Object sum2Obj = rowData.get("sum2"); + if (sum2Obj instanceof Integer) { + pstmt.setInt(8, (Integer) sum2Obj); + } else if (sum2Obj instanceof String) { + pstmt.setInt(8, Integer.parseInt((String) sum2Obj)); + } else { + pstmt.setNull(8, Types.INTEGER); + } + } catch (Exception e) { + pstmt.setNull(8, Types.INTEGER); + } + + // GLH_result + try { + List glhResults = (List) rowData.get("GLH_result"); + String glhResultStr = String.join(",", glhResults); + pstmt.setString(9, glhResultStr); + } catch (Exception e) { + System.out.println("GLH_result字段转换失败: " + rowData.get("GLH_result")); + pstmt.setNull(9, Types.VARCHAR); + } + + pstmt.addBatch(); + batchCount++; + + // 每100条执行一次批量插入 + if (batchCount % 100 == 0) { + pstmt.executeBatch(); + conn.commit(); + System.out.println("已批量插入 " + batchCount + " 条数据"); + } + } + + // 执行剩余的批量插入 + int[] results = pstmt.executeBatch(); + conn.commit(); + + int successCount = 0; + for (int result : results) { + if (result >= 0) successCount++; + } + + System.out.println("成功写入" + successCount + "条数据到SQLite数据库"); + + } catch (SQLException e) { + try { + if (conn != null) conn.rollback(); + } catch (SQLException ex) { + ex.printStackTrace(); + } + e.printStackTrace(); + System.err.println("写入SQLite数据库失败: " + e.getMessage()); + } finally { + closeResources(null, pstmt, conn); + } + } + + /** + * 关闭数据库资源 + */ + private static void closeResources(ResultSet rs, Statement stmt, Connection conn) { + try { + if (rs != null) rs.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + + try { + if (stmt != null) stmt.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + + try { + if (conn != null) conn.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + /** + * 查询数据总数 + */ + public static int getTotalCount() { + String sql = "SELECT COUNT(*) FROM lottery_results"; + + try (Connection conn = getConnection(); + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery(sql)) { + + return rs.next() ? rs.getInt(1) : 0; + + } catch (SQLException e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 清除数据库表 + */ + public static void clearTable() { + String sql = "DELETE FROM lottery_results"; + + try (Connection conn = getConnection(); + Statement stmt = conn.createStatement()) { + + int rows = stmt.executeUpdate(sql); + System.out.println("已清除 " + rows + " 条数据"); + + } catch (SQLException e) { + e.printStackTrace(); + } + } + + /** + * 查看表结构 + */ + public static void showTableStructure() { + String sql = "PRAGMA table_info(lottery_results)"; + + try (Connection conn = getConnection(); + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery(sql)) { + + System.out.println("表结构 lottery_results:"); + System.out.println("=========================="); + System.out.printf("%-5s %-15s %-10s %-5s %-5s %-5s%n", + "cid", "name", "type", "notnull", "dflt_value", "pk"); + System.out.println("------------------------------------------------------------"); + + while (rs.next()) { + System.out.printf("%-5d %-15s %-10s %-5d %-10s %-5d%n", + rs.getInt("cid"), + rs.getString("name"), + rs.getString("type"), + rs.getInt("notnull"), + rs.getString("dflt_value"), + rs.getInt("pk")); + } + + } catch (SQLException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file