Confuso sul modello di repository DDD a primavera dei dati
-
12-11-2019 - |
Domanda
Non so molto del modello di repository DDD, ma l'implementazione in primavera mi è confusione.
public interface PersonRepository extends JpaRepository<Person, Long> { … }
Man mano che l'interfaccia estende JParePository (o MongoDbrepository ...), se si cambia da un DB all'altro, devi anche cambiare l'interfaccia.
Per me un'interfaccia è lì per fornire un po 'di astrazione, ma qui non è tanto astratto ...
Sai perché i dati primaverili funzionano così?
Soluzione
Hai ragione, un'interfaccia è un'astrazione su qualcosa che funziona equivale a tutte le classi di implementazione, da un punto di vista esterno.
Ed è esattamente quello che succede qui:
- JParePository è una visione comune di tutti i tuoi repository JPA (per tutte le diverse entità), mentre MongoDbrepository è la stessa per tutte le entità MongoDB.
Ma JParepository e MongoDbrepository non hanno nulla in comune, tranne le cose che sono definite nelle super interfacce comuni:
- org.springframework.data.repository.pagingandsortingRepository
- org.springframework.data.repository.repository
Quindi per me sembra normale.
Se si utilizzano le classi che implementano il tuo repository, utilizzare PagingandSortingRepository o repository se si desidera essere in grado di passare da un'implementazione JPA a un'implementazione basata su documenti (scusa ma non riesco a immaginare un caso d'uso del genere - comunque). E, naturalmente, l'implementazione del repository dovrebbe implementare l'interfaccia corretta (JParePository, MongoDbrepository) a seconda di cosa sia.
Altri suggerimenti
Il ragionamento alla base di questo è chiaramente indicato in questo post sul blog http://blog.springsource.com/2011/02/10/getting-started-with-spring-data-jpa/.
Definizione di questa interfaccia ha due scopi: in primo luogo, estendendo JParePository otteniamo un sacco di metodi CRUD generici nel nostro tipo che consente di salvare gli account, eliminarli e così via. In secondo luogo, ciò consentirà all'infrastruttura del repository JPA dei dati di Spring di scansionare il percorso di classe per questa interfaccia e creare un bean a molla per esso.
Se non ti fidi delle fonti così vicine alla fonte (gioco di parole previsto) potrebbe essere una buona idea leggere anche questo post http://www.brucephillips.name/blog/index.cfm/2011/3/25/using-spring-data-jpa-to-redoced-data-access-coding.
Ciò che non avevo bisogno di codificare è un'implementazione dell'interfaccia di PersonRepository. Spring creerà un'implementazione di questa interfaccia e renderà disponibile un fagiolo di PersonRepository per essere autowired nella mia classe di servizio. Il Bean PersonRepository avrà tutti i metodi CRUD standard (che saranno transazionali) e restituiscono oggetti della persona o raccolta di oggetti persone. Quindi, utilizzando Spring Data JPA, ho salvato scrivendo la mia classe di implementazione.
Fino a M2 dei dati primaverili abbiamo richiesto agli utenti di estendere JpaRepository
Per i seguenti motivi:
- L'infrastruttura di scansione di ClassPath ha raccolto solo interfacce che estendono quell'interfaccia come si potrebbe utilizzare i dati di primavera JPA e Spring Data Mongo in parallelo e hanno entrambi indicato lo stesso pacchetto in cui non sarebbe chiaro quale archivia per creare il proxy. Tuttavia, dal momento che RC1 lasciamo semplicemente questo onere per lo sviluppatore poiché pensiamo che sia un caso piuttosto esotico e il vantaggio di usare
Repository
,CrudRepository
O gli Outweights simili è lo sforzo che devi intraprendere nel caso angolare appena descritto. Puoi usareexclude
einclude
Elementi nello spazio dei nomi per ottenere un controllo a grana più fine su questo. - Fino a M2 abbiamo avuto la transazionalità applicata ai metodi CRUD ridisegnando i metodi CRUD e annotarli con
@Transactional
. Questa decisione a sua volta è stata guidata dall'algoritmoAnnotationTransactionAttributeSource
Usi per trovare la configurazione delle transazioni. Dato che volevamo fornire all'utente la possibilità di riconfigurare le transazioni semplicemente ridisegnando un metodo CRUD nell'interfaccia del repository in calcestruzzo e applicando@Transactional
su di esso. Per RC1 abbiamo deciso di implementare un'usanzaTransactionAttributeSource
Essere in grado di riportare le annotazioni all'implementazione del repository CRUD.
Per farla breve, ecco cosa si riduce a:
A partire da RC1 non è più necessario estendere l'interfaccia del repository specifico dell'archivio, tranne tu vuoi…
- Uso
List
-Stembled Access afindAll(…)
invece diIterable
-basato uno nelle interfacce di repository più core (sebbene tu possa semplicemente ridipingere i metodi pertinenti in un'interfaccia di base comune per restituireList
anche s) - Vuoi utilizzare i metodi specifici per JPA come
saveAndFlush(…)
e così via.
Generalmente sei molto più flessibile riguardo all'esposizione dei metodi CRUD poiché RC1 come puoi anche estendere il Repository
interfaccia marcatore e aggiungi selettivamente i metodi CRUD che si desidera esporre. Poiché l'implementazione di supporto implementerà comunque tutti i metodi di PagingAndSortingRepository
Possiamo ancora instradare le chiamate all'istanza:
public interface MyBaseRepository<T, ID extends Serializable> extends Repository<T, ID> {
List<T> findAll();
T findOne(ID id);
}
public interface UserRepository extends MyBaseRepository<User, Long> {
List<T> findByUsername(String username);
}
In questo esempio definiamo MyBaseRepository
per esporre solo findAll()
e findOne(…)
(che verrà instradato nell'istanza che implementa i metodi CRUD) e il repository concreto che aggiunge un metodo Finder ai due CRUD.
Per maggiori dettagli su quell'argomento, consultare il Documentazione di riferimento.