Spring Data MongoDB - Indexen, annotaties en converters

1. Overzicht

In deze tutorial zullen enkele van de kernfuncties van Spring Data MongoDB worden onderzocht - indexering, algemene annotaties en converters.

2. Indexen

2.1. @Indexed

Deze annotatie markeert het veld als geïndexeerd in MongoDB:

@QueryEntity @Document openbare klasse Gebruiker {@Indexed private String-naam; ...}

Nu dat de naam veld is geïndexeerd - laten we eens kijken naar de indexen in MongoDB:

db.user.getIndexes ();

Dit is wat we hebben op databaseniveau:

[{"v": 1, "key": {"_id": 1}, "name": "_id_", "ns": "test.user"}, {"v": 1, "key": {"name": 1}, "name": "name", "ns": "test.user"}]

Zoals u kunt zien, hebben we twee indexen - een daarvan is _ID kaart - die standaard is gemaakt vanwege de @ID kaart annotatie en de tweede is onze naam veld.

2.2. Maak programmatisch een index

We kunnen ook programmatisch een index maken:

mongoOps.indexOps (User.class). sureIndex (new Index (). on ("name", Direction.ASC)); 

We hebben nu een index voor het veld gemaakt naam en het resultaat zal hetzelfde zijn als in de vorige sectie.

2.3. Samengestelde indexen

MongoDB ondersteunt samengestelde indexen, waarbij een enkele indexstructuur verwijzingen naar meerdere velden bevat.

Laten we een snel voorbeeld bekijken met samengestelde indexen:

@QueryEntity @Document @CompoundIndexes ({@CompoundIndex (name = "email_age", def = "{'email.id': 1, 'age': 1}")}) openbare klasse Gebruiker {//}

We hebben een samengestelde index gemaakt met de e-mail en leeftijd velden. Laten we nu eens kijken naar de feitelijke indexen:

{"v": 1, "key": {"email.id": 1, "age": 1}, "name": "email_age", "ns": "test.user"} 

Merk op dat a DBRef veld kan niet worden gemarkeerd met @Inhoudsopgave - dat veld kan alleen deel uitmaken van een samengestelde index.

3. Algemene annotaties

3.1 @Transient

Zoals je zou verwachten, zorgt deze eenvoudige annotatie ervoor dat het veld niet in de database wordt bewaard:

openbare klasse Gebruiker {@Transient privé Geheel getal yearOfBirth;
 // standaard getter en setter}

Laten we de gebruiker invoegen met het instellingenveld geboortejaar:

Gebruiker gebruiker = nieuwe gebruiker (); user.setName ("Alex"); user.setYearOfBirth (1985); mongoTemplate.insert (gebruiker); 

Als we nu kijken naar de staat van de database, zien we dat het bestand is ingediend geboortejaar is niet opgeslagen:

{"_id": ObjectId ("55d8b30f758fd3c9f374499b"), "name": "Alex", "age": null}

Dus als we vragen en controleren:

mongoTemplate.findOne (Query.query (Criteria.where ("name"). is ("Alex")), User.class) .getYearOfBirth ()

Het resultaat zal zijn nul.

3.2. @Veld

@Veld geeft de sleutel aan die moet worden gebruikt voor het veld in het JSON-document:

@Field ("email") privé EmailAddress emailAddress; 

Nu e-mailadres wordt met de sleutel in de database opgeslagen e-mail:

Gebruiker gebruiker = nieuwe gebruiker (); user.setName ("Brendan"); EmailAddress emailAddress = nieuw EmailAddress (); emailAddress.setValue ("[e-mail beschermd]"); user.setEmailAddress (emailAddress); mongoTemplate.insert (gebruiker); 

En de staat van de database:

{"_id": ObjectId ("55d076d80bad441ed114419d"), "name": "Brendan", "age": null, "email": {"value": "[email protected]"}}

3.3. @BuienRadarNL en @Waarde

@BuienRadarNL markeert een constructor, zelfs een die is beschermd door een pakket, als de primaire constructor die wordt gebruikt door de persistentielogica. De constructorargumenten worden op naam toegewezen aan de sleutelwaarden in het opgehaalde DBObject.

Laten we naar deze constructor kijken voor onze Gebruiker klasse:

@PersistenceConstructor openbare gebruiker (String naam, @Value ("# root.age?: 0") Geheel getal leeftijd, EmailAddress emailAddress) {this.name = name; this.age = leeftijd; this.emailAddress = emailAddress; } 

Let op het gebruik van de standaardveer @Waarde annotatie hier. Met behulp van deze annotatie kunnen we de Spring Expressions gebruiken om de waarde van een sleutel die uit de database is opgehaald, te transformeren voordat deze wordt gebruikt om een ​​domeinobject te construeren. Dat is hier een zeer krachtige en zeer nuttige functie.

In ons voorbeeld als leeftijd is niet ingesteld waarop het zal worden ingesteld 0 standaard.

Laten we nu eens kijken hoe het werkt:

Gebruiker gebruiker = nieuwe gebruiker (); user.setName ("Alex"); mongoTemplate.insert (gebruiker);

Onze database ziet er uit:

{"_id": ObjectId ("55d074ca0bad45f744a71318"), "name": "Alex", "leeftijd": null}

Dus de leeftijd veld is nul, maar wanneer we het document opvragen en ophalen leeftijd:

mongoTemplate.findOne (Query.query (Criteria.where ("naam"). is ("Alex")), User.class) .getAge ();

Het resultaat is 0.

4. Omvormers

Laten we nu eens kijken naar een andere zeer nuttige functie in Spring Data MongoDB - converters, en specifiek naar de MongoConverter.

Dit wordt gebruikt voor het afhandelen van de toewijzing van alle Java-typen aan DBObjects bij het opslaan en opvragen van deze objecten.

We hebben twee opties - we kunnen met beide werken MappingMongoConverter - of SimpleMongoConverter in eerdere versies (dit was verouderd in Spring Data MongoDB M3 en de functionaliteit is verplaatst naar MappingMongoConverter).

Of we kunnen onze eigen aangepaste converter schrijven. Om dat te doen, zouden we het Converter interface en registreer de implementatie in MongoConfig.

Laten we eens kijken een snel voorbeeld. Zoals je hebt gezien in een deel van de JSON-uitvoer hier, hebben alle objecten die in een database zijn opgeslagen het veld _klasse die automatisch wordt opgeslagen. Als we echter dat specifieke veld tijdens persistentie willen overslaan, kunnen we dat doen met een MappingMongoConverter.

Ten eerste - hier is de implementatie van de aangepaste conversie:

@Component public class UserWriterConverter implementeert Converter {@Override public DBObject convert (User user) {DBObject dbObject = new BasicDBObject (); dbObject.put ("naam", user.getName ()); dbObject.put ("leeftijd", user.getAge ()); if (user.getEmailAddress ()! = null) {DBObject emailDbObject = nieuwe BasicDBObject (); emailDbObject.put ("waarde", user.getEmailAddress (). getValue ()); dbObject.put ("e-mail", emailDbObject); } dbObject.removeField ("_ class"); retourneer dbObject; }}

Merk op hoe we gemakkelijk het doel kunnen bereiken om niet vol te houden _klasse door het veld hier specifiek te verwijderen.

Nu moeten we de aangepaste converter registreren:

privélijst converters = nieuwe ArrayList(); @Override openbare MongoCustomConversions customConversions () {converters.add (nieuwe UserWriterConverter ()); retourneer nieuwe MongoCustomConversions (converters); }

We kunnen natuurlijk hetzelfde resultaat ook bereiken met XML-configuratie, als we:

Nu, wanneer we een nieuwe gebruiker opslaan:

Gebruiker gebruiker = nieuwe gebruiker (); user.setName ("Chris"); mongoOps.insert (gebruiker); 

Het resulterende document in de database bevat niet langer de klasse-informatie:

{"_id": ObjectId ("55cf09790bad4394db84b853"), "name": "Chris", "age": null}

5. Conclusie

In deze tutorial hebben we enkele kernconcepten van het werken met Spring Data MongoDB behandeld - indexering, algemene annotaties en converters.

De implementatie van al deze voorbeelden en codefragmenten kan gevonden worden in mijn github-project.


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