You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Eclipse开发JavaFX应用Inno Setup安装后SQLite数据库创建异常

问题原因

你当前使用的SQLite JDBC连接串为jdbc:sqlite:patientdata,属于相对路径配置:SQLite会将数据库文件创建在JVM进程启动时的工作目录下。

  • 在Eclipse开发环境、直接双击运行JAR包时,进程工作目录默认为项目根目录/JAR包所在目录,当前用户对该目录有完整读写权限,因此数据库创建、读写操作均正常。
  • 通过Inno Setup打包安装后,应用默认安装到C:\Program Files\<应用名称>目录,Windows系统对该目录有严格的权限控制,普通运行的进程没有写入权限,会直接拦截数据库文件创建操作;即便系统触发UAC虚拟化把文件重定向到VirtualStore目录,也不会出现在原安装路径下,自然找不到存储位置。
修复方案

1. 固定数据库存储到用户有权限的目录

不要使用相对路径连接数据库,将数据库存储到系统为用户应用分配的专属数据目录,该目录默认对当前用户开放完整读写权限,不会有权限问题。修改getConnection()方法中的连接逻辑,先拼接数据库文件的绝对路径再建立连接:

public static Connection getConnection() throws Exception {
    Connection conn = null;
    // 适配不同操作系统的应用数据目录
    String appDataBase;
    String osName = System.getProperty("os.name").toLowerCase();
    if (osName.contains("win")) {
        appDataBase = System.getenv("APPDATA");
    } else if (osName.contains("mac")) {
        appDataBase = System.getProperty("user.home") + "/Library/Application Support";
    } else {
        appDataBase = System.getProperty("user.home") + "/.config";
    }
    // 为当前应用创建独立存储文件夹
    File appDir = new File(appDataBase + File.separator + "PatientSystem");
    if (!appDir.exists()) {
        appDir.mkdirs();
    }
    File dbFile = new File(appDir, "patientdata.db");
    String jdbcUrl = "jdbc:sqlite:" + dbFile.getAbsolutePath();

    Class.forName("org.sqlite.JDBC");
    conn = DriverManager.getConnection(jdbcUrl);
    // 建表逻辑
    try (Statement stmt = conn.createStatement()) {
        String pat = "CREATE TABLE if not exists newpatient " +
                       "(patientId INTEGER NOT NULL," +
                       " patientName    CHAR(50)    NOT NULL, " + 
                       " patientAge     INTEGER     NOT NULL, " + 
                       "patientGender   CHAR(10) NOT NULL,"+
                       "patientAddress  CHAR(100) NOT NULL,"+
                       "patientMobile   BIGINT(10) NOT NULL)";
        stmt.executeUpdate(pat);

        String hist = "CREATE TABLE if not exists history " +
                           "(id INTEGER NOT NULL," +
                           " date    DATE    NOT NULL, " + 
                           " start   TIME     NOT NULL, " +                                               
                           "stop   TIME NOT NULL)";
        stmt.executeUpdate(hist);
    }
    return conn;
}

2. 编程读取数据库实际存储路径

建立连接后,执行SQLite内置的PRAGMA database_list命令即可直接获取主数据库文件的绝对路径:

try (Statement st = conn.createStatement();
     ResultSet rs = st.executeQuery("PRAGMA database_list")) {
    while (rs.next()) {
        if (rs.getInt("seq") == 0) { // seq=0对应主数据库
            String realDbPath = rs.getString("file");
            System.out.println("数据库实际存储位置:" + realDbPath);
        }
    }
}

3. 其他需要修复的隐患

你当前insertrecord()方法直接拼接用户输入生成SQL语句,存在严重的SQL注入风险,且输入内容包含单引号时会直接触发SQL语法错误,建议替换为PreparedStatement做参数化查询。另外数据库连接、Statement等资源用完要及时关闭,避免出现连接泄漏。

不要通过Inno Setup给Program Files下的安装目录配置全局写入权限,这违反Windows系统安全规范,会给用户设备带来安全风险,用户数据必须存储到用户专属数据目录。

内容的提问来源于stack exchange,提问作者mexco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 19:18:46