Spring Web Application: что-то делать при запуске (инициализация) - PullRequest
7 голосов
/ 13 марта 2012

Я хочу заполнить некоторые таблицы моей БД из текстового файла при запуске, я хочу, чтобы мой метод инициализации вызывался только тогда, когда мое приложение действительно запускается.

Я использую Spring (+ MVC) и Hibernate с MySQL.

как мне это сделать?

Ответы [ 6 ]

17 голосов
/ 13 марта 2012

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

@Component
public class DatabaseFillerOnStartup implements ApplicationListener<ContextRefreshedEvent> {
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        ...
    }
}
7 голосов
/ 13 марта 2012

В Hibernate есть способ добавить некоторые файлы с инструкциями sql, которые будут выполняться при запуске.

Параметр hibernate.hbm2ddl.import_files.

@ См. Hibernate Ссылка: Глава 3.4. Дополнительные свойства конфигурации

  • Таблица 3.7. Разные свойства
  • hibernate.hbm2ddl.import_files:

Разделенные запятыми имена необязательных файлов, содержащих SQL DML операторы, выполненные во время создания SessionFactory. Это полезно для тестирования или демонстрации: добавив операторы INSERT, например, вы может заполнить вашу базу данных минимальным набором данных, когда это развертывается.

Порядок файлов имеет значение, операторы данного файла выполняются раньше утверждения следующих файлов. Эти заявления только выполняется, если схема создана, т.е. если установлен hibernate.hbm2ddl.auto создать или создать-отбросить.

например. /humans.sql,/dogs.sql

Мне нравятся некоторые подсказки, что это может сработать, только если hibernate запущен в режиме 'create'. Но я не уверен.

5 голосов
/ 13 марта 2012

Используйте постконструктивную аннотацию где-то внутри компонента:

@PostConstruct
public void init() {
     //startup logic here
}

Возможно, имеет (desgin) смысл использовать компонент конфигурации, но это может быть любой компонент вообще.

0 голосов
/ 08 февраля 2018

Если для вашего свойства hibernate.hbm2ddl.auto установлено значение create или create-drop, тогда проще всего это сделать, установив свойство hibernate.hbm2ddl.import_files с именем файла SQL, содержащим операторы SQL, для загрузки ваших исходных данных в базу данных. схема, например первоначальные пользователи приложения.

Ниже приведен пример метода, который есть в моем классе DatabaseConfig. Он устанавливает hibernate.hbm2ddl.import_files свойство с именем файла SQL import_initial_data.sql , которое содержит операторы SQL Insert для загрузки моих исходных данных в схему базы данных.

   @Bean
   public LocalSessionFactoryBean hibernate5SessionFactoryBean(){
      LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
      localSessionFactoryBean.setDataSource((DataSource) appContext.getBean("DataSource"));
      localSessionFactoryBean.setAnnotatedClasses( AppUser.class );
      Properties properties = new Properties();
      properties.put( "hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
      properties.put("hibernate.hbm2ddl.auto","create-drop");
      properties.put("hibernate.hbm2ddl.import_files", "import_initial_data.sql");
      properties.put("hibernate.show_sql","true");
      localSessionFactoryBean.setHibernateProperties(properties);
      return localSessionFactoryBean;
   }

Это мой AppUser.java в model упаковке:

package com.beniregev.model;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import javax.persistence.*;

@Entity
@NoArgsConstructor(access = AccessLevel.PUBLIC)
@AllArgsConstructor(access = AccessLevel.PUBLIC)
public class AppUser {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private int id;
   @Column(nullable = false, unique = true)
   private String userName;
   @Column(nullable = false)
   private String password;

   public AppUser(String userName, String password) {
      this.userName = userName;
      this.password = password;
   }
}

Зависимость Maven для ломбок :

<dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <version>1.16.6</version>
   <scope>provided</scope>
</dependency>

Файл import_initial_data.sql , который находится в каталоге resources:

INSERT INTO appuser(username, password) VALUES ('jesus', 'christ');
INSERT INTO appuser(username, password) VALUES ('mary', 'virgin');
INSERT INTO appuser(username, password) VALUES ('josef', 'who?');
INSERT INTO appuser(username, password) VALUES ('jeremaia', 'profet');
COMMIT;

И результат * SELECT * FROM appuser; *:

Resultset of SELECT * FROM appuser;

0 голосов
/ 16 сентября 2015

Вы можете создать некоторый bean-компонент в конфигурации корневого контекста - например,

<bean id="someBean" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="someProperty">
        ... description of the property
    </property>
    <property name="targetMethod" value="methodName" />
</bean>

Таким образом - при запуске приложения будет вызываться метод "methodName".У нас есть обновления БД, реализованные таким образом.

0 голосов
/ 19 марта 2013

Два варианта,

Первый: пусть hibernate создаст ваш ddl при каждом запуске сервисов (только для локальной среды или среды разработки)

<bean id="hibernateVendor" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
      p:showSql="false"
      p:generateDdl="true"/>

Или создайте весной Bean с помощью init-lazy false и добавьте туда логику для создания базы данных, если у вас ее нет, или внедрите свой сценарий, или делайте что хотите.

 <bean id="bootstrapStartup" class="com.tscompany.rest.bootstrap.BootstrapStartup" lazy-init="false" init-method="init"/>
...