Spring Data MongoDB - Indekser, merknader og omformere
1. Oversikt
Denne opplæringen vil utforske noen av kjernefunksjonene i Spring Data MongoDB - indeksering, vanlige merknader og omformere.
2. Indekser
2.1. @Indexed
Denne kommentaren markerer feltet som indeksert i MongoDB:
@QueryEntity @Document offentlig klasse bruker {@Indexed privat strengnavn; ...}
Nå som Navn feltet er indeksert - la oss ta en titt på indeksene i MongoDB:
db.user.getIndexes ();
Her er hva vi har på databasenivå:
[{"v": 1, "key": {"_id": 1}, "name": "_id_", "ns": "test.user"}, {"v": 1, "key": {"name": 1}, "name": "name", "ns": "test.user"}]
Som du kan se, har vi to indekser - en av dem er _id - som ble opprettet som standard på grunn av @Id kommentar og den andre er vår Navn felt.
2.2. Lag en indeks programmatisk
Vi kan også lage en indeks programmatisk:
mongoOps.indexOps (User.class). sikreIndex (ny indeks (). on ("navn", Direction.ASC));
Vi har nå opprettet en indeks for feltet Navn og resultatet blir det samme som i forrige avsnitt.
2.3. Sammensatte indekser
MongoDB støtter sammensatte indekser, der en enkelt indeksstruktur inneholder referanser til flere felt.
La oss se et raskt eksempel ved å bruke sammensatte indekser:
@QueryEntity @Document @CompoundIndexes ({@CompoundIndex (name = "email_age", def = "{'email.id': 1, 'age': 1}")}) offentlig klasse bruker {//}
Vi opprettet en sammensatt indeks med e-post og alder Enger. La oss nå sjekke ut de faktiske indeksene:
{"v": 1, "key": {"email.id": 1, "age": 1}, "name": "email_age", "ns": "test.user"}
Merk at a DBRef feltet kan ikke merkes med @Index - det feltet kan bare være en del av en sammensatt indeks.
3. Vanlige merknader
3.1 @Flyktig
Som du forventer, ekskluderer denne enkle kommentaren feltet fra å være vedvarende i databasen:
offentlig klasse bruker {@Transient private Integer yearOfBirth;
// standard getter og setter}
La oss sette inn bruker med innstillingsfeltet fødselsår:
Brukerbruker = ny bruker (); user.setName ("Alex"); user.setYearOfBirth (1985); mongoTemplate.insert (bruker);
Nå hvis vi ser på tilstanden til databasen, ser vi at den arkiverte fødselsår ble ikke lagret:
{"_id": ObjectId ("55d8b30f758fd3c9f374499b"), "name": "Alex", "age": null}
Så hvis vi spør og sjekker:
mongoTemplate.findOne (Query.query (Criteria.where ("name"). is ("Alex")), User.class) .getYearOfBirth ()
Resultatet blir null.
3.2. @Felt
@Felt indikerer nøkkelen som skal brukes til feltet i JSON-dokumentet:
@Field ("e-post") privat EmailAddress emailAddress;
Nå epostadresse lagres i databasen ved hjelp av nøkkelen e-post:
Brukerbruker = ny bruker (); user.setName ("Brendan"); EmailAddress emailAddress = ny EmailAddress (); emailAddress.setValue ("[email protected]"); user.setEmailAddress (emailAddress); mongoTemplate.insert (bruker);
Og databasens tilstand:
{"_id": ObjectId ("55d076d80bad441ed114419d"), "name": "Brendan", "age": null, "email": {"value": "[email protected]"}}
3.3. @PersistenceConstructor og @Verdi
@PersistenceConstructor markerer en konstruktør, til og med en som er pakkebeskyttet, for å være den primære konstruktøren som brukes av utholdenhetslogikken. Konstruktørargumentene tilordnes med navn til nøkkelverdiene i den hentede DBObject.
La oss se på denne konstruktøren for vår Bruker klasse:
@PersistenceConstructor offentlig bruker (strengnavn, @Value ("# root.age?: 0") Heltal alder, EmailAddress emailAddress) {this.name = name; this.age = alder; this.emailAddress = emailAddress; }
Legg merke til bruken av standardfjæren @Verdi kommentar her. Det er ved hjelp av denne merknaden at vi kan bruke Spring Expressions til å transformere en nøkkelverdi hentet fra databasen før den brukes til å konstruere et domeneobjekt. Det er en veldig kraftig og svært nyttig funksjon her.
I vårt eksempel hvis alder er ikke satt til at det vil bli satt til 0 som standard.
La oss nå se hvordan det fungerer:
Brukerbruker = ny bruker (); user.setName ("Alex"); mongoTemplate.insert (bruker);
Databasen vår vil se ut:
{"_id": ObjectId ("55d074ca0bad45f744a71318"), "name": "Alex", "age": null}
Så alder feltet er null, men når vi spør etter dokumentet og henter det alder:
mongoTemplate.findOne (Query.query (Criteria.where ("name"). is ("Alex")), User.class) .getAge ();
Resultatet blir 0.
4. Omformere
La oss nå ta en titt på en annen veldig nyttig funksjon i Spring Data MongoDB - omformere, og spesielt på MongoConverter.
Dette brukes til å håndtere kartleggingen av alle Java-typer til DBO-objekter når du lagrer og spørre etter disse objektene.
Vi har to alternativer - vi kan enten jobbe med MappingMongoConverter - eller SimpleMongoConverter i tidligere versjoner (dette ble avviklet i Spring Data MongoDB M3 og funksjonaliteten er flyttet inn MappingMongoConverter). Eller vi kan skrive vår egen tilpassede omformer. For å gjøre det, må vi implementere Konverter grensesnitt og registrere implementeringen i MongoConfig. La oss se på et raskt eksempel. Som du har sett i noen av JSON-utdataene her, har alle objekter som er lagret i en database feltet _klasse som lagres automatisk. Hvis vi imidlertid vil hoppe over det aktuelle feltet under utholdenhet, kan vi gjøre det ved hjelp av a MappingMongoConverter. Først - her er den tilpassede konverteringsimplementeringen: Legg merke til hvordan vi lett kan nå målet om ikke å vedvare _klasse ved å spesifikt fjerne feltet direkte her. Nå må vi registrere den tilpassede omformeren: Vi kan selvfølgelig oppnå det samme resultatet med XML-konfigurasjon også hvis vi trenger å: Nå, når vi lagrer en ny bruker: Det resulterende dokumentet i databasen inneholder ikke lenger klasseinformasjonen: I denne veiledningen har vi dekket noen kjernekonsepter for å jobbe med Spring Data MongoDB - indeksering, vanlige merknader og omformere. Implementeringen av alle disse eksemplene og kodebiter finner du i mitt github-prosjekt.@Component public class UserWriterConverter implementerer Converter {@Override public DBObject convert (User user) {DBObject dbObject = new BasicDBObject (); dbObject.put ("navn", user.getName ()); dbObject.put ("alder", user.getAge ()); hvis (user.getEmailAddress ()! = null) {DBObject e-postDbObject = ny BasicDBObject (); emailDbObject.put ("verdi", user.getEmailAddress (). getValue ()); dbObject.put ("e-post", emailDbObject); } dbObject.removeField ("_ class"); returner dbObject; }}
privat liste
Brukerbruker = ny bruker (); user.setName ("Chris"); mongoOps.insert (bruker);
{"_id": ObjectId ("55cf09790bad4394db84b853"), "name": "Chris", "age": null}
5. Konklusjon