Spring Data JPA Delete and Relationships

1. Oversikt

I denne opplæringen vil vi se på hvordan sletting gjøres i Spring Data JPA.

2. Eksempel på enhet

Som vi vet fra Spring Data JPA-referansedokumentasjonen, gir lagringsgrensesnitt oss litt grunnleggende støtte for enheter.

Hvis vi har en enhet, som en Bok:

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

Deretter kan vi utvide JPA-er for Spring Data CrudRepository for å gi oss tilgang til CRUD-operasjoner på Bok:

@Repository offentlig grensesnitt BookRepository utvider CrudRepository {}

3. Slett fra depotet

Blant andre, CrudRepository inneholder to metoder: deleteById og slette alle.

La oss teste disse metodene direkte fra vår BookRepository:

@RunWith (SpringRunner.class) @SpringBootTest (klasser = {Application.class}) offentlig klasse DeleteFromRepositoryUnitTest {@Autowired private BookRepository repository; Bokbok1; Bokbok2; Listebøker; // datainitialisering @Test offentlig ugyldig nårDeleteByIdFromRepository_thenDeletingShouldBeSuccessful () {repository.deleteById (book1.getId ()); assertThat (repository.count ()). erEqualTo (1); } @Test offentlig ugyldig nårDeleteAllFromRepository_thenRepositoryShouldBeEmpty () {repository.deleteAll (); assertThat (repository.count ()). erEqualTo (0); }}

Og selv om vi bruker CrudRepository, merk at de samme metodene eksisterer for andre Spring Data JPA-grensesnitt som JpaRepository eller PagingAndSortingRepository.

4. Derived Delete Query

Vi kan også utlede spørringsmetoder for å slette enheter. Det er et sett med regler for å skrive dem, men la oss bare fokusere på det enkleste eksemplet.

Et avledet slettingsforespørsel må starte med deleteBy, etterfulgt av navnet på utvalgskriteriene. Disse kriteriene må oppgis i metodeanropet.

La oss si at vi vil slette Boks av tittel. Ved å bruke navnekonvensjonen ville vi begynne med deleteBy og liste tittel som våre kriterier:

@Repository offentlig grensesnitt BookRepository utvider CrudRepository {long deleteByTitle (strengtittel); }

Returverdien, av typen lang, angir hvor mange poster metoden slettet.

La oss skrive en test og sørge for at den er riktig:

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

Å vedvare og slette objekter i JPA krever en transaksjon, det er derfor vi bør bruke en @Transaksjonell kommentar når du bruker disse avledede slettingsspørsmålene, for å sikre at en transaksjon kjører. Dette er forklart i detalj i ORM med vårdokumentasjon.

5. Tilpasset slett spørring

Metodenavnene for avledede spørsmål kan bli ganske lange, og de er begrenset til bare en enkelt tabell.

Når vi trenger noe mer komplekst, kan vi skrive et tilpasset spørsmål ved hjelp av @Spørsmål og @Modifying sammen.

La oss sjekke ekvivalent kode for vår avledede metode fra tidligere:

@Modifying @Query ("slett fra bok b hvor b.title =: tittel") ugyldig deleteBooks (@Param ("tittel") streng tittel);

Igjen kan vi bekrefte at det fungerer med en enkel test:

@Test @Transactional public void whenDeleteFromCustomQuery_thenDeletingShouldBeSuccessful () {repository.deleteBooks ("Hobbiten"); assertThat (repository.count ()). erEqualTo (1); }

Begge løsningene som er presentert ovenfor er like og oppnår samme resultat. Imidlertid tar de en litt annen tilnærming.

De @Spørsmål metoden oppretter et enkelt JPQL-spørsmål mot databasen. Til sammenligning, den deleteBy metoder utfører en lesespørring, og deretter sletter du hvert av elementene en etter en.

6. Slett i forhold

La oss nå se hva som skjer når vi har det forhold til andre enheter.

Anta at vi har en Kategori enhet, som har en OneToMany tilknytning til Bok enhet:

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

De CategoryRepository kan bare være et tomt grensesnitt som strekker seg CrudRepository:

@Repository offentlig grensesnitt CategoryRepository utvider CrudRepository {}

Vi bør også endre Bok enhet som gjenspeiler denne tilknytningen:

@ManyToOne privat kategorikategori;

La oss nå legge til to kategorier og knytte dem til bøkene vi har for øyeblikket. Nå, hvis vi prøver å slette kategoriene, vil bøkene også bli slettet:

@Test offentlig ugyldig nårDeletingCategories_thenBooksShouldAlsoBeDeleted () {categoryRepository.deleteAll (); assertThat (bookRepository.count ()). erEqualTo (0); assertThat (categoryRepository.count ()). erEqualTo (0); }

Dette er imidlertid ikke toveis. Det betyr at hvis vi sletter bøkene, er kategoriene fortsatt der:

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

Vi kan endre denne oppførselen ved å endre egenskapene til forholdet, for eksempel CascadeType.

7. Konklusjon

I denne artikkelen så vi på forskjellige måter å slette enheter i Spring Data JPA. Vi så på de medfølgende slettemetodene fra CrudRepository, samt våre avledede spørsmål eller tilpassede spørsmål som bruker @Spørsmål kommentar.

Vi har også sett på hvordan sletting gjøres i forhold. Som alltid kan alle kodebitene som er nevnt i denne artikkelen finnes på GitHub-depotet vårt.


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