Spring Data JPA Delete og Relationships

1. Oversigt

I denne vejledning ser vi på, hvordan sletning sker i Spring Data JPA.

2. Prøveenhed

Som vi kender fra Spring Data JPA-referencedokumentationen, giver repository-grænseflader os grundlæggende support til enheder.

Hvis vi har en enhed, som en Bestil:

@Entity public class Book {@Id @GeneratedValue private Lang id; privat streng titel; // standard konstruktører // standard getters og setters}

Derefter kan vi udvide JPA'er til Spring Data CrudRepository for at give os adgang til CRUD-operationer på Bestil:

@Repository offentlig grænseflade BookRepository udvider CrudRepository {}

3. Slet fra lageret

Blandt andre, CrudRepository indeholder to metoder: deleteById og slet alt.

Lad os teste disse metoder direkte fra vores BookRepository:

@RunWith (SpringRunner.class) @SpringBootTest (klasser = {Application.class}) offentlig klasse DeleteFromRepositoryUnitTest {@Autowired private BookRepository repository; Bogbog1; Bogbog2; Listebøger; // datainitiering @ Test offentlig ugyldig nårDeleteByIdFromRepository_thenDeletingShouldBeSuccessful () {repository.deleteById (book1.getId ()); assertThat (repository.count ()). er EqualTo (1); } @Test offentlig ugyldig nårDeleteAllFromRepository_thenRepositoryShouldBeEmpty () {repository.deleteAll (); assertThat (repository.count ()). er EqualTo (0); }}

Og selvom vi bruger CrudRepository, bemærk, at de samme metoder findes for andre Spring Data JPA-grænseflader som f.eks JpaRepository eller PagingAndSortingRepository.

4. Afledt Slet forespørgsel

Vi kan også udlede forespørgselsmetoder til sletning af enheder. Der er et sæt regler for at skrive dem, men lad os bare fokusere på det enkleste eksempel.

En afledt sletningsforespørgsel skal starte med deleteByefterfulgt af navnet på udvælgelseskriterierne. Disse kriterier skal angives i metodekaldet.

Lad os sige, at vi vil slette Bestils ved titel. Ved hjælp af navngivningskonventionen ville vi starte med deleteBy og liste titel som vores kriterier:

@Repository offentlig grænseflade BookRepository udvider CrudRepository {long deleteByTitle (String title); }

Returneringsværdien af ​​typen lang, angiver, hvor mange poster metoden er slettet.

Lad os skrive en test og sikre os, at det er korrekt:

@Test @Transactional public void whenDeleteFromDerivedQuery_thenDeletingShouldBeSuccessful () {long deleteRecords = repository.deleteByTitle ("The Hobbit"); assertThat (deleteRecords) .isEqualTo (1); }

At opretholde og slette objekter i JPA kræver en transaktion, det er derfor, vi skal bruge en @Transaktionel kommentar, når du bruger disse afledte sletningsforespørgsler for at sikre, at en transaktion kører. Dette forklares detaljeret i ORM med Spring-dokumentation.

5. Custom Slet forespørgsel

Metodenavnene for afledte forespørgsler kan blive ret lange, og de er begrænset til kun en enkelt tabel.

Når vi har brug for noget mere komplekst, kan vi skrive en brugerdefineret forespørgsel ved hjælp af @Forespørgsel og @Modifying sammen.

Lad os kontrollere den tilsvarende kode for vores afledte metode fra tidligere:

@Modifying @Query ("slet fra bog b hvor b.title =: titel") ugyldig deleteBooks (@Param ("titel") streng titel);

Igen kan vi kontrollere, at det fungerer med en simpel test:

@Test @Transactional public void whenDeleteFromCustomQuery_thenDeletingShouldBeSuccessful () {repository.deleteBooks ("The Hobbit"); assertThat (repository.count ()). er EqualTo (1); }

Begge løsninger præsenteret ovenfor er ens og opnår det samme resultat. De tager dog en lidt anden tilgang.

Det @Forespørgsel metoden opretter en enkelt JPQL-forespørgsel mod databasen. Til sammenligning er deleteBy metoder udfører en læseforespørgsel og sletter derefter hvert af elementerne en efter en.

6. Slet i forhold

Lad os nu se, hvad der sker, når vi har det forhold til andre enheder.

Antag, at vi har en Kategori enhed, der har en OneToMany tilknytning til Bestil enhed:

@Entity offentlig klasse Kategori {@Id @GeneratedValue privat Lang id; privat strengnavn; @OneToMany (mappedBy = "category", cascade = CascadeType.ALL, orphanRemoval = true) private listebøger; // standard konstruktører // standard getters og setters}

Det CategoryRepository kan bare være en tom grænseflade, der udvides CrudRepository:

@Repository offentlig grænseflade CategoryRepository udvider CrudRepository {}

Vi bør også ændre Bestil enhed, der afspejler denne tilknytning:

@ManyToOne privat kategorikategori;

Lad os nu tilføje to kategorier og knytte dem til de bøger, vi har i øjeblikket. Hvis vi nu prøver at slette kategorierne, slettes bøgerne også:

@Test offentlig ugyldigt nårDeletingCategories_thenBooksShouldAlsoBeDeleted () {categoryRepository.deleteAll (); assertThat (bookRepository.count ()). er EqualTo (0); assertThat (categoryRepository.count ()). er EqualTo (0); }

Dette er dog ikke tovejs. Det betyder, at hvis vi sletter bøgerne, er kategorierne der stadig:

@Test offentlig ugyldig nårDeletingBooks_thenCategoriesShouldAlsoBeDeleted () {bookRepository.deleteAll (); assertThat (bookRepository.count ()). er EqualTo (0); assertThat (categoryRepository.count ()). er EqualTo (2); }

Vi kan ændre denne adfærd ved at ændre egenskaberne for forholdet, f.eks CascadeType.

7. Konklusion

I denne artikel kiggede vi på forskellige måder at slette enheder i Spring Data JPA på. Vi kiggede på de medfølgende sletningsmetoder fra CrudRepository, såvel som vores afledte forespørgsler eller brugerdefinerede ved hjælp af @Forespørgsel kommentar.

Vi kiggede også på, hvordan sletning sker i forhold. Som altid kan alle kodestykker, der er nævnt i denne artikel, findes i vores GitHub-lager.


$config[zx-auto] not found$config[zx-overlay] not found