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
в весеннее время конфигурации.