安装我的应用程序后如何控制 SQLite 3 数据库文件目录(使用 JPackage 打包)

How to control SQLite 3 database files directory after installing my app (Packaged using JPackage)

我在我的 JavaFX 应用程序中使用 SQLite 3 作为数据库,目标是将所有内容打包到一个文件中(这样用户除了启动 .msi 文件来安装它外不需要做任何事情), 我将数据库文件放在资源中,并使用 JPackage 打包我的整个应用程序,问题是在安装它之后,数据库文件被保存在 C:/Users/username/AppData/Local/Temp 中,这不是存储重要数据的好地方(我应该提到我的应用程序目录在 C:/Users/username/Program Files).

中符合预期

我真的不知道为什么它们会分开(应用程序目录和数据库目录)以及为什么数据库文件会保存在一个临时文件中,有什么办法可以改变它们的目录吗?

详情:

我的数据库连接器:

 private Connection connection;

    private CashManagementDBConnector(){
        try {
            connection = DriverManager.getConnection("jdbc:sqlite::resource:DataBases/CashManagement.db");

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

JDBC

我正在使用 xerial SQLite JDBC 3.36.0.3

JDK版本

java 17

到目前为止,我认为问题出在 JDBC

SQLite 将资源连接 jdbc:sqlite::resource:blah.db 视为只读的,因此它会将它找到的资源的副本作为目录中的新数据库:

System.getProperty("java.io.tmpdir");

如果您不想这样做,在启动时您可以让代码检查任何位置的特定数据库文件,例如:

Path mydb = Path.of(System.getenv("LOCALAPPDATA"), "MyAppName", "blah.db");

如果以上文件不存在,您可以复制主资源文件覆盖它:

final String resName= "/DataBases/CashManagement.db";
if (!Files.isRegularFile(mydb)) {
    Files.createDirectories(mydb.getParent()); // if using subdir for app
    try(var in = YourClass.class.getResourceAsStream(resName)) {
        Objects.requireNonNull(in, () -> "Not found resource: "+resName);
        Files.copy(in, mydb);
    }
}

然后使用JDBC驱动程序来复制资源:

 try(Connection conn = DriverManager.getConnection("jdbc:sqlite:"+mydb.toAbsolutePath())) {
 ...
 }