sql >> Database >  >> NoSQL >> MongoDB

Automatisch gegenereerd veld voor MongoDB met Spring Boot

1. Overzicht

In deze zelfstudie leren we hoe we een sequentieel, automatisch gegenereerd veld voor MongoDB in Spring Boot kunnen implementeren.

Als we MongoDB gebruiken als database voor een Spring Boot-toepassing, kunnen we @GeneratedValue niet gebruiken annotatie in onze modellen omdat deze niet beschikbaar is. Daarom hebben we een methode nodig om hetzelfde effect te produceren als wanneer we JPA en een SQL-database gebruiken.

De algemene oplossing voor dit probleem is eenvoudig. We maken een verzameling (tabel) die de gegenereerde reeks opslaat voor andere verzamelingen. Tijdens het maken van een nieuw record gebruiken we het om de volgende waarde op te halen.

2. Afhankelijkheden

Laten we de volgende spring-boot starters toevoegen aan onze pom.xml :

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <versionId>2.2.2.RELEASE</versionId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
        <versionId>2.2.2.RELEASE</versionId>
    </dependency>
</dependencies>

De nieuwste versie voor de afhankelijkheden wordt beheerd door spring-boot-starter-parent .

3. Collecties

Zoals besproken in het overzicht, gaan we een verzameling maken waarin de automatisch oplopende volgorde voor andere verzamelingen wordt opgeslagen. We noemen deze verzameling database_sequences. Het kan worden gemaakt met behulp van de mongo shell of MongoDB-kompas. Laten we een overeenkomstige modelklasse maken:

@Document(collection = "database_sequences")
public class DatabaseSequence {

    @Id
    private String id;

    private long seq;

    //getters and setters omitted
}

Laten we dan een gebruikers . maken collectie, en een bijbehorend modelobject, dat de details opslaat van mensen die ons systeem gebruiken:

@Document(collection = "users")
public class User {

    @Transient
    public static final String SEQUENCE_NAME = "users_sequence";

    @Id
    private long id;

    private String email;

    //getters and setters omitted
}

In de Gebruiker model dat hierboven is gemaakt, hebben we een statisch veld toegevoegd SEQUENCE_NAME, wat een unieke verwijzing is naar de automatisch oplopende reeks voor de gebruikers collectie.

We annoteren het ook met de @Transient om te voorkomen dat het naast andere eigenschappen van het model blijft bestaan.

4. Een nieuw record maken

Tot nu toe hebben we de benodigde collecties en modellen gemaakt. Nu gaan we een service maken die de automatisch verhoogde waarde genereert die kan worden gebruikt als id voor onze entiteiten.

Laten we een SequenceGeneratorService . maken die generateSequence() . heeft :

public long generateSequence(String seqName) {
    DatabaseSequence counter = mongoOperations.findAndModify(query(where("_id").is(seqName)),
      new Update().inc("seq",1), options().returnNew(true).upsert(true),
      DatabaseSequence.class);
    return !Objects.isNull(counter) ? counter.getSeq() : 1;
}

Nu kunnen we de generateSequence() . gebruiken tijdens het maken van een nieuw record:

User user = new User();
user.setId(sequenceGenerator.generateSequence(User.SEQUENCE_NAME));
user.setEmail("[email protected]");
userRepository.save(user);

Om alle gebruikers weer te geven, gebruiken we de UserRepository :

List<User> storedUsers = userRepository.findAll();
storedUsers.forEach(System.out::println);

Zoals het nu is, moeten we het id-veld elke keer dat we een nieuwe instantie van ons model maken, instellen. We kunnen dit proces omzeilen door een listener te maken voor Spring Data MongoDB-levenscyclusgebeurtenissen.

Om dat te doen, maken we een UserModelListener dat breidt AbstractMongoEventListener . uit en dan overschrijven we de onBeforeConvert() :

@Override
public void onBeforeConvert(BeforeConvertEvent<User> event) {
    if (event.getSource().getId() < 1) {
        event.getSource().setId(sequenceGenerator.generateSequence(User.SEQUENCE_NAME));
    }
}

Elke keer dat we een nieuwe Gebruiker . opslaan, de id wordt automatisch ingesteld.


  1. Krijg waarden op sleutelpatroon in StackExchange.Redis

  2. Mongo Triple Samengestelde Index

  3. 4 manieren om de collecties in een MongoDB-database op te sommen

  4. Stel Redis-cachevoorvoegselsleutel in op Symfony