Приложение Spring Boot с файловой базой данных H2

#java #spring #spring-boot

#java #spring #spring-boot

Вопрос:

Я пытаюсь настроить базу данных H2 при запуске приложения spring boot. Я настроил базу данных в application.properties:

 spring.datasource.url = jdbc:h2:file:~/testdb
spring.datasource.username = sa
spring.datasource.password = sa
spring.datasource.driverClassName = org.h2.Driver
  

Приложение.java-файл:

 @Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);

        CreateH2Database createH2Database = new CreateH2Database();
        createH2Database.create();
    }
}
  

CreateH2Database.java:

 public class CreateH2Database {

    private Logger log = Logger.getLogger(CreateH2Database.class);

    @Autowired
    protected JdbcTemplate jdbcTemplate;

    public void create() {
        log.info("Creating H2 Database");
        createUsers();
    }

    private void createUsers() {
        log.info("Creating users table");
        jdbcTemplate.execute("create table if not exists users (id serial, first_name varchar(255), last_name varchar(255))");
        String[] names = "John Woo;Jeff Dean;Josh Bloch;Josh Long".split(";");
        for (String fullname : names) {
            String[] name = fullname.split(" ");
            log.info("Inserting user record for "   name[0]   " "   name[1]   "n");
            jdbcTemplate.update(
                "INSERT INTO users(first_name,last_name) values(?,?)",
                name[0], name[1]);
            }
        }
    }
  

После запуска приложения оно должно создать таблицу Users, если она еще не существует, и вставить пользователей в таблицу. Если таблица уже существует, я не хочу, чтобы она изменялась.

  1. Я получаю NullPointerException on jdbcTemplate.execute . Как я могу jdbcTemplate внедрить? Во всех примерах, которые я видел, требуется, чтобы источник данных создавался вручную, а затем создается JdbcTemplate. Однако источник данных в этом примере, похоже, создан на основе значений application.properties.
  2. Является ли это правильным подходом к настройке базы данных (т. Е. вызову CreateH2Database после запуска SpringApplication)? Сработает ли этот подход, если я захочу запустить приложение как WAR на другом сервере приложений?

Ответ №1:

Поскольку вы используете Spring Boot, вам следует воспользоваться преимуществами его функций инициализации базы данных. Нет необходимости развертывать собственную реализацию.

Все, что вам нужно сделать, это разместить файлы schema.sql и data.sql в корне пути к классу (скорее всего, под /resources ). Spring Boot автоматически обнаружит их и запустит первую для создания базы данных, а вторую для ее заполнения.

Ознакомьтесь с этой частью документации по загрузке Spring

Если вам нужно выполнить инициализацию условно (возможно, только при запуске интеграционных тестов), вы можете воспользоваться профилями Spring. Что бы вы сделали в этом случае, так это чтобы файл свойств для тестового профиля содержал

spring.datasource.initialize=true

в то время как файл свойств для других профилей будет содержать

spring.datasource.initialize=false

Комментарии:

1. Спасибо за ваш ответ. Я попытался добавить файлы schema.sql и data.sql . Однако при этом данные будут загружаться из data.sql каждого запуска приложения. Мне нужно запустить это, если данные не были заполнены для их добавления. Есть ли способ указать подобные условия при запуске?

2. Что, если у меня есть модульный и интеграционный тесты, и я хочу запустить оба? На данный момент я могу запустить несколько интеграционных тестов, но когда я добавляю модульный тест, он завершается сбоем и сообщает мне, что таблица уже существует.

3. @tobi Было бы здорово увидеть, как именно выглядит ваш случай. Не могли бы вы создать новый вопрос со всеми соответствующими деталями и разместить ссылку здесь? Спасибо