张洋洋
2025-01-08 29723c0c6658effce1419aadc01354853965ec6d
src/main/java/com/se/simu/service/Impl/SemFilesSimuServiceImpl.java
@@ -1,15 +1,33 @@
package com.se.simu.service.Impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.se.simu.service.SemFilesSimuService;
import com.se.simu.utils.ZipUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.sql.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
@Slf4j
@Service
public class SemFilesSimuServiceImpl implements SemFilesSimuService {
    @Value("${config.outPath}")
    private String outPath;
    /**
     * 获取 INTRODUCE
@@ -43,5 +61,279 @@
        return introduceMap;
    }
    @Override
    public Object createSimuBySemFile() {
        return null;
    }
    @Override
    public Object readSemFile(String filePath) {
        // 文件地址
        log.info("filePath:{}", filePath);
        // 处理文件
        JSONObject result = new JSONObject();
        try {
            // 测试连接SQLite数据库
            Connection connection = connectToSQLiteWithCopy(filePath);
            System.out.println("SQLite数据库连接成功!");
            Statement stmt = connection.createStatement();
            // 查询ENTITY表的数据并返回JSON格式的结果
//            result = queryEntityTable(stmt);
            result = queryDynamizersTable(stmt);
            // 关闭连接
            connection.close();
            return result;
        } catch (SQLException | IOException e) {
            System.err.println("操作失败: " + e.getMessage());
            return e.getMessage();
        }
    }
    /**
     * 根据传入的文件路径,添加后缀 `.db` 并连接 SQLite 数据库。
     *
     * @param filePath 文件路径
     * @return SQLite数据库的连接
     * @throws SQLException 如果SQLite连接失败
     */
    public static Connection connectToSQLite(String filePath) throws SQLException {
        // 检查文件路径是否为空
        if (filePath == null || filePath.trim().isEmpty()) {
            throw new IllegalArgumentException("文件路径不能为空");
        }
        // 检查文件是否已经有.db后缀,没有则添加
        if (!filePath.endsWith(".db")) {
            filePath = filePath + ".db";
        }
        log.info("Connecting to SQLite database: " + filePath);
        // 创建文件对象
        File dbFile = new File(filePath);
        // 如果文件不存在,则创建一个新文件
        if (!dbFile.exists()) {
            log.info("文件不存在,请检查文件位置是否正确...");
            return null;
            // try {
            //     // 通过调用 createNewFile() 方法创建新文件
            //     boolean created = dbFile.createNewFile();
            //     if (!created) {
            //         throw new SQLException("无法创建数据库文件");
            //     }
            // } catch (Exception e) {
            //     throw new SQLException("创建数据库文件时出错: " + e.getMessage(), e);
            // }
        }
        // 使用 SQLite JDBC 连接字符串连接数据库
        String url = "jdbc:sqlite:" + dbFile.getAbsolutePath();
        log.info("连接到SQLite数据库: {}", url);
        // 创建并返回数据库连接
        return DriverManager.getConnection(url);
    }
    /**
     * 根据传入的文件路径,复制文件并给复制的文件添加后缀 `.db`,然后连接 SQLite 数据库。
     *
     * @param filePath 原始文件路径
     * @return SQLite数据库的连接
     * @throws SQLException 如果SQLite连接失败
     * @throws IOException  如果文件复制失败
     */
    public static Connection connectToSQLiteWithCopy(String filePath) throws SQLException, IOException {
        // 检查文件路径是否为空
        if (filePath == null || filePath.trim().isEmpty()) {
            throw new IllegalArgumentException("文件路径不能为空");
        }
        // 创建原始文件对象
        File originalFile = new File(filePath);
        // 检查原文件是否存在
        if (!originalFile.exists()) {
            throw new FileNotFoundException("原始文件不存在:" + filePath);
        }
        // 获取当前时间戳作为文件名的一部分
        String timestamp = String.valueOf(System.currentTimeMillis());
        // 创建一个新的文件名,添加一个随机后缀以避免文件名冲突
        String newFilePath = filePath + "." + timestamp + ".db";
        // 复制文件到新的路径
        copyFile(originalFile, new File(newFilePath));
        // 使用 SQLite JDBC 连接字符串连接新的数据库文件
        String url = "jdbc:sqlite:" + newFilePath;
        log.info("连接到SQLite数据库: {}", url);
        // 返回SQLite数据库连接
        return DriverManager.getConnection(url);
    }
    /**
     * 复制文件到新的位置
     *
     * @param sourceFile 原始文件
     * @param destFile   目标文件
     * @throws IOException 如果复制过程中发生错误
     */
    private static void copyFile(File sourceFile, File destFile) throws IOException {
        // 使用NIO的Files.copy方法进行高效的文件复制
        Path sourcePath = sourceFile.toPath();
        Path destinationPath = destFile.toPath();
        // 复制文件并覆盖目标文件
        Files.copy(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING);
        log.info("文件已复制到:" + destinationPath.toString());
    }
    /**
     * 查询ENTITY表的数据并返回JSON格式的数据
     *
     * @param stmt SQLite数据库连接
     * @return JSON格式的查询结果
     * @throws SQLException 如果查询过程中发生错误
     */
    public static JSONObject queryEntityTable(Statement stmt) throws SQLException {
        // 构建SQL查询语句
        String querySql = "SELECT ID,DATA,SCHEMA,UUID FROM ENTITY";
        // 执行查询并返回结果
        try (ResultSet rs = stmt.executeQuery(querySql)) {
            // 创建一个 JSON 数组用于存储多条记录
            JSONArray jsonArray = new JSONArray();
            // 将查询结果转化为JSON数组
            JSONObject resJsonObject = new JSONObject();
            // 遍历查询结果
            while (rs.next()) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("ID", rs.getInt("ID"));
                String data = rs.getString("DATA");
                // 将DATA字段进行反序列化
                jsonObject.put("DATA", JSON.parse(data));
                jsonObject.put("SCHEMA", rs.getInt("SCHEMA"));
                jsonObject.put("UUID", rs.getString("UUID"));
                // 将每一行的结果添加到JSON数组
                jsonArray.add(jsonObject);
            }
            resJsonObject.put("entity", jsonArray);
            return resJsonObject;
        }
    }
    /**
     * 查询DYNAMIZERS表的数据并返回JSON格式的数据
     * 对于BLOB字段,转换为Base64字符串
     *
     * @param stmt SQL语句执行对象
     * @return JSON格式的查询结果
     * @throws SQLException 如果查询过程中发生错误
     */
    public JSONObject queryDynamizersTable(Statement stmt) throws SQLException {
        // 构建SQL查询语句
        String querySql = "SELECT URL, GMLID, DATA FROM DYNAMIZERS";
        // 创建一个 JSON 对象用于存储结果
        JSONObject resultJson = new JSONObject();
        // 创建一个 JSON 数组用于存储多条记录
        JSONArray jsonArray = new JSONArray();
        // 执行查询并返回结果
        try (ResultSet rs = stmt.executeQuery(querySql)) {
            // 遍历查询结果
            while (rs.next()) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("URL", rs.getString("URL"));
                jsonObject.put("GMLID", rs.getString("GMLID"));
                // 获取 BLOB 数据并将其转换为 Base64 编码字符串
                byte[] blobData = rs.getBytes("DATA");
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
                String dirpath = outPath + "\\" + formatter.format(LocalDateTime.now());
                String filepath = outPath + "\\" + formatter.format(LocalDateTime.now()) + "\\" + rs.getString("URL");
                try {
                    File file = new File(dirpath);
                    if (!file.exists()) {
                        file.mkdirs();
                    }
                    File resultFile = new File(filepath);
                    resultFile.createNewFile();
                    try (FileOutputStream fos = new FileOutputStream(filepath)) {
                        fos.write(blobData);
                        ZipUtils.unzip(filepath,dirpath);
                        System.out.println("Bytes written to file successfully.");
                        resultFile.delete();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                jsonObject.put("DATA", filepath);
                jsonArray.add(jsonObject);
            }
            // 将查询结果放入最终的 JSON 对象中
            resultJson.put("dynamizers", jsonArray);
        }
        return resultJson;
    }
    /**
     * 使用分页 Query Entity Table
     * // 假设每页查询1000条数据,查询第2页的数据
     * // JSONArray result = queryEntityTableWithPagination(stmt, 1000, 2);
     *
     * @param stmt       STMT
     * @param pageSize
     * @param pageNumber 页码
     * @return {@link JSONArray}
     * @throws SQLException sql异常
     */
    public static JSONArray queryEntityTableWithPagination(Statement stmt, int pageSize, int pageNumber) throws SQLException {
        // 计算查询的偏移量
        int offset = (pageNumber - 1) * pageSize;
        // 构建SQL查询语句,使用LIMIT和OFFSET进行分页
        String querySql = "SELECT * FROM ENTITY LIMIT " + pageSize + " OFFSET " + offset;
        try (ResultSet rs = stmt.executeQuery(querySql)) {
            JSONArray jsonArray = new JSONArray();
            // 遍历查询结果
            while (rs.next()) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("ID", rs.getInt("ID"));
                jsonObject.put("DATA", rs.getString("DATA"));
                jsonObject.put("SCHEMA", rs.getString("SCHEMA"));
                jsonObject.put("UUID", rs.getString("UUID"));
                jsonArray.add(jsonObject);
            }
            return jsonArray;
        }
    }
//    public static void main(String[] args) {
//        try {
//            // 测试连接SQLite数据库
//            Connection connection = connectToSQLiteWithCopy("D:\\0a_project\\simulation\\other\\1211SEM样例\\管点.sem");
//            System.out.println("SQLite数据库连接成功!");
//            // 关闭连接
//            connection.close();
//        } catch (SQLException | IOException e) {
//            System.err.println("操作失败: " + e.getMessage());
//        }
//    }
    /**
     * 创建数据库连接
     */
    private static Connection getConnection(String sqliteDbPath) throws SQLException {
        // 创建SQLite数据库连接
        Connection conn = DriverManager.getConnection("jdbc:sqlite:" + sqliteDbPath);
        Statement stmt = conn.createStatement();
        // 关闭数据库连接
        //conn.close();
        return conn;
    }
}