2012-03-13 6 views
7

Chcę wypełnić niektóre tabele mojego DB z pliku tekstowego przy starcie, chcę, aby moja metoda inicjalizacji była wywoływana tylko wtedy, gdy moja aplikacja się uruchomi.Spring Web Application: robienie czegoś na starcie (inicjalizacja)

Używam Spring (+ MVC) i Hibernate z MySQL.

jak mogę zrobić?

+0

możliwe duplikat [wiosennej inicjalizacji aplikacji internetowych z bazy danych na starcie] (http://stackoverflow.com/questions/ 7082594/Spring-web-application-initialization-from-database-on-startup) –

+1

@Tomasz Nurkiewicz: nie jest duplikatem http://stackoverflow.com/questions/7082594/spring-web-application-initialization- from -bazy danych-na starcie, ponieważ przepływ informacji jest odwrotnie, więc można użyć innych sposobów rozwiązania problemu. – Ralph

+0

Jest bardzo podobny. Mój jest trochę bardziej ogólny. –

Odpowiedz

5

Użyj adnotacji postconstuct gdzieś wewnątrz fasoli:

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

Prawdopodobnie czyni (Desgin) poczucie użyć fasoli konfiguracji, ale może to być dowolny fasoli w ogóle.

+0

OK, więc właściwą drogą może być wykonanie "Inicjatora" singleton i @PostConstruct a method? Dziękuję Ci! :) –

+0

To nie działa przy uruchamianiu AsyncTasks. Skorzystaj z poniższej rekomendacji sinuhepop - http://stackoverflow.com/a/9680800/1019307 – HankCa

7

Hibernacja jest wyposażony w sposób dodawania plików z instrukcjami SQL, które będą wykonywane podczas uruchamiania.

Parametr to hibernate.hbm2ddl.import_files.

@See Hibernate Reference: Chapter 3.4. Optional configuration properties

  • Tabela 3.7. Różne właściwości
  • hibernate.hbm2ddl.import_files:

oddzielone przecinkami nazwiskami opcjonalnych plików zawierających SQL DML sprawozdania wykonywane podczas tworzenia SessionFactory. Jest to przydatne do testowania lub demonstrowania: dodając instrukcje INSERT, na przykład użytkownik może zapełnić bazę danych minimalnym zestawem danych po wdrożeniu .

Kolejność plików jest ważna, wyciągi z pliku podanego są wykonywane przed oświadczeniami następujących plików. Te instrukcje są wykonywane tylko pod warunkiem, że schemat zostanie utworzony, tzn. Jeśli hibernate.hbm2ddl.auto zostanie ustawione na w celu utworzenia lub utworzenia-upuszczenia.

np. /humans.sql,/dogs.sql

ja lubię kilka wskazówek, że to może działać tylko wtedy, hibernacja jest uruchamiana w trybie „tworzyć”. Ale nie jestem pewien.

+0

bardzo przydatna. To nie jest odpowiedź na to pytanie, ale ... TAK właśnie tego potrzebuję! DZIĘKUJĘ CI! Jednak nie mogę sprawić, aby import_files działał :(Zamiast tego wstawiam "import.sql" w mojej ścieżce klas, to działa perfekcyjnie! –

16

Można utworzyć program nasłuchujący aplikacji, zaprojektowany specjalnie dla takich potrzeb. W tym przypadku będzie on wykonywany za każdym razem, gdy kontekst zostanie uruchomiony (lub odświeżony).

@Component 
public class DatabaseFillerOnStartup implements ApplicationListener<ContextRefreshedEvent> { 
    @Override 
    public void onApplicationEvent(ContextRefreshedEvent event) { 
     ... 
    } 
} 
+0

użyteczne, dziękuję :) –

+0

Dokładnie to, czego szukałem, aby wykonać autodiagnostykę . Dziękuję Ci! – Marquee

+0

To powinna być odpowiedź ... :) –

0

dwie opcje,

pierwsze: Niech hibernacji utworzyć ddl spędzaj usługi jest startup (tylko dla lokalnego środowiska lub dev)

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

Albo tworzyć wiosną fasoli z init- leniwy fałszywy i dodaj tam logikę, aby utworzyć bazę danych, jeśli nie masz jej lub wstrzykujesz swój skrypt lub robisz, co chcesz.

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

Można utworzyć kilka fasoli w konfiguracji root-kontekstowego - jak

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

Zatem - na starcie aplikacji metodą "methodName" zostanie wywołany. W ten sposób wdrażamy uaktualnienia DB.

0

Jeśli nieruchomość hibernate.hbm2ddl.auto ustawiony create lub create-drop następnie najprostszy sposób na to jest poprzez ustawienie hibernate.hbm2ddl.import_files właściwość SQL nazwę pliku, który zawiera instrukcje SQL, aby załadować danych początkowych do schematu bazy danych, na przykład początkowi użytkownicy aplikacji.

Poniżej znajduje się przykładowa metoda, którą mam w mojej klasie DatabaseConfig. Ustawia ona właściwość hibernate.hbm2ddl.import_files o nazwie pliku SQL import_initial_data.sql, która zawiera instrukcje SQL Insert w celu załadowania moich początkowych danych do schematu bazy danych.

@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; 
    } 

To mój AppUser.java w model pakiet:

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; 
    } 
} 

zależność Maven dla Lombok:

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

import_initial_data.sql plik, który mam w resources katalogu:

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; 

a wynik * select * from appuser; *:

Resultset of SELECT * FROM appuser;