Java >> Java tutorial >  >> Tag >> Spring

Hurtig vejledning om indlæsning af indledende data med fjederstart

1. Oversigt

Spring Boot gør det virkelig nemt at administrere vores databaseændringer. Hvis vi forlader standardkonfigurationen, vil den søge efter enheder i vores pakker og oprette de respektive tabeller automatisk.

Men vi får nogle gange brug for mere finkornet kontrol over databaseændringerne. Og det er, når vi kan bruge data.sql og schema.sql filer i foråret.

Yderligere læsning:

Forårsstart med H2-database

Lær, hvordan du konfigurerer og bruger H2-databasen med Spring Boot. Læs mere →

Databasemigrationer med Flyway

Denne artikel beskriver nøglebegreberne for Flyway, og hvordan vi kan bruge denne ramme til løbende at ombygge vores applikations databaseskema pålideligt og nemt.Læs mere →

Generer databaseskema med Spring Data JPA

JPA leverer en standard for generering af DDL fra vores enhedsmodel. Her undersøger vi, hvordan man gør dette i Spring Data og sammenligner det med native Hibernate.Læs mere →

2. Den data.sql Fil

Lad os også her antage, at vi arbejder med JPA og definere et simpelt land enhed i vores projekt:

@Entity
public class Country {

    @Id
    @GeneratedValue(strategy = IDENTITY)
    private Integer id;
    
    @Column(nullable = false)
    private String name;

    //...
}

Hvis vi kører vores applikation, Spring Boot opretter en tom tabel til os, men vil ikke udfylde den med noget.

En nem måde at gøre dette på er at oprette en fil med navnet data.sql :

INSERT INTO country (name) VALUES ('India');
INSERT INTO country (name) VALUES ('Brazil');
INSERT INTO country (name) VALUES ('USA');
INSERT INTO country (name) VALUES ('Italy');

Når vi kører projektet med denne fil på klassestien, vil Spring samle den op og bruge den til at udfylde databasen.

3. Den schema.sql Fil

Nogle gange ønsker vi ikke at stole på standardmekanismen til oprettelse af skemaer.

I sådanne tilfælde kan vi oprette en tilpasset schema.sql fil:

CREATE TABLE country (
    id   INTEGER      NOT NULL AUTO_INCREMENT,
    name VARCHAR(128) NOT NULL,
    PRIMARY KEY (id)
);

Spring vil samle denne fil op og bruge den til at oprette et skema.

Bemærk venligst, at script-baseret initialisering, dvs. gennem schema.sql og data.sql og Dvale initialisering sammen kan forårsage nogle problemer.

Enten deaktiverer vi Hibernate automatisk skemaoprettelse:

spring.jpa.hibernate.ddl-auto=none

Dette vil sikre, at script-baseret initialisering udføres ved hjælp af schema.sql og data.sql direkte.

Hvis vi stadig ønsker at have både Hibernate automatisk skemagenerering i konjugering med script-baseret skemaoprettelse og datapopulation, bliver vi nødt til at bruge:

spring.jpa.defer-datasource-initialization=true

Dette sikrer, at efter oprettelse af Hibernate-skemaet er udført, derefter schema.sql læses for eventuelle yderligere skemaændringer og data.sql udføres for at udfylde databasen.

Desuden udføres script-baseret initialisering som standard kun for indlejrede databaser, for altid at initialisere en database ved hjælp af scripts, skal vi bruge:

spring.sql.init.mode=always

Se venligst den officielle Spring-dokumentation om initialisering af databaser ved hjælp af SQL-scripts.

4. Styring af databaseoprettelse ved hjælp af Hibernate

Spring giver en JPA-specifik ejendom, som Hibernate bruger til DDL-generering: spring.jpa.hibernate.ddl-auto .

Standardværdierne for Hibernate-egenskaber er createopdateringopret-slipvalider og ingen :

  • opret – Hibernate sletter først eksisterende tabeller og opretter derefter nye tabeller.
  • opdatering – Objektmodellen, der er oprettet baseret på tilknytningerne (annoteringer eller XML), sammenlignes med det eksisterende skema, og derefter opdaterer Hibernate skemaet i henhold til diff. Den sletter aldrig de eksisterende tabeller eller kolonner, selvom de ikke længere kræves af programmet.
  • opret-slip – ligner opret , med den tilføjelse, at Hibernate vil droppe databasen, når alle handlinger er afsluttet; bruges typisk til enhedstestning
  • valider – Hibernate validerer kun, om tabellerne og kolonnerne eksisterer; ellers giver det en undtagelse.
  • ingen – Denne værdi slår effektivt DDL-genereringen fra.

Spring Boot indstiller internt denne parameterværdi til create-drop hvis der ikke er fundet nogen skemaadministrator, ellers ingen for alle andre tilfælde.

Vi skal indstille værdien omhyggeligt eller bruge en af ​​de andre mekanismer til at initialisere databasen.

5. Tilpasning af oprettelse af databaseskema

Som standard opretter Spring Boot automatisk skemaet for en integreret DataSource .

Hvis vi har brug for at kontrollere eller tilpasse denne adfærd, kan vi bruge egenskaben spring.sql.init.mode . Denne egenskab har en af ​​tre værdier:

  • altid – initialiser altid databasen
  • indlejret – initialiser altid, hvis en indlejret database er i brug. Dette er standard, hvis egenskabsværdien ikke er angivet.
  • aldrig – initialiser aldrig databasen

Især, hvis vi bruger en ikke-indlejret database, lad os sige MySQL eller PostGreSQL, og ønsker at initialisere dens skema, bliver vi nødt til at indstille denne egenskab til altid .

Denne egenskab blev introduceret i Spring Boot 2.5.0; vi skal bruge spring.datasource.initialization-mode hvis vi bruger tidligere versioner af Spring Boot.

6. @Sql

Spring giver også @Sql annotation — en deklarativ måde at initialisere og udfylde vores testskema.

Lad os se, hvordan du bruger @Sql annotation for at oprette en ny tabel og også indlæse tabellen med indledende data til vores integrationstest:

@Sql({"/employees_schema.sql", "/import_employees.sql"})
public class SpringBootInitialLoadIntegrationTest {

    @Autowired
    private EmployeeRepository employeeRepository;

    @Test
    public void testLoadDataForTestClass() {
        assertEquals(3, employeeRepository.findAll().size());
    }
}

Her er attributterne for @Sql anmærkning:

  • konfiguration –  lokal konfiguration for SQL-scripts. Vi beskriver dette i detaljer i næste afsnit.
  • udførelsesfase – Vi kan også angive, hvornår scripterne skal udføres, enten BEFORE_TEST_METHOD eller AFTER_TEST_METHOD .
  • udsagn – Vi kan erklære inline SQL-sætninger, der skal udføres.
  • scripts – Vi kan erklære stierne til SQL-scriptfiler, der skal udføres. Dette er et alias for værdien  attribut.

@Sql annotation kan bruges på klasse- eller metodeniveau.

Vi indlæser yderligere data, der kræves for et bestemt testtilfælde ved at annotere denne metode:

@Test
@Sql({"/import_senior_employees.sql"})
public void testLoadDataForTestCase() {
    assertEquals(5, employeeRepository.findAll().size());
}

7. @SqlConfig

Vi kan konfigurere den måde, vi parser og kører SQL-scripts på ved at bruge @SqlConfig anmærkning.

@SqlConfig kan erklæres på klasseniveau, hvor det fungerer som en global konfiguration. Eller vi kan bruge det til at konfigurere en bestemt @Sql anmærkning.

Lad os se et eksempel, hvor vi specificerer kodningen af ​​vores SQL-scripts samt transaktionstilstanden til udførelse af scripts:

@Test
@Sql(scripts = {"/import_senior_employees.sql"}, 
  config = @SqlConfig(encoding = "utf-8", transactionMode = TransactionMode.ISOLATED))
public void testLoadDataForTestCase() {
    assertEquals(5, employeeRepository.findAll().size());
}

Og lad os se på de forskellige attributter for @SqlConfig :

  • blokCommentStartDelimiter – afgrænsning for at identificere starten af ​​blokkommentarer i SQL-scriptfiler
  • blokCommentEndDelimiter – afgrænsningstegn for at angive slutningen af ​​blokkommentarer i SQL-scriptfiler
  • kommentarpræfiks – præfiks for at identificere enkeltlinjekommentarer i SQL-scriptfiler
  • datakilde – navnet på javax.sql.DataSource bean, som scripts og sætninger vil blive kørt imod
  • kodning – kodning til SQL-scriptfilerne; standard er platformkodning
  • errorMode – tilstand, der vil blive brugt, når der opstår en fejl ved at køre scripts
  • separator – streng, der bruges til at adskille individuelle udsagn; standard er “–“
  • TransactionManager – bønnenavnet på PlatformTransactionManager  der vil blive brugt til transaktioner
  • transaktionstilstand – den tilstand, der vil blive brugt ved udførelse af scripts i transaktion

8. @SqlGroup

Java 8 og nyere tillader brug af gentagne annoteringer. Vi kan bruge denne funktion til @Sql også anmærkninger. For Java 7 og derunder er der en containerannotation — @SqlGroup .

Brug af @SqlGroup annotering, erklærer vi flere @Sql anmærkninger :

@SqlGroup({
  @Sql(scripts = "/employees_schema.sql", 
    config = @SqlConfig(transactionMode = TransactionMode.ISOLATED)),
  @Sql("/import_employees.sql")})
public class SpringBootSqlGroupAnnotationIntegrationTest {

    @Autowired
    private EmployeeRepository employeeRepository;

    @Test
    public void testLoadDataForTestCase() {
        assertEquals(3, employeeRepository.findAll().size());
    }
}

9. Konklusion

I denne hurtige artikel så vi, hvordan vi kan udnytte schema.sql og data.sql filer til at opsætte et indledende skema og udfylde det med data.

Vi så også på, hvordan man bruger @Sql , @SqlConfig og @SqlGroup  annoteringer til at indlæse testdata til test.

Husk, at denne tilgang er mere velegnet til grundlæggende og simple scenarier, og enhver avanceret databasehåndtering ville kræve mere avanceret og raffineret værktøj som Liquibase eller Flyway.

Kodestykker kan som altid findes på GitHub.


Java tag