parent
7405a02aad
commit
75ad55318c
@ -0,0 +1,271 @@
|
||||
package Tools;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DatabaseSynchronizer {
|
||||
// 数据库连接配置
|
||||
private static final String SQLITE_URL = "jdbc:sqlite:D:\\dsWork\\CcsEduData\\数据库与脚本\\edudb_gather_220100000000_full_fullreport.db";
|
||||
private static final String PG_URL = "jdbc:postgresql://10.10.14.71:5432/szjz_db";
|
||||
private static final String PG_USER = "postgres";
|
||||
private static final String PG_PASSWORD = "DsideaL147258369";
|
||||
|
||||
public void syncDatabase() {
|
||||
// 要同步的表名列表
|
||||
List<String> tables = List.of("教基1001", "教基4149", "教基3115", "教基2107");
|
||||
|
||||
try {
|
||||
// 加载数据库驱动
|
||||
Class.forName("org.sqlite.JDBC");
|
||||
Class.forName("org.postgresql.Driver");
|
||||
|
||||
// 同步每个表
|
||||
for (String tableName : tables) {
|
||||
syncTable(tableName);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void syncTable(String tableName) throws SQLException {
|
||||
// 获取表结构和数据
|
||||
TableInfo tableInfo = getTableInfo(tableName);
|
||||
List<List<Object>> data = getTableData(tableName);
|
||||
|
||||
// 在PostgreSQL中创建表并插入数据
|
||||
createTableInPostgres(tableInfo);
|
||||
insertDataToPostgres(tableInfo, data);
|
||||
}
|
||||
|
||||
private TableInfo getTableInfo(String tableName) throws SQLException {
|
||||
TableInfo tableInfo = new TableInfo(tableName);
|
||||
|
||||
try (Connection conn = DriverManager.getConnection(SQLITE_URL);
|
||||
ResultSet rs = conn.getMetaData().getColumns(null, null, tableName, null)) {
|
||||
|
||||
while (rs.next()) {
|
||||
String columnName = rs.getString("COLUMN_NAME");
|
||||
String sqliteType = rs.getString("TYPE_NAME");
|
||||
// 转换SQLite类型到PostgreSQL类型
|
||||
String pgType = convertSqliteTypeToPg(sqliteType);
|
||||
tableInfo.addColumn(columnName, pgType);
|
||||
}
|
||||
}
|
||||
return tableInfo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void createTableInPostgres(TableInfo tableInfo) throws SQLException {
|
||||
StringBuilder createTableSQL = new StringBuilder();
|
||||
createTableSQL.append("CREATE TABLE IF NOT EXISTS ")
|
||||
.append(tableInfo.tableName)
|
||||
.append(" (");
|
||||
|
||||
for (int i = 0; i < tableInfo.columnNames.size(); i++) {
|
||||
if (i > 0) createTableSQL.append(", ");
|
||||
createTableSQL.append(tableInfo.columnNames.get(i))
|
||||
.append(" ")
|
||||
.append(tableInfo.columnTypes.get(i));
|
||||
}
|
||||
createTableSQL.append(")");
|
||||
|
||||
try (Connection conn = DriverManager.getConnection(PG_URL, PG_USER, PG_PASSWORD);
|
||||
Statement stmt = conn.createStatement()) {
|
||||
stmt.execute(createTableSQL.toString());
|
||||
}
|
||||
}
|
||||
private void insertDataToPostgres(TableInfo tableInfo, List<List<Object>> data) throws SQLException {
|
||||
if (data.isEmpty()) {
|
||||
System.out.println("没有数据需要插入");
|
||||
return;
|
||||
}
|
||||
|
||||
try (Connection conn = DriverManager.getConnection(PG_URL, PG_USER, PG_PASSWORD)) {
|
||||
conn.setAutoCommit(false);
|
||||
|
||||
StringBuilder insertSQL = new StringBuilder();
|
||||
insertSQL.append("INSERT INTO ")
|
||||
.append(tableInfo.tableName)
|
||||
.append(" (");
|
||||
|
||||
for (int i = 0; i < tableInfo.columnNames.size(); i++) {
|
||||
if (i > 0) insertSQL.append(", ");
|
||||
insertSQL.append(tableInfo.columnNames.get(i));
|
||||
}
|
||||
|
||||
insertSQL.append(") VALUES (");
|
||||
|
||||
for (int i = 0; i < tableInfo.columnNames.size(); i++) {
|
||||
if (i > 0) insertSQL.append(", ");
|
||||
insertSQL.append("?");
|
||||
}
|
||||
|
||||
insertSQL.append(")");
|
||||
|
||||
System.out.println("插入SQL: " + insertSQL);
|
||||
|
||||
try (PreparedStatement pstmt = conn.prepareStatement(insertSQL.toString())) {
|
||||
int batchSize = 1000;
|
||||
int count = 0;
|
||||
int totalInserted = 0;
|
||||
|
||||
for (List<Object> row : data) {
|
||||
if (row.size() != tableInfo.columnNames.size()) {
|
||||
System.out.println("警告: 数据行列数不匹配");
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < row.size(); i++) {
|
||||
Object value = row.get(i);
|
||||
String columnType = tableInfo.columnTypes.get(i).toUpperCase();
|
||||
|
||||
try {
|
||||
if (value == null) {
|
||||
pstmt.setNull(i + 1, Types.NULL);
|
||||
}
|
||||
// 处理数值类型
|
||||
else if (columnType.contains("DOUBLE") || columnType.contains("NUMERIC") ||
|
||||
columnType.contains("DECIMAL") || columnType.contains("REAL")) {
|
||||
if (value instanceof String) {
|
||||
String strValue = (String) value;
|
||||
if (strValue.isEmpty()) {
|
||||
pstmt.setNull(i + 1, Types.DOUBLE);
|
||||
} else {
|
||||
try {
|
||||
pstmt.setDouble(i + 1, Double.parseDouble(strValue));
|
||||
} catch (NumberFormatException e) {
|
||||
pstmt.setNull(i + 1, Types.DOUBLE);
|
||||
System.out.println("警告: 无法转换为数值类型: " + strValue);
|
||||
}
|
||||
}
|
||||
} else if (value instanceof Number) {
|
||||
pstmt.setDouble(i + 1, ((Number) value).doubleValue());
|
||||
} else {
|
||||
pstmt.setNull(i + 1, Types.DOUBLE);
|
||||
System.out.println("警告: 未知的数值类型: " + value.getClass());
|
||||
}
|
||||
}
|
||||
// 处理整数类型
|
||||
else if (columnType.contains("INTEGER") || columnType.contains("INT")) {
|
||||
if (value instanceof String) {
|
||||
String strValue = (String) value;
|
||||
if (strValue.isEmpty()) {
|
||||
pstmt.setNull(i + 1, Types.INTEGER);
|
||||
} else {
|
||||
try {
|
||||
pstmt.setInt(i + 1, Integer.parseInt(strValue));
|
||||
} catch (NumberFormatException e) {
|
||||
pstmt.setNull(i + 1, Types.INTEGER);
|
||||
System.out.println("警告: 无法转换为整数类型: " + strValue);
|
||||
}
|
||||
}
|
||||
} else if (value instanceof Number) {
|
||||
pstmt.setInt(i + 1, ((Number) value).intValue());
|
||||
} else {
|
||||
pstmt.setNull(i + 1, Types.INTEGER);
|
||||
System.out.println("警告: 未知的整数类型: " + value.getClass());
|
||||
}
|
||||
}
|
||||
// 其他类型当作字符串处理
|
||||
else {
|
||||
pstmt.setString(i + 1, value.toString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("警告: 设置值时出错: 列=" + tableInfo.columnNames.get(i) +
|
||||
", 值=" + value + ", 类型=" + columnType);
|
||||
pstmt.setNull(i + 1, Types.NULL);
|
||||
}
|
||||
}
|
||||
|
||||
pstmt.addBatch();
|
||||
|
||||
if (++count % batchSize == 0) {
|
||||
pstmt.executeBatch();
|
||||
conn.commit();
|
||||
totalInserted += count;
|
||||
count = 0;
|
||||
System.out.println("已插入 " + totalInserted + " 行");
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
pstmt.executeBatch();
|
||||
conn.commit();
|
||||
totalInserted += count;
|
||||
}
|
||||
|
||||
System.out.println("总共插入 " + totalInserted + " 行数据");
|
||||
} catch (SQLException e) {
|
||||
conn.rollback();
|
||||
System.out.println("插入数据时出错: " + e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 修改 getTableData 方法,添加调试信息
|
||||
private List<List<Object>> getTableData(String tableName) throws SQLException {
|
||||
List<List<Object>> data = new ArrayList<>();
|
||||
|
||||
try (Connection conn = DriverManager.getConnection(SQLITE_URL);
|
||||
Statement stmt = conn.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName)) {
|
||||
|
||||
ResultSetMetaData metaData = rs.getMetaData();
|
||||
int columnCount = metaData.getColumnCount();
|
||||
|
||||
System.out.println("Table: " + tableName + ", Column count: " + columnCount);
|
||||
for (int i = 1; i <= columnCount; i++) {
|
||||
System.out.println("Column " + i + ": " + metaData.getColumnName(i) +
|
||||
" (" + metaData.getColumnTypeName(i) + ")");
|
||||
}
|
||||
|
||||
while (rs.next()) {
|
||||
List<Object> row = new ArrayList<>();
|
||||
for (int i = 1; i <= columnCount; i++) {
|
||||
row.add(rs.getObject(i));
|
||||
}
|
||||
data.add(row);
|
||||
}
|
||||
|
||||
System.out.println("Read " + data.size() + " rows from SQLite");
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private String convertSqliteTypeToPg(String sqliteType) {
|
||||
// 类型转换映射
|
||||
return switch (sqliteType.toUpperCase()) {
|
||||
case "INTEGER" -> "INTEGER";
|
||||
case "REAL" -> "DOUBLE PRECISION";
|
||||
case "TEXT" -> "TEXT";
|
||||
case "BLOB" -> "BYTEA";
|
||||
default -> "TEXT";
|
||||
};
|
||||
}
|
||||
|
||||
// 表信息存储类
|
||||
private static class TableInfo {
|
||||
String tableName;
|
||||
List<String> columnNames = new ArrayList<>();
|
||||
List<String> columnTypes = new ArrayList<>();
|
||||
|
||||
TableInfo(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
void addColumn(String name, String type) {
|
||||
columnNames.add(name);
|
||||
columnTypes.add(type);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
DatabaseSynchronizer synchronizer = new DatabaseSynchronizer();
|
||||
synchronizer.syncDatabase();
|
||||
}
|
||||
}
|
Loading…
Reference in new issue