在将请求添加到MongoDB之前如何处理Spring Data中的插入请求? [英] How to process insert requests in Spring Data before adding them to MongoDB?

查看:86
本文介绍了在将请求添加到MongoDB之前如何处理Spring Data中的插入请求?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在遵循 https://spring.io/guides/gs/accessing-mongodb-data-rest/,我正在尝试创建一个链接缩短程序.我已经编码了一个URL类(具有idlongURLhash属性)和URLRepository类(目前,仅使用演示中所示的findByHash方法).请注意,散列"是指由尚待实现的方法生成的随机短字符串,而不是像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);

}

解决方案

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

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

这很简单,很容易理解.

如果您需要将前一种方法的实现作为原子操作,则需要手动实现存储库查询方法(有关阅读该通用说明,请阅读

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

after following the very useful tutorial at https://spring.io/guides/gs/accessing-mongodb-data-rest/ , I'm trying to create a link shortener app. I've coded an URL class (with id, longURL and hash attributes) and URLRepository class (for now, with just the findByHash method as shown in the demo). Please note that by "hash" I'm referring to a random short string generated by a method yet-to-be-implemented, not an actual hashing function like MD5. Just calls to a independent generateHash(String URL) for example

I'm able to add new entries into the database by using the REST interface provided by Spring, as well as fetching them. However I'd like to have the application generate the hash itself and making some checks and processing before storing it - Mainly checking that the URL is not already stored, in which case it will just return the existing hash.

I suppose that I'd have to extend SimpleMongoRepository's <S extends T> List<S> save(Iterable<S> entites); method (As extended by MongoRepository) under my URLRepository class, but I'm not really sure how to do that. I also saw the insert method and I don't know which one I should be using

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

}

解决方案

It feels like you're better off writing a custom controller instead of using Spring Data REST here as you basically need two resources: one to add a link or return an existing and a second one to retrieve an original URI via its hash.

In the first method you'd simply call a repository method findByLongURL(…) and use the obtained URL instance if you have a result or take a second step to actually create the hash and save the URL instance thought repository. The second resource would basically just call you already existing method.

That's straight forward and easy to digest.

If you need the implementation of the former method be an atomic operation the repository query method needs to be manually implemented (for general instructions on that read up the relevant section in the 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);
  }
}

As you can see this involves dealing with some lower level details (although the verbosity can be reduced by using static imports) but basically gives you an atomic operation.

这篇关于在将请求添加到MongoDB之前如何处理Spring Data中的插入请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆