6

我想创建一个用户只需运行 .jar 文件即可运行的程序。我希望这个程序能够访问一个数据库,该数据库在第一次下载程序时预先填充了一些数据,并且当用户使用它时,更多的数据被添加到数据库中。

数据库应该本地存储在用户的计算机上。

我最好的选择是什么?我应该使用哪个数据库引擎,我该怎么做才能让用户在安装应用程序时不必设置数据库,它将预先填充 .jar 文件?

4

3 回答 3

7

一个简单的解决方案是使用本地存储在磁盘上的嵌入式数据库(例如靠近 jar 文件)。您可以为此使用h2,甚至sqlite

加载时,程序将检查数据库是否存在,如果不存在,只需播放一个设置 SQL 脚本,该脚本将创建数据库结构和初始数据,否则你很好,只需执行应用程序的工作即可创建做。

这是一个非常简单的 h2 数据库示例:

假设您正在打包一个名为 JAR 文件夹的 SQL 文件init.sql/resources/它将创建一个表,例如:

create table foobar(bazz VARCHAR);
insert into foobar values('foo');
insert into foobar values('bar');
// and so on

然后在您的代码中的某个地方,您需要访问数据,您将尝试加载数据库或创建它(如果它尚不存在)。

Connection loadDatabase() throws Exception {
    Class.forName("org.h2.Driver");
    Connection con = null;
    try {
        // throws an exception if the database does not exists
        con = DriverManager.getConnection("jdbc:h2:./foo.db;ifexists=true");
    } catch (SQLException e) {
        // if the database does not exists it will be created
        conn = DriverManager.getConnection("jdbc:h2:./foo.db");
        // init the db
        initDatabase(con);
    }

    return con;
}

void initDatabase(Connection con) throws Exception {
    // load the init.sql script from JAR
    InputStreamReader isr = new InputStreamReader(
        getClass().getResourceAsStream("/resources/init.sql"));
    // run it on the database to create the whole structure, tables and so on
    RunScript.execute(con, isr);
    isr.close();
}

void doSomeStuffWithDb() throws Exception {
    Connection con = loadDatabase();
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("select * from foobar");
    // will print foo, then bar
    while (rs.next()) {
        System.out.println(rs.getString(1));
    }
    rs.close();
    stmt.close();
    conn.close();
}

foo.db执行后,您应该在应用程序旁边有一个名为的文件,其中包含创建的表等。

这是一个非常简单的例子,当然你可以使用 JDBC 的任何包装器来避免使用 ResultSet 等,比如 spring jdbcTemplate,甚至加载连接实例等。

于 2012-10-18T18:55:23.527 回答
2

我会调查h2。这是一个很棒的数据库,有很多持久化选项。另外,由于您使用的是 Java,因此我会考虑研究 hibernate。

于 2012-10-18T18:33:22.847 回答
2

使用Java DB,然后当用户第一次启动程序时,将脚本加载到它。

于 2012-10-18T18:29:10.060 回答