我们如何使用 spring boot 为 mongodb 创建自动生成的字段

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36448921/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 20:42:44  来源:igfitidea点击:

How can we create Auto generated field for mongodb using spring boot

mongodbspring-bootspring-dataspring-data-mongodb

提问by Saakshi Aggarwal

I write some code.I want to make questionId field in BaseQuestionClass as Autogenerated.Any solution for that? I am not using jpa jar.so i can't use @Generatedvalueannotation.So how we show here this field is auto generated. code is below.

我写了一些代码。我想将BaseQuestionClass 中的questionId 字段设为自动生成。对此有任何解决方案吗?我没有使用 jpa jar。所以我不能使用@Generatedvalue注释。所以我们在这里显示这个字段是自动生成的。代码如下。

pom.xml

pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>audit_project</name>
    <description>Demo project for Spring Boot</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>2.11.0</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

BaseQuestion.java

基本问题.java

package model;

import java.util.List;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "basequestion")
public class BaseQuestion {
      @ID
    private String id;
    private int questionId;
    private String responseType;
    private boolean required;
    private boolean active;
    private String questionCode;
    private QuestionText questionText;
    private String category;
    private List<Responses> responses;

    public QuestionText getQuestionText() {
        return questionText;
    }

    public void setQuestionText(QuestionText questionText) {
        this.questionText = questionText;
    }

    public List<Responses> getResponses() {
        return responses;
    }

    public void setResponses(List<Responses> responses) {
        this.responses = responses;
    }

    public int getQuestionId() {
        return questionId;
    }

    public void setQuestionId(int questionId) {
        this.questionId = questionId;
    }

    public String getResponseType() {
        return responseType;
    }

    public void setResponseType(String responseType) {
        this.responseType = responseType;
    }

    public boolean getRequired() {
        return required;
    }

    public void setRequired(boolean required) {
        this.required = required;
    }

    public String getQuestionCode() {
        return questionCode;
    }

    public void setQuestionCode(String questionCode) {
        this.questionCode = questionCode;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }
}

AuditProjectRepository.java

AuditProjectRepository.java

package repository;

import org.springframework.data.mongodb.repository.MongoRepository;

import model.BaseQuestion;

public interface AuditProjectRepository extends MongoRepository<BaseQuestion, String> {

    public BaseQuestion findByQuestionId(int questionId);

    public BaseQuestion findByQuestionCode(String questionCode);

    public Long deleteByQuestionId(int questionid);

}

回答by rajadilipkolli

MongoDB came with all sophisticated ObjectId generation feature, but often you just jumped the ship from relational database, and you still want an easy to read / communicate numeric identifier field which automatically increments every time new record is inserted.

MongoDB 带有所有复杂的 ObjectId 生成功能,但通常您只是从关系数据库中跳槽,并且您仍然需要一个易于阅读/交流的数字标识符字段,该字段在每次插入新记录时自动递增。

One neat suggestion from MongoDB tutorialis to use a counter collection with a ‘counter name' as its id, and a ‘seq' field to store the last used number.

来自MongoDB 教程的一个巧妙建议是使用一个以“计数器名称”作为其 ID 的计数器集合,以及一个“seq”字段来存储上次使用的数字。

When developing using Spring Data MongoDB, this neat trick can be written as a simple service. Here I used the collection name as the counter name so it's easy to guess / remember.

在使用 Spring Data MongoDB 进行开发时,这个巧妙的技巧可以写成一个简单的服务。在这里,我使用集合名称作为计数器名称,因此很容易猜测/记住。

import static org.springframework.data.mongodb.core.FindAndModifyOptions.options;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import com.model.CustomSequences;


@Service
public class NextSequenceService {
    @Autowired private MongoOperations mongo;

    public int getNextSequence(String seqName)
    {
        CustomSequences counter = mongo.findAndModify(
            query(where("_id").is(seqName)),
            new Update().inc("seq",1),
            options().returnNew(true).upsert(true),
            CustomSequences.class);
        return counter.getSeq();
    }
}

CustomSequences is just a simple class representing the collection. Please beware the usage of int data type, this will limit to 2^31 entries maximum.

CustomSequences 只是一个表示集合的简单类。请注意 int 数据类型的使用,这将限制为最多 2^31 个条目。

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "customSequences")
public class CustomSequences {
    @Id
    private String id;
    private int seq;

// getters and setters
}

Then when inserting a new entry (with help of Spring MongoDB Repository support), just set the id field like this before you save it

然后在插入新条目时(借助 Spring MongoDB Repository 支持),只需在保存之前像这样设置 id 字段

BaseQuestion baseQuestion = new BaseQuestion();
baseQuestion.setQuestionId(nextSequenceService.getNextSequence("customSequences"));
/* Rest all values */

baseQuestionRepository.save(baseQuestion);

If you don't like this way then you need to use MongoDBEvents and use onBeforeConvert to generate automated value using same above approach.

如果您不喜欢这种方式,那么您需要使用 MongoDBEvents 并使用 onBeforeConvert 使用上述相同的方法生成自动值。

Also above approach is threadsafe as findAndModify() is a thread safe atomic method

上述方法也是线程安全的,因为 findAndModify() 是线程安全的原子方法