使用Spring Boot为MongoDb自动生成字段

原文链接: http://www.spring4all.com/article/1788
https://www.baeldung.com/spring-boot-mongodb-auto-generated-field
作者:baeldung
译者:Rain

1.概览

在本教程中,我们将学习如何在Spring Boot中为MongoDB实现一个连续的、自动生成的字段。
当使用MongoDB作为Spring Boot 应用程序的数据库时,我们不能在模型中使用@GeneratedValue注解,因为它不可用。 因此,我们需要一种方法来产生与使用JPA和SQL数据库相同的效果。

这个问题的解决方案通常很简单。我们将创建一个集合(表),它将为其他集合存储生成的序列。在创建新记录时我们将使用它的下一个值。

2.依赖

添加如下配置到pom.xml

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

最新版本依赖参看spring-boot-starter-parent

3.集合

正如在概述中所讨论,我们将创建一个集合来存储其他集合的自动递增序列。我们将这个集合称为database_sequence。它可以使用mongo shell或MongoDB Compass创建。让我们创建一个相应的模型类:

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

    @Id
    private String id;

    private long seq;

    //getters and setters omitted
}

然后,我们创建一个用户集合和一个相应的模型对象,它将存储使用我们系统的人的详细信息:

@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
}

在上面用户模型创建中,我们添加了一个静态字段SEQUENCE_NAME, 它是对用户集合的自动递增序列的一个引用。
我们也用@Transient注解它,防止它与其他属性一起持久化。

4.创建一条新记录

到此我们已经创建了需求的集合和模型,现在我们准备创建一个服务,它将生成可作为实体id的自动递增值。
我们创建拥有generateSequence()方法的SequenceGeneratorService服务

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;
}

现在我们在创建新记录的时候能使用方法generateSequence()

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

使用UserRepository来遍历所有用户。

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

现在,每次创建模型的新实例时,我们都必须设置id字段。我们可以通过为Spring Data MongoDB生命周期事件创建侦听器来绕过这个过程。
为此,我们将创建一个UserModelListener,它扩展AbstractMongoEventListener,然后重写onBeforeConvert():

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

每次保存新用户的时候,ID都会自动设置。

5.结论

最后,我们了解了如何为id字段生成连续的、自动递增的值,并模拟SQL数据库中相同的行为。
Hibernate在默认情况下使用类似的方法来生成自动递增的值。像往常一样,完整的源代码可以在Github上获得。

你可能感兴趣的:(spring-boot)