草庐IT

java - 自定义 Spring MongoRepository - 按类过滤

coder 2023-11-03 原文

我有几个 Java 文档存储在 mongodb 的同一个集合“app”中。我的意图是将它用于常见的持久性操作(插入、查找、删除...)。当我尝试只为其中一个类定义存储库时,问题就来了,因为我定义的存储库将搜索所有实体,而我需要的是一个存储库,我可以在其中调用所有 mongorepository 标准函数(find、findAll ,查找...)。我的解释可能很难理解,这就是我现在的:

基础文档:

@Document(collection = "app")
@NoRepositoryBean
public abstract class AbstractApplicationDocument {    
    @Id
    public String mongoId;
    // more variables, getters, setters...
}

其中一个子文档(会有很多)。

@EqualsAndHashCode(callSuper=true)
public class ClientApplicationDocument extends AbstractApplicationDocument
{
    @Id
    public String mongoId;    
}

基础仓库

@NoRepositoryBean
public interface ApplicationRepository<T, ID extends Serializable>  extends MongoRepository<T, ID>  {

}

扩展存储库(我想按类过滤的地方)

public interface HttpClientRepository extends ApplicationRepository<HttpClientDocument, String> {
}

如果我可以重用 MongoDb 实用程序,我想避免的临时解决方案示例

@Component
public class HttpClientRepositoryImpl {

    @Autowired
    private HttpClientRepository clientRepo;

    @Autowired
    private MongoTemplate mongo;

    public List<HttpClientDocument> findAll() {    
        Query query = new Query();
        query.addCriteria(Criteria.where("_class").is(HttpClientDocument.class.getName()));
        mongo.getConverter();
        return mongo.find(query, HttpClientDocument.class,"app");
    }
}

gradle中的相关信息。我添加这个是因为我看到了一些对我无效的解决方案。可能是因为他们使用不同的库:

compile("org.springframework.boot:spring-boot-starter-data-mongodb:${springBootVersion}")
compile ("org.springframework:spring-context-support:4.1.8.RELEASE");

有什么简单的解决方法吗?

最佳答案

您可以通过多种方式自定义 Spring Data 存储库。您可以提供自定义存储库基类或提供 custom implementation classes .

特别针对您的问题, SimpleMongoRepository 不限制对 _class 的查询 field 。您可以在下面看到一个限制 findAll 的自定义存储库基类的示例。查询方法只使用声明的实体类型。

对于在 MongoRepository 上声明的其他方法,您也需要应用该模式。您想要限制到特定类类型的级别。

@EnableMongoRepositories(repositoryBaseClass = MyMongoRepository.class)
static class Config {
}

static class MyMongoRepository<T, ID extends Serializable> extends SimpleMongoRepository<T, ID> {

    private final MongoEntityInformation<T, ID> metadata;
    private final MongoOperations mongoOperations;

    public MyMongoRepository(MongoEntityInformation<T, ID> metadata, MongoOperations mongoOperations) {
        super(metadata, mongoOperations);
        this.metadata = metadata;
        this.mongoOperations = mongoOperations;
    }

    @Override
    public List<T> findAll() {

        Query query = new Query();
        query.restrict(this.metadata.getJavaType());

        return this.mongoOperations.find(query, this.metadata.getJavaType(), this.metadata.getCollectionName());
    }
}

findAll查询现在限制类类型和查询,例如ModelRepository extends MongoRepository<Model, String>看起来像:

{ "_class" : { "$in" : [ "com.example.Model"]}}

使用 @Query 查询方法可用于传入类类型 ( @Query("{'_class': ?0}") ),但无法限制派生查询方法 ( List<Model> findByFirstnameAndLastname(…) ) 的类类型。

有一个 open ticket在我们的 Jira 中与限制存储库的类型有关。该特定票证与多态查询有关,但从本质上讲,它与查询方法的类型限制有关。

关于java - 自定义 Spring MongoRepository - 按类过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38302410/

有关java - 自定义 Spring MongoRepository - 按类过滤的更多相关文章

  1. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  2. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  3. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  4. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  5. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  6. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  7. ruby - 定义方法参数的条件 - 2

    我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano

  8. ruby - 如何在 Grape 中定义哈希数组? - 2

    我使用Ember作为我的前端和GrapeAPI来为我的API提供服务。前端发送类似:{"service"=>{"name"=>"Name","duration"=>"30","user"=>nil,"organization"=>"org","category"=>nil,"description"=>"description","disabled"=>true,"color"=>nil,"availabilities"=>[{"day"=>"Saturday","enabled"=>false,"timeSlots"=>[{"startAt"=>"09:00AM","endAt"=>

  9. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

  10. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

随机推荐