MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Campo gerado automaticamente para MongoDB usando Spring Boot

1. Visão geral


Neste tutorial, vamos aprender como implementar um campo sequencial gerado automaticamente para o MongoDB no Spring Boot.

Quando estamos usando o MongoDB como banco de dados para um aplicativo Spring Boot, não podemos usar @GeneratedValue anotação em nossos modelos, pois não está disponível. Portanto, precisamos de um método para produzir o mesmo efeito que teremos se estivermos usando JPA e um banco de dados SQL.

A solução geral para este problema é simples. Criaremos uma coleção (tabela) que armazenará a sequência gerada para outras coleções. Durante a criação de um novo registro, nós o usaremos para buscar o próximo valor.

2. Dependências


Vamos adicionar os seguintes iniciadores de inicialização de mola ao nosso 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>

A versão mais recente das dependências é gerenciada por spring-boot-starter-parent .

3. Coleções


Conforme discutido na visão geral, criaremos uma coleção que armazenará a sequência incrementada automaticamente para outras coleções. Chamaremos essa coleção de database_sequences. Ele pode ser criado usando o mongo shell ou MongoDB Compass. Vamos criar uma classe de modelo correspondente:
@Document(collection = "database_sequences")
public class DatabaseSequence {

    @Id
    private String id;

    private long seq;

    //getters and setters omitted
}

Vamos então criar um usuários coleção e um objeto de modelo correspondente, que armazenará os detalhes das pessoas que estão usando nosso sistema:
@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
}

No Usuário modelo criado acima, adicionamos um campo estático SEQUENCE_NAME, que é uma referência exclusiva à sequência incrementada automaticamente para os usuários coleção.

Também anotamos com o @Transient para evitar que ele seja persistido junto com outras propriedades do modelo.

4. Criando um novo registro


Até agora, criamos as coleções e modelos necessários. Agora, criaremos um serviço que gerará o valor incrementado automaticamente que pode ser usado como id para nossas entidades.

Vamos criar um SequenceGeneratorService que tem generateSequence() :
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;
}

Agora, podemos usar o comando generateSequence() ao criar um novo registro:
User user = new User();
user.setId(sequenceGenerator.generateSequence(User.SEQUENCE_NAME));
user.setEmail("[email protected]");
userRepository.save(user);

Para listar todos os usuários, usaremos o UserRepository :
List<User> storedUsers = userRepository.findAll();
storedUsers.forEach(System.out::println);

Como está agora, temos que definir o campo id toda vez que criamos uma nova instância do nosso modelo. Podemos contornar esse processo criando um ouvinte para eventos de ciclo de vida do Spring Data MongoDB.

Para fazer isso, criaremos um UserModelListener que estende AbstractMongoEventListener e, em seguida, substituiremos o onBeforeConvert() :
@Override
public void onBeforeConvert(BeforeConvertEvent<User> event) {
    if (event.getSource().getId() < 1) {
        event.getSource().setId(sequenceGenerator.generateSequence(User.SEQUENCE_NAME));
    }
}

Agora, sempre que salvamos um novo Usuário,código será definido automaticamente.