【问题标题】:HSQLDB in resources within a WARWAR 内资源中的 HSQLDB
【发布时间】:2017-06-10 16:02:57
【问题描述】:

我使用 Spring Boot 开发了一个小应用程序,它使用 HSQLDB 作为数据库来存储用户,暂时。我想要做的是将数据库存储在 Maven 的资源文件夹中。我的 application.properties 文件包含以下配置:

#...
spring.datasource.url=jdbc:hsqldb:file:src/main/resources/database/dashboard
#...

所以,每当我使用 Java 启动应用程序时(右键单击我的应用程序的 main() 并作为 Spring Boot 应用程序运行),数据库都会正确存储。

但是,在使用 mvn clean install spring-boot:repackage 打包一个 WAR 文件,将其部署到 Tomcat 中并运行它之后,数据库不会存储在展开的 WAR 中。

我的问题是如何告诉spring.datasource.url=jdbc:hsqldb:file:* 属性将数据库存储在 Maven 资源目录中(在 WAR 爆炸后仍会指向该目录)?我可以使用 pom.xml 中使用的某种环境变量吗?

编辑 鉴于@Steve C 和@fredt 的答案,我意识到数据库不应该存储在战争中。相反,我会将其存储在用户的主目录spring.datasource.url=jdbc:hsqldb:file:~/tomcat_webapp_data/dashboard/database.. 非常感谢!

【问题讨论】:

  • 您似乎在使用相对路径指向 hsqldb。 Hsql 的文件位置将相对于工作目录(可能是 tomcat/ 中的 bin/ )。您应该使用绝对路径。
  • 1) 更好地使用 Apache Derby,HSQLDB 总是完全加载到 RAM 内存中 - 这可能会用更大的 DB 杀死你的应用程序 2) 只需更改构建脚本以将整个 db 目录包含在战争中,然后确保在服务器容器中有正确的 db 文件路径
  • @Redlab 我不想使用绝对路径,因为我不知道将放置 WAR 的系统的性质(linux,win ...),也不知道它是否'将使用 java 运行。
  • @KrzysztofCichocki 我觉得我在使用 Derby 时会遇到同样的问题......数据库会非常小。您的第二种方法似乎是正确的。但是如果我初始化数据库并将其包含在战争中,仍然需要数据源的配置(对相对路径的引用)。

标签: java maven spring-boot properties hsqldb


【解决方案1】:

WAR 文件的目录和内容是只读的。

您可以在加入 WAR 之前在 HSQLDB 数据库 .properties 文件中设置 read_only 标志。您使用jdbc:hsqldb:res:<path> URL 访问此类数据库。

如果您想将数据存储在持久且可更新的数据库中,请连接到应用程序中的(起初不存在的)数据库,并设置其表(如果它们尚不存在来自资源的数据)。然后,您可以存储数据。数据库路径应位于用于 jar 和资源的目录之外。

与其中一种 cmets 不同,HSQLDB 不仅限于将数据存储在内存中,还可以拥有基于磁盘的表,称为 CACHED 表。

您可以在数据库 URL 中包含一个变量,以从 Web 服务器中获取预定义的属性。例如:

jdbc:hsqldb:file:${mydbpath}

http://hsqldb.org/doc/2.0/guide/dbproperties-chapt.html#dpc_variables_url

【讨论】:

    【解决方案2】:

    Maven 的src/main/resources 目录是构建时路径,而不是运行时路径。

    如果您正在构建 jar 文件,则 src/main/resources 中的所有内容都会复制到 jar 的根目录。

    如果你正在构建一个war文件,那么src/main/resources中的所有内容都会被复制到war中/WEB-INF/classes目录的根目录中。

    现在,您的 JDBC URL jdbc:hsqldb:file:src/main/resources/database/dashboard 表示具有相对路径的文件。在运行时,此路径是相对于当前工作目录的 - 无论如何它不太可能在运行时存在。

    如果你真的想在你的 WAR 中构建数据库,那么给出:

    • 您正在部署一个展开的 WAR 文件(无法写入 WAR 文件本身的内容);

    • 您真的很想将数据库存储在爆炸的 WAR 中;

    • 你想把它放在WEB-INF/database/dashboard中(如果你存储在WEB-INF目录之外会有安全隐患);

    然后你可以使用类似的东西来计算 JDBC url:

    ...
    String databaseDirectoryName = servletContext.getRealPath("WEB-INF/database");
    File databaseDirectory = new File(databaseDirectoryName);
    if (!databaseDirectory.exists()) {
        if (!databaseDirectory.mkdirs()) {
            throw new RuntimeException("Failed to create database directory");
        }
    }
    File databaseFile = new File(databaseDirectory, "dashboard");
    String jdbcURL = "jdbc:hsqldb:" + databaseFile.toURI();
    ...
    

    将它纳入您的 Spring 配置对您来说是一个练习;但是使用@Configuration@Bean 会想到一种方法来执行此操作-您只需要在Spring 配置时访问servletContext

    【讨论】:

      猜你喜欢
      • 2013-08-14
      • 1970-01-01
      • 2014-07-13
      • 2013-07-21
      • 1970-01-01
      • 2010-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多