HSQLDB в ресурсах в рамках войны

Я разработал небольшое приложение, использующее Spring Boot, которое в настоящее время использует HSQLDB в качестве базы данных для хранения пользователей. Я хочу сохранить базу данных в папке ресурсов Maven. Мой файл application.properties содержит следующую конфигурацию:

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

Таким образом, всякий раз, когда я запускаю приложение с Java (щелкните правой кнопкой мыши на main() моего приложения и Run Boot Spring Boot App), база данных сохраняется правильно.

Но после упаковки файла WAR с mvn clean install spring-boot:repackageпри развертывании его в 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.. Огромное спасибо!

2 ответа

Каталоги и содержимое файла WAR доступны только для чтения.

Вы можете установить флаг read_only в файле.properties базы данных HSQLDB перед включением в WAR. Вы получаете доступ к такой базе данных с jdbc:hsqldb:res:<path> URL.

Если вы хотите хранить данные в постоянной и обновляемой базе данных, подключитесь к (сначала не существующей) базе данных в вашем приложении и настройте ее таблицы, если они еще не существуют с данными из ресурса. Вы можете хранить данные. Путь к базе данных должен быть вне каталогов, которые используются для jar-файлов и ресурсов.

Вопреки одному из комментариев, HSQLDB не ограничивается хранением данных в памяти и может иметь дисковые таблицы, называемые таблицами CACHED.

Вы можете включить переменную в URL базы данных, чтобы получить предварительно определенное свойство с веб-сервера. Например:

jdbc:hsqldb:file:${mydbpath}

См. http://hsqldb.org/doc/2.0/guide/dbproperties-chapt.html.

В Maven src/main/resources Каталог - это путь времени сборки, а не путь времени выполнения.

Если вы создаете файл JAR, то все в src/main/resources копируется в корень банки.

Если вы создаете файл войны, то все в src/main/resources копируется в корень каталога /WEB-INF/classes в войне.

Теперь ваш JDBC URL jdbc:hsqldb:file:src/main/resources/database/dashboard указывает на файл с относительным путем. Во время выполнения этот путь относительно текущего рабочего каталога - и в любом случае он вряд ли будет существовать во время выполнения.

Если вы действительно хотите построить базу данных в вашей WAR, тогда получите:

  • вы развертываете разорванный файл WAR (невозможно записать содержимое самого файла WAR);

  • вы действительно хотите сохранить базу данных в разнесенной WAR;

  • Вы хотите поместить это в WEB-INF/database/dashboard (есть последствия для безопасности, если вы храните вне каталога WEB-INF);

тогда вы можете вычислить URL JDBC, используя что-то вроде:

...
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 приходит на ум как способ сделать это - вам просто нужно получить доступ к servletContext в весеннее время конфигурации.

Другие вопросы по тегам