2013-06-09 1 views
53

스프링 데이터와 mongodb를 사용하여 복잡한 쿼리를 수행 할 수있는 응용 프로그램을 작성해야합니다. 나는 MongoRepository를 사용하여 시작했지만 예제를 찾거나 실제로 구문을 이해하기 위해 복잡한 쿼리로 고생했습니다.Spring Data의 MongoTemplate과 MongoRepository의 차이점은 무엇입니까?

이 같은 질의에 대해 이야기하고있다 :

@Repository 
public interface UserRepositoryInterface extends MongoRepository<User, String> { 
    List<User> findByEmailOrLastName(String email, String lastName); 
} 

또는 내가 구문 권리를하지 않기 때문에 내가 시행 착오를 시도 JSON 기반의 쿼리의 사용. mongodb 문서를 읽은 후에도 (잘못된 구문으로 인해 작동하지 않는 예제).

@Repository 
public interface UserRepositoryInterface extends MongoRepository<User, String> { 
    @Query("'$or':[{'firstName':{'$regex':?0,'$options':'i'}},{'lastName':{'$regex':?0,'$options':'i'}}]") 
    List<User> findByEmailOrFirstnameOrLastnameLike(String searchText); 
} 

모든 문서를 읽은 후에는 mongoTemplate 훨씬 더 나은 다음 MongoRepository 설명하는 것으로 보인다. 나는 다음 설명서를 참조하고 있습니다 :

http://static.springsource.org/spring-data/data-mongodb/docs/current/reference/html/reference.html

당신이 사용하는 것이 더 편리하고 강력한 무엇인지 말씀해 주시겠습니까? mongoTemplate 또는 MongoRepository? 둘 다 성숙합니까? 아니면 그 중 하나가 더 많은 기능을 갖고 있지 않습니까?

답변

95

"편리하고" "사용하기에 편리합니다"는 어느 정도 모순적인 목표입니다. 템플릿은 템플릿보다 훨씬 편리하지만, 후자는 무엇을 실행할 것인지에 대한 세분화 된 제어를 제공합니다.

여러 스프링 데이터 모듈에 대해 저장소 프로그래밍 모델을 사용할 수 있으므로 스프링 데이터 MongoDB reference docs의 일반 섹션에서 더 자세한 문서를 찾을 수 있습니다. ;

TL DR

우리는 일반적으로 다음과 같은 방법 추천 : 저장소 추상적 인

  1. 시작을 그냥 쿼리 유도 메커니즘을 사용하여 간단한 쿼리 또는 수동으로 정의 된 쿼리를 선언합니다.
  2. 더 복잡한 쿼리의 경우 저장소에 수동으로 구현 된 메서드를 추가하십시오 (여기에 설명 된대로). 구현을 위해서는 MongoTemplate을 사용하십시오.

    1. 사용자 정의 코드에 대한 인터페이스를 정의합니다 :

      interface CustomUserRepository { 
      
          List<User> yourCustomMethod(); 
      } 
      
    2. 는 대한 구현을 추가

    세부

    귀하의 예를 들어이 같이 보일 것이다 이 수업을 듣고 명명 규칙에 따라 우리가 할 수 있는지 확인하십시오. 수업을 찾는다.

    class UserRepositoryImpl implements CustomUserRepository { 
    
        private final MongoOperations operations; 
    
        @Autowired 
        public UserRepositoryImpl(MongoOperations operations) { 
    
        Assert.notNull(operations, "MongoOperations must not be null!"); 
        this.operations = operations; 
        } 
    
        public List<User> yourCustomMethod() { 
        // custom implementation here 
        } 
    } 
    
  3. 는 이제 기본 저장소 인터페이스는 사용자 정의를 확장 할 수 및 인프라가 자동으로 사용자 정의 구현을 사용합니다 :

    interface UserRepository extends CrudRepository<User, Long>, CustomUserRepository { 
    
    } 
    

당신은 기본적으로 선택을 받기 방법 : 모든 것을 그냥 쉽게 그 신고하려면 UserRepository으로 가면 수동으로 구현하는 것이 더 나은 것은 CustomUserRepository입니다. 사용자 지정 옵션은 here으로 문서화되어 있습니다.

+0

안녕 Oliver,이 실제로 작동하지 않습니다. spring-data는 사용자 정의 이름에서 질의를 자동으로 생성하려고 시도합니다. yourCustomMethod(). "당신"은 도메인 클래스의 유효한 필드가 아닙니다. 매뉴얼을 따라 갔다가 spring-data-jpa-examples을 어떻게 사용하는지 두 번 확인했습니다. 불운. 스프링 데이터는 사용자 인터페이스를 저장소 클래스로 확장하자마자 항상 자동 생성을 시도합니다. 유일한 차이점은 MongoRepository가 CrudRepository가 아니라는 것입니다. 반복자를 사용하지 않으려 고합니다. 당신이 힌트를 가지고 있다면 그것은 인정 될 것입니다. –

+4

가장 일반적인 실수는 구현 클래스의 이름을 잘못 지정하는 것입니다. 기본 저장소 인터페이스의 이름이 YourRepository 인 경우 구현 클래스의 이름을 YourRepositoryImpl로 지정해야합니다. 그럴까요? 그렇다면 GitHub 등의 샘플 프로젝트를 살펴 보니 기쁩니다. –

+1

안녕하세요 Oliver, Impl 클래스의 이름이 잘못 지정되었습니다. 이름을 조정했는데 지금은 작동하는 것처럼 보입니다. 귀하의 의견에 대단히 고마워요. 이 방법으로 다른 종류의 쿼리 옵션을 사용할 수있게되어 정말 좋습니다. 잘 생각했습니다! –

11

이 답변은 다소 지연 될 수 있지만 전체 저장소 경로를 피하는 것이 좋습니다. 실용적인 가치가있는 구현 방법은 거의 없습니다. 이 기능을 작동 시키려면 설명서 구성에 많은 도움이없이 며칠이나 몇 주를 보낼 수있는 Java 구성 넌센스로 실행하십시오.

대신에 MongoTemplate 경로를 사용하고 스프링 프로그래머가 직면 한 구성 악몽에서 자유롭게 자신 만의 데이터 액세스 레이어를 만들 수 있습니다. MongoTemplate은 많은 유연성이 있기 때문에 자신의 클래스와 상호 작용을 설계하는 데 편안한 엔지니어를위한 구원자입니다.

  1. 는 응용 프로그램 수준에서 실행하고 당신에게 MongoClient 객체를 줄 것이다 MongoClientFactory 클래스를 만듭니다 구조는 다음과 같이 할 수 있습니다. 이것을 Singleton 또는 Enum Singleton (스레드로부터 안전함)을 사용하여 구현할 수 있습니다.
  2. 각 도메인 개체에 대한 데이터 액세스 개체를 상속 할 수있는 데이터 액세스 기본 클래스를 만듭니다. 기본 클래스는 모든 DB 액세스에 클래스 별 메서드가 사용할 수있는 MongoTemplate 객체를 만드는 메서드를 구현할 수 있습니다.
  3. 각 도메인 객체에 대한 각 데이터 액세스 클래스는 기본 메서드를 구현하거나 기본 클래스로 구현할 수 있습니다.
  4. Controller 메서드는 필요에 따라 데이터 액세스 클래스의 메서드를 호출 할 수 있습니다.
+0

안녕하세요 @rameshpa 동일한 프로젝트에서 MongoTemplate과 리포지토리를 모두 사용할 수 있습니까? 사용할 수 있습니까 – Gauranga

+1

구현할 수있는 MongoTemplate은 리포지토리에서 사용하는 연결과 다른 DB 연결을 갖습니다. 원자력 문제가 될 수 있습니다. 또한 시퀀싱 요구 사항이있는 경우 하나의 스레드에서 두 개의 다른 연결을 사용하지 않는 것이 좋습니다. – rameshpa

관련 문제