JPackage打包JavaFX应用后如何调整SQLite3数据库文件的存储目录
问题原因
你当前使用jdbc:sqlite::resource:DataBases/CashManagement.db的连接写法触发了xerial SQLite JDBC驱动的内置逻辑:当检测到数据库路径指向jar包内的资源文件时,因为jar包内的资源是只读的无法支持写入操作,驱动会自动将资源内的db文件解压复制到系统临时目录后再建立连接,这就是数据库文件出现在Temp目录的原因。
解决方案
可读写的SQLite数据库不能直接存放在jar包资源目录或Program Files安装目录(普通用户默认无该目录写入权限),你需要将资源内的初始数据库模板复制到用户可读写的专用数据目录后再连接,步骤如下:
- 首次启动应用时,先检查用户数据目录下是否存在目标数据库文件
- 若不存在,将jar包资源内的初始
CashManagement.db复制到该目录 - 直接通过文件系统路径连接该目录下的数据库文件
代码实现示例
改造后的数据库连接器代码参考:
private Connection connection; private CashManagementDBConnector(){ try { // Windows下获取用户应用数据目录,对应C:\Users\用户名\AppData\Roaming String userAppData = System.getenv("APPDATA"); Path appDataDir = Paths.get(userAppData, "你的应用名称"); // 应用专属目录不存在则创建 if (!Files.exists(appDataDir)) { Files.createDirectories(appDataDir); } Path dbPath = appDataDir.resolve("CashManagement.db"); // 首次启动无数据库文件,从资源目录复制初始模板 if (!Files.exists(dbPath)) { try (InputStream is = getClass().getResourceAsStream("/DataBases/CashManagement.db")) { Files.copy(is, dbPath); } } // 直接连接本地文件系统中的数据库 connection = DriverManager.getConnection("jdbc:sqlite:" + dbPath.toAbsolutePath()); } catch (SQLException | IOException e) { e.printStackTrace(); } }
- 代码中的
你的应用名称替换为实际应用名,用于区分不同应用的存储目录 - 如需跨平台兼容可调整用户目录获取逻辑:macOS下可使用
System.getProperty("user.home") + "/Library/Application Support/你的应用名",Linux下使用System.getProperty("user.home") + "/.你的应用名"
注意事项
- 不要将可写数据库放在Program Files安装目录,Windows UAC权限限制会导致普通用户运行应用时写入报错
- 原有
:resource连接方式仅适用于只读的内置数据库场景,需要读写的场景必须使用本地文件系统路径连接
内容的提问来源于stack exchange,提问作者Youssef Idraiss
相关产品推荐
相关产品推荐

