首页 文章

如何在将数据添加到MongoDB之前处理Spring Data中的插入请求?

提问于
浏览
3

https://spring.io/guides/gs/accessing-mongodb-data-rest/后面的非常有用的教程之后,我'm trying to create a link shortener app. I' ve编写了一个URL类(带有 idlongURLhash 属性)和URLRepository类(现在,只使用演示中显示的 findByHash 方法) . 请注意,"hash"我指的是一个由尚未实现的方法生成的随机短字符串,而不是像MD5这样的实际散列函数 . 只需要调用独立的 generateHash(String URL)

我可以使用Spring提供的REST接口将新条目添加到数据库中,以及获取它们 . 但是我想让应用程序生成散列本身并在存储之前进行一些检查和处理 - 主要检查URL是否已经存储,在这种情况下它将只返回现有的散列 .

我想我必须在我的 URLRepository 类下扩展 SimpleMongoRepository<S extends T> List<S> save(Iterable<S> entites); 方法(由 MongoRepository 扩展),但我不确定如何做到这一点 . 我也看到了 insert 方法,我不知道应该使用哪一个

URL.java

public class URL {

    @Id private String id;

    private String longURL;
    private String hash;

    public String getLongURL() {
        return longURL;
    }

    public void setLongURL(String longURL) {
        this.longURL = longURL;
    }

    public String getHash() {
        return hash;
    }

    public void setHash(String Hash) {
        this.hash = Hash;
    }

}

URLRepository.java

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.util.Assert;

@RepositoryRestResource(collectionResourceRel = "urls", path = "urls")
public interface URLRepository extends MongoRepository<URL, String> {

    List<URL> findByHash(@Param("hash") String hash);

}

1 回答

  • 2

    感觉你最好不要在这里编写自定义控制器而不是使用Spring Data REST,因为你基本上需要两个资源:一个用于添加链接或返回一个现有的,另一个用于通过哈希检索原始URI .

    在第一种方法中,您只需调用存储库方法 findByLongURL(…) 并使用获得的 URL 实例(如果您有结果)或采取第二步实际创建哈希并保存 URL 实例思想库 . 第二个资源基本上只是称你已经存在的方法 .

    这是直截了当的,易于消化 .

    如果您需要执行前一个方法作为原子操作,则需要手动实现存储库查询方法(有关读取reference documentation中相关部分的一般说明):

    class UrlRepositoryImpl implements UrlRepositoryCustom {
    
      private final MongoOperations operations;
    
      public UrlRepositoryImpl(MongoOperations operations) {
        this.operations = operations;
      }
    
      @Override
      public URL findOrInsert(String source) {
    
        // What to find?
        Query query = Query.query(Criteria.where("longURL").is(source);
    
        // What to write if nothing can be found
        Update update = new Update()
          .setOnInsert("longURL", source)
          .setOnInsert("hash", calculatedHash);
    
        FindAndModifyOptions options = new FindAndModifyOptions.options()
          .returnNew(true) // returns the document insert (if so)
          .upsert(true); // insert document if it doesn't exist
    
        return operations.findAndModify(query, update, options, URL.class);
      }
    }
    

    正如您所看到的,这涉及处理一些较低级别的细节(虽然可以通过使用静态导入来减少冗长)但基本上为您提供原子操作 .

相关问题