2016-07-11 2 views
1

mongodb의 동일한 콜렉션 "app"에 저장된 여러 Java 문서가 있습니다. 내 의도는 일반적인 지속 작업 (삽입, 찾기, 삭제 ...)에 사용하는 것입니다. 내가 정의한 저장소가 모든 엔티티를 검색 할 때 클래스 중 하나만 저장소를 정의하려고하면 문제가 발생하며 모든 엔티티를 검색 할 저장소가 있으며 모든 mongorepository 표준 함수 (find, findAll , findby ...). 내 설명이 이해하기 어려울 수 있습니다, 이것은 내가 지금 무엇을 가지고 :Spring MongoRepository 사용자 정의 - 클래스별로 필터링

자료 문서 : 하위 문서의

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

} 

(I 클래스에 의해 필터링 할) 확장 저장소 나는 내가 다시 사용할 수있는 경우 피하려는 임시 방편의

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

있습니까 : 서로 다른 라이브러리를 사용하는 아마 때문에?

+0

도메인 클래스'AbstractApplicationDocument'는'@ NoRepositoryBean'을 필요로하지 않습니다. 이 주석은 저장소 인터페이스 사용에만 사용됩니다. 왜'MongoRepository'에서 직접 응용 프로그램 저장소를 파생시키는 대신 빈 중간 'ApplicationRepository'를 사용합니까?하나의 컬렉션에서 여러 문서에 대해 : 그것은 한 가지 방법이고, 다른 하나는 형식 일치를 가진 Query by Example을 사용하는 것입니다. – mp911de

+0

주석을 제거했습니다. 감사합니다. 이것은 mongo와의 첫 번째 접촉이며 일부 수업은 내가 찾은 예제 사본 일뿐입니다. 빈 인터페이스는 추가 확장을 위해 존재합니다 (일부 응용 프로그램에만 캐시를 추가해야합니다). 그러나 어쨌든 이것은 인터페이스에서 제대로 작동하지 않으므로 아마도 다시 제거 할 것입니다. 하나의 콜렉션에 여러 문서가 몽고 (mongo) 구조로되어 있기 때문에 그렇게하는 것이 성능상의 이유입니다 (설명하기에는 너무 길다). – user2525691

+0

여러 문서 (구조)를 하나의 컬렉션에 저장하는 것에 대해 의문의 여지가 없습니다. MongoDB 저장소 동작을 사용자 정의하는 방법에 대한 답변을 추가했습니다. – mp911de

답변

2

다양한 방법으로 스프링 데이터 저장소를 사용자 정의 할 수 있습니다. 사용자 정의 저장소 기본 클래스를 제공하거나 custom implementation classes을 제공 할 수 있습니다.

특별히 질문이 있으시면 SimpleMongoRepository_class 필드에 대한 쿼리를 제한하지 않습니다. 다음은 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 쿼리는 예를 들어, 이제 클래스 유형 및 쿼리를 제한 @Query

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

쿼리 메소드는 클래스 형 (@Query("{'_class': ?0}"))하지만 파생 된 쿼리 메소드 (List<Model> findByFirstnameAndLastname(…))의 클래스 유형을 contrain 할 수있는 방법이 없습니다 전달하는 데 사용할 수 있습니다처럼 ModelRepository extends MongoRepository<Model, String>이 보일 것이다.

저장소 유형 제한과 관련하여 Jira에 open ticket이 있습니다. 이 티켓은 다형성 쿼리와 관련이 있지만 본질적으로 쿼리 메서드에 대한 형식 제한과 관련이 있습니다.

+0

고마워, 내가 시도한 해결책과 비슷하지만 네가 좀 더 우아 해 보인다. 티켓이 열려 있으면 내가 기다리고 있던 답변을 찾지 못할 것이라는 것을 의미하므로이 시간대에 가장 좋은 해결책입니다. – user2525691

+0

티켓에 투표를 남기거나 생각을 추가 할 수 있습니다. – mp911de

관련 문제