Ich frage mich, wie ich die ersten Datenbankdaten am besten laden kann, bevor die Anwendung gestartet wird. Was ich suche, ist etwas, das meine H2-Datenbank mit Daten füllt.
Zum Beispiel habe ich ein Domänenmodell "Benutzer". Ich kann auf Benutzer zugreifen, indem ich zu / users gehe, aber anfangs befinden sich keine Benutzer in der Datenbank, sodass ich sie erstellen muss. Gibt es überhaupt eine Möglichkeit, die Datenbank automatisch mit Daten zu füllen?
Im Moment habe ich eine Bean, die vom Container instanziiert wird und Benutzer für mich erstellt.
Beispiel:
@Component
public class DataLoader {
private UserRepository userRepository;
@Autowired
public DataLoader(UserRepository userRepository) {
this.userRepository = userRepository;
LoadUsers();
}
private void LoadUsers() {
userRepository.save(new User("lala", "lala", "lala"));
}
}
Aber ich bezweifle sehr, dass dies der beste Weg ist. Oder ist es?
spring
spring-boot
spring-data
Lithicas
quelle
quelle
data.sql
und / oderschema.sql
initiieren. All dies ist im Referenzhandbuch dokumentiert (das ich zum Lesen empfehle).Antworten:
Sie können einfach eine data.sql- Datei in Ihrem Ordner src / main / resources erstellen, die beim Start automatisch ausgeführt wird. In dieser Datei fügen Sie einfach einige Einfügeanweisungen hinzu, z.
In ähnlicher Weise können Sie auch eine schema.sql- Datei (oder schema-h2.sql) erstellen, um Ihr Schema zu erstellen:
Normalerweise sollten Sie dies nicht tun müssen, da Spring Boot Hibernate bereits so konfiguriert, dass Ihr Schema basierend auf Ihren Entitäten für eine In-Memory-Datenbank erstellt wird. Wenn Sie schema.sql wirklich verwenden möchten, müssen Sie diese Funktion deaktivieren, indem Sie sie zu Ihren application.properties hinzufügen:
Weitere Informationen finden Sie in der Dokumentation zur Datenbankinitialisierung .
Wenn Sie Spring Boot 2 verwenden , funktioniert die Datenbankinitialisierung nur für eingebettete Datenbanken (H2, HSQLDB, ...). Wenn Sie es auch für andere Datenbanken verwenden möchten, müssen Sie die
spring.datasource.initialization-mode
Eigenschaft ändern :Wenn Sie mehrere Datenbankanbieter verwenden, können Sie Ihre Datei data-h2.sql oder data-mysql.sql benennen, je nachdem, welche Datenbankplattform Sie verwenden möchten.
Damit dies funktioniert, müssen Sie die
spring.datasource.platform
Eigenschaft jedoch konfigurieren :quelle
schema.sql
/data.sql
Dateien werden ausgeführt, wenn esspring.datasource.initialize
isttrue
(was die Standardeinstellung ist).spring.jpa.hibernate.ddl-auto
kann verwendet werden, um Ihre Tabellen basierend auf Ihrer Entitätskonfiguration zu generieren, anstatt eine SQL-Datei zu verwenden. Dies ist in speicherinternen Datenbanken standardmäßig aktiviert. Aus diesem Grund habe ich den Hinweis in meine Antwort eingefügt und erklärt, dass Sie, wenn Sie eine In-Memory-Datenbank verwenden und die verwenden möchten, dieseschema.sql
deaktivieren müssen, daspring.jpa.hibernate.ddl-auto
sonst beide versuchen, Ihre Tabelle zu erstellen.data-h2.sql
Dateinamen für Ihre Anfangsdaten verwenden möchten , sollten Sie dies auchspring.datasource.platform=h2
in Ihren Anwendungseigenschaften festlegen .org.h2.jdbc.JdbcSQLException
Ausnahme verursachen können, da die Daten bereits in der Datenbank vorhanden sind. Ich verwende eine eingebettete H2-Datenbank, aber das Problem bleibt gleich.MERGE INTO
. Ich habe herausgefunden, dass es eine Möglichkeit gibt, dies mithilfe einer import.sql- Datei anstelle einer data.sql zu umgehen . Es erfordertspring.jpa.hibernate.ddl-auto
zu erstellen oder erstellen Drop . Wenn dann die Schemadatei erstellt wird (und / oder eine schema.sql ausgeführt wird), wird auch die import.sql ausgeführt. Dennoch: Es fühlt sich wie eine Problemumgehung an und nicht wie eine saubere Implementierung des Erstellens von Init-Daten.Wenn ich nur einfache Testdaten einfügen möchte, implementiere ich oft a
ApplicationRunner
. Implementierungen dieser Schnittstelle werden beim Start der Anwendung ausgeführt und können beispielsweise ein automatisch verdrahtetes Repository zum Einfügen einiger Testdaten verwenden.Ich denke, eine solche Implementierung wäre etwas expliziter als Ihre, da die Schnittstelle impliziert, dass Ihre Implementierung etwas enthält, das Sie direkt nach der Fertigstellung Ihrer Anwendung ausführen möchten.
Ihre Implementierung würde etw aussehen. so was:
quelle
Als Vorschlag versuchen Sie Folgendes:
Option 2: Initialisieren Sie mit Schema- und Datenskripten
Voraussetzungen: in müssen
application.properties
Sie Folgendes erwähnen:spring.jpa.hibernate.ddl-auto=none
(Andernfalls werden Skripte vom Ruhezustand ignoriert und das Projekt wird nach Klassen@Entity
und / oder@Table
kommentierten Klassen durchsucht.)Fügen Sie dann in Ihrer
MyApplication
Klasse Folgendes ein:Wo sich der
scripts
Ordner unter demresources
Ordner befindet (IntelliJ Idea)Hoffe es hilft jemandem
quelle
Sie können
spring.datasource.data
derapplication.properties
Liste der SQL-Dateien, die Sie ausführen möchten, eine Eigenschaft hinzufügen . So was:Die SQL-Insert-Anweisungen in jeder dieser Dateien werden dann ausgeführt, damit Sie die Dinge sauber halten können.
Wenn Sie die Dateien in den Klassenpfad einfügen, werden
src/main/resources
sie beispielsweise angewendet. Oder ersetzen Sieclasspath:
durchfile:
und verwenden Sie einen absoluten Pfad zur Dateiquelle
file:
stattdessen zu setzenclasspath:
.Sie können so etwas verwenden:
quelle
Mit Spring Boot können Sie ein einfaches Skript verwenden, um Ihre Datenbank mithilfe von Spring Batch zu initialisieren .
Wenn Sie jedoch etwas ausgefeilteres zum Verwalten von DB-Versionen usw. verwenden möchten, lässt sich Spring Boot gut in Flyway integrieren .
Siehe auch:
quelle
In Spring Boot 2 funktionierte data.sql bei mir nicht wie in Spring Boot 1.5
Darüber hinaus
import.sql
wird beim Start eine Datei mit dem Namen im Stammverzeichnis des Klassenpfads ausgeführt, wenn Hibernate das Schema von Grund auf neu erstellt (dh wenn die Eigenschaft ddl-auto auf create oder create-drop festgelegt ist).Beachten Sie, dass es sehr wichtig ist, wenn Sie Schlüssel einfügen, die nicht dupliziert werden können. Verwenden Sie nicht die Eigenschaft ddl-auto, die aktualisiert werden soll, da bei jedem Neustart dieselben Daten erneut eingefügt werden
Weitere Informationen finden Sie auf der Spring-Website
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html
quelle
So habe ich das verstanden:
Vielen Dank an den Autor dieses Artikels:
http://blog.netgloo.com/2014/11/13/run-code-at-spring-boot-startup/
quelle
Sie können einfach eine
import.sql
Datei in erstellensrc/main/resources
und Hibernate führt sie aus, wenn das Schema erstellt wird.quelle
Ich habe ein ähnliches Problem folgendermaßen gelöst:
quelle
Wenn jemand Schwierigkeiten hat, dies auch nach der akzeptierten Antwort zum Laufen zu bringen, füge ich nur
src/test/resources/application.yml
die H2-datasource
Details hinzu:quelle
Sie können sich registrieren und einen Ereignis-Listener einrichten, um dies wie folgt zu erreichen:
Wenn das ContextRefreshEvent ausgelöst wird, erhalten wir Zugriff auf alle automatisch verdrahteten Beans in der Anwendung - einschließlich Modelle und Repositorys.
quelle
Wenn Sie nur wenige Zeilen einfügen möchten und über ein JPA-Setup verfügen. Sie können unten verwenden
quelle
Dies wird auch funktionieren.
quelle
Die kompakteste (für dynamische Daten) Lösung von @ mathias-dpunkt in MainApp (mit Lombok
@AllArgsConstructor
):quelle
Du bist fast da!
quelle
Sie können den folgenden Code verwenden. Im folgenden Code erfolgt beim Starten der Spring-Boot-Anwendung eine Datenbankeinfügung.
quelle