安装我的应用程序后如何控制 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())) {
...
}
我在我的 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())) {
...
}