Intellij Idea 从.jar文件运行时数据库未更新

rn0zuynd  于 2023-08-03  发布在  其他
关注(0)|答案(1)|浏览(173)

DbHelper包含所有数据库方法。我为insert创建了一个单独的方法来保存重复。当我从IDE运行我的应用程序时(使用Launcher主类),它会更新数据库并正常运行。但是当我运行我的应用程序的.jar文件(工件)时,它不会将更新保存到数据库(但可以正常读取文件)。
我认为这与autocommit设置为false有关,所以我将所有更新数据库函数都设置为true(尽管我从未显式地将其设置为false)。我还确保所有的ResultSet变量在我处理完它们时都是关闭的。连接到数据库的代码:

public static Connection getConnection() {
    try {
        Class.forName("org.sqlite.JDBC"); // Load the SQLite JDBC driver
        String databaseUrl;
        // if running .jar file do this
        databaseUrl = "jdbc:sqlite::resource:ttlsDatabase.db";

        //else (running from ide) do this
        //databaseUrl = "jdbc:sqlite:C:\\Users\\medaw\\Desktop\\TTLS_APP\\src\\main\\Resource\\ttlsDatabase.db";

        Connection databaseLink = DriverManager.getConnection(databaseUrl);
        return databaseLink;
    } catch (ClassNotFoundException e) {
        System.err.println("SQLite JDBC driver not found. Make sure you have added the SQLite JDBC driver to your project's classpath.");
    } catch (SQLException e) {
        System.err.println("An error occurred with the database: " + e.getMessage());
    }
    return null;
}

字符串
每当我想运行.jar文件时,我都会注解:

databaseUrl = "jdbc:sqlite:C:\\Users\\medaw\\Desktop\\TTLS_APP\\src\\main\\Resource\\ttlsDatabase.db";


否则我会评论:

databaseUrl = "jdbc:sqlite:C:\\Users\\medaw\\Desktop\\TTLS_APP\\src\\main\\Resource\\ttlsDatabase.db";


它起作用了,我确保了con变量(它永远不会为空),并且在两种情况下都可以正常地从数据库中检索数据。我假设数据库处于某种只读模式。
这是我用来更新数据库的函数。关于优化这段代码的建议,我洗耳恭听!我将它用于所有只需要执行一次查询的更新:

public static boolean updateDatabase(ArrayList<Object> list, String query){
    try (Connection con = getConnection()) {
        con.setAutoCommit(true);

        PreparedStatement stmt = con.prepareStatement(query);
        stmt = setStatements(stmt, list);
        if (stmt == null) {
            return false;
        }

        int x = stmt.executeUpdate();
        if(x == 0){
            return false;
        }
        con.commit();

        return true;
    } catch (Exception e) {
        UtilityMethods.showMessageDialog("Unable to update item!", "Error!", "Update Unsuccessful", 1);
    }
    return false;
}


w8ntj3qf

w8ntj3qf1#

资源只读

jar文件中的资源(任何文件类型,而不仅仅是SQL lite db文件)都是只读的。
用于访问jar文件中资源的jar protocol不允许回写来更改资源。
JarURLConnection示例只能用于读取JAR文件。使用此类无法获取OutputStream来修改或写入底层JAR文件。
SQLite将需要更新数据库文件,如果你写数据到数据库。因此,要允许对数据库进行更新,您需要使用文件系统上的数据库文件(而不是嵌入在jar中的资源)。

如何获取可写数据库文件

如果你有一个种子数据库,你想分发给你的用户,有几种方法可以做到这一点。

方法一:将嵌入式数据库文件资源从jar中提取到文件中

如果将初始数据库嵌入到jar文件中,则可以在应用启动时将初始数据库映像提取到文件中,并让SQLite连接到提取的文件。这样做的机制记录在詹姆斯的回答中:

  • 使用Maven构建JavaFX应用程序后复制外部资源文件
    方法二:将数据库文件与jar文件分开打包

您可以打包数据库文件并将其与jar分开分发。
1.使用像jpackage这样的打包系统,允许安装具有单独资源(复杂)的应用程序,或者
1.使用Maven assembly或类似的文件,使用单独的数据库文件创建应用的zip发行版。

方法三:如果没有数据库文件,则创建新的数据库文件

如果您使用的是JPA/Spring/Hibernate,这些工具能够通过对为应用程序定义的实体类进行内省来创建不存在的数据库。这也可能是一个可行的替代方案。
使用这种技术需要一个定义了JPA实体的JPA持久性管理器,它不适用于原始JDBC。当然,结果数据库将是空的。如果需要的话,您可能还需要在数据库中添加populate some data
对于Spring,它是这样做的,但是如果你使用另一种技术,请参考你的DB访问框架的文档:

  • 使用JPA初始化数据库

相关问题