import java.sql.*; import java.util.UUID; public class SQLiteConverter { // SQLite JDBC驱动 private static final String JDBC_DRIVER = "org.sqlite.JDBC"; // 原始数据库路径 private static final String ORIGINAL_DB_PATH = "jdbc:sqlite:D:\\YJEarth.model"; // 新数据库路径 private static final String NEW_DB_PATH = "jdbc:sqlite:E:\\通用模型库.model"; public static void main(String[] args) { System.out.println("===== 开始数据库转换程序 ====="); System.out.println("原始数据库: " + ORIGINAL_DB_PATH); System.out.println("目标数据库: " + NEW_DB_PATH + "\n"); // 使用try-with-resources自动管理连接资源 try (Connection originalConn = DriverManager.getConnection(ORIGINAL_DB_PATH); Connection newConn = DriverManager.getConnection(NEW_DB_PATH)) { System.out.println("✅ 成功连接到原始数据库"); System.out.println("✅ 成功创建并连接到新数据库\n"); // 在新数据库中创建表结构 System.out.println("===== 开始创建新表结构 ====="); createNewTables(newConn); System.out.println("===== 新表结构创建完成 ====="); // 迁移mode_types表数据到model_type表 System.out.println("\n===== 开始迁移mode_types表数据 ====="); MigrationResult modeTypesResult = migrateModeTypes(originalConn, newConn); System.out.println("===== mode_types表数据迁移完成 ====="); System.out.printf(" 成功: %d 条, 失败: %d 条, 总计: %d 条%n", modeTypesResult.successCount, modeTypesResult.failureCount, modeTypesResult.totalCount); // 迁移models表数据到model表 System.out.println("\n===== 开始迁移models表数据 ====="); MigrationResult modelsResult = migrateModels(originalConn, newConn); System.out.println("===== models表数据迁移完成 ====="); System.out.printf(" 成功: %d 条, 失败: %d 条, 总计: %d 条%n", modelsResult.successCount, modelsResult.failureCount, modelsResult.totalCount); if (modeTypesResult.failureCount > 0 || modelsResult.failureCount > 0) { System.out.println("\n⚠️ 注意:部分记录迁移失败、已跳过错误记录"); } System.out.println("\n===== 数据库转换处理完成! ====="); } catch (SQLException e) { System.err.println("\n❌ 数据库连接错误: " + e.getMessage()); e.printStackTrace(); } } /** * 迁移结果数据类 */ private static class MigrationResult { int successCount; int failureCount; int totalCount; MigrationResult(int success, int failure, int total) { this.successCount = success; this.failureCount = failure; this.totalCount = total; } } /** * 在新数据库中创建表结构 */ private static void createNewTables(Connection conn) throws SQLException { try (Statement stmt = conn.createStatement()) { // 创建model_type表 System.out.println("正在创建model_type表..."); String createModelTypeTable = "CREATE TABLE IF NOT EXISTS \"model_type\" (" + "\"id\" TEXT," + "\"name\" TEXT," + "\"parent_id\" TEXT," + "\"tree_index\" INTEGER," + "\"created_at\" TEXT," + "\"updated_at\" TEXT," + "PRIMARY KEY (\"id\")" + ");"; stmt.execute(createModelTypeTable); System.out.println("✅ model_type表创建完成"); // 创建model表 System.out.println("正在创建model表..."); String createModelTable = "CREATE TABLE IF NOT EXISTS \"model\" (" + "\"id\" TEXT," + "\"model_type_id\" TEXT," + "\"model_name\" TEXT," + "\"model_type\" TEXT," + "\"poster_type\" TEXT," + "\"poster\" TEXT," + "\"data\" TEXT," + "\"data_bytes\" BLOB," + "\"view\" TEXT," + "\"created_at\" TEXT," + "\"updated_at\" TEXT," + "PRIMARY KEY (\"id\")" + ");"; stmt.execute(createModelTable); System.out.println("✅ model表创建完成"); } } /** * 迁移mode_types表数据到model_type表 */ private static MigrationResult migrateModeTypes(Connection originalConn, Connection newConn) throws SQLException { // 先获取记录总数、用于显示进度 int totalCount; try (PreparedStatement countStmt = originalConn.prepareStatement("SELECT COUNT(*) FROM mode_types"); ResultSet countRs = countStmt.executeQuery()) { countRs.next(); totalCount = countRs.getInt(1); System.out.println("发现 " + totalCount + " 条mode_types记录待迁移"); } // 查询原始表数据 try (PreparedStatement selectStmt = originalConn.prepareStatement("SELECT * FROM mode_types"); ResultSet rs = selectStmt.executeQuery()) { // 插入到新表、关闭自动提交以提高性能 newConn.setAutoCommit(false); try (PreparedStatement insertStmt = newConn.prepareStatement( "INSERT INTO model_type (" + "id, name, parent_id, tree_index, created_at, updated_at" + ") VALUES (?, ?, ?, ?, ?, ?)")) { int successCount = 0; int failureCount = 0; while (rs.next()) { try { // 生成新的UUID作为ID String newId = UUID.randomUUID().toString().replaceAll("-", ""); String typeName = rs.getString("type_name"); // 映射字段 insertStmt.setString(1, newId); insertStmt.setString(2, typeName); insertStmt.setString(3, rs.getString("p_id")); insertStmt.setInt(4, 0); insertStmt.setString(5, rs.getString("created_at")); insertStmt.setString(6, rs.getString("updated_at")); insertStmt.executeUpdate(); successCount++; // 每迁移10条记录或最后一批记录时打印进度 if (successCount % 10 == 0 || (successCount + failureCount) == totalCount) { printProgress(successCount + failureCount, totalCount); } } catch (SQLException e) { // 捕获单条记录的异常、跳过该记录 failureCount++; System.err.printf("\n❌ 迁移mode_types记录失败 (序号: %d): %s%n", successCount + failureCount, e.getMessage()); } } newConn.commit(); return new MigrationResult(successCount, failureCount, totalCount); } catch (SQLException e) { newConn.rollback(); throw e; } finally { newConn.setAutoCommit(true); } } } /** * 迁移models表数据到model表 */ private static MigrationResult migrateModels(Connection originalConn, Connection newConn) throws SQLException { // 先获取记录总数、用于显示进度 int totalCount; try (PreparedStatement countStmt = originalConn.prepareStatement("SELECT COUNT(*) FROM models"); ResultSet countRs = countStmt.executeQuery()) { countRs.next(); totalCount = countRs.getInt(1); System.out.println("发现 " + totalCount + " 条models记录待迁移"); } // 查询原始表数据 try (PreparedStatement selectStmt = originalConn.prepareStatement("SELECT * FROM models"); ResultSet rs = selectStmt.executeQuery()) { // 插入到新表、关闭自动提交以提高性能 newConn.setAutoCommit(false); try (PreparedStatement insertStmt = newConn.prepareStatement( "INSERT INTO model (" + "id, model_type_id, model_name, model_type, poster_type, " + "poster, data, data_bytes, view, created_at, updated_at" + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")) { int successCount = 0; int failureCount = 0; while (rs.next()) { try { // 生成新的UUID作为ID String newId = UUID.randomUUID().toString().replaceAll("-", ""); String modelName = rs.getString("model_name"); // 映射字段 insertStmt.setString(1, newId); insertStmt.setString(2, rs.getString("p_id")); insertStmt.setString(3, modelName); insertStmt.setString(4, rs.getString("model_type")); insertStmt.setString(5, rs.getString("poster_type")); // 处理BLOB字段 byte[] posterBlob = rs.getBytes("poster"); insertStmt.setString(6, posterBlob != null ? new String(posterBlob) : null); insertStmt.setString(7, null); byte[] dataBlob = rs.getBytes("data"); insertStmt.setBytes(8, dataBlob); insertStmt.setString(9, null); insertStmt.setString(10, rs.getString("created_at")); insertStmt.setString(11, rs.getString("updated_at")); insertStmt.executeUpdate(); successCount++; // 每迁移10条记录或最后一批记录时打印进度 if (successCount % 10 == 0 || (successCount + failureCount) == totalCount) { printProgress(successCount + failureCount, totalCount); } } catch (SQLException e) { // 捕获单条记录的异常、跳过该记录 failureCount++; System.err.printf("\n❌ 迁移models记录失败 (序号: %d, 名称: %s): %s%n", successCount + failureCount, rs.getString("model_name"), e.getMessage()); } } newConn.commit(); return new MigrationResult(successCount, failureCount, totalCount); } catch (SQLException e) { newConn.rollback(); throw e; } finally { newConn.setAutoCommit(true); } } } /** * 打印迁移进度 */ private static void printProgress(int current, int total) { double percentage = (current * 100.0) / total; System.out.printf("迁移进度: %d/%d (%.1f%%)\r", current, total, percentage); System.out.flush(); } }