development

SpringData의 MongoTemplate과 MongoRepository의 차이점은 무엇입니까?

big-blog 2020. 10. 14. 08:01
반응형

SpringData의 MongoTemplate과 MongoRepository의 차이점은 무엇입니까?


spring-data와 mongodb를 사용하여 복잡한 쿼리를 수행 할 수있는 애플리케이션을 작성해야합니다. 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/

사용하기 더 편리하고 강력한 것이 무엇인지 말씀해 주시겠습니까? mongoTemplate또는 MongoRepository? 둘 다 성숙 했습니까 아니면 둘 중 하나가 다른 기능보다 더 많은 기능이 부족합니까?


"편리함"과 "사용하기 강력 함"은 어느 정도 상반되는 목표입니다. 리포지토리는 템플릿보다 훨씬 편리하지만 후자는 실행할 항목을보다 세밀하게 제어 할 수 있습니다.

저장소 프로그래밍 모델은 여러 SpringData 모듈에서 사용할 수 있으므로 SpringData MongoDB 참조 문서 의 일반 섹션에서 더 자세한 문서를 찾을 수 있습니다 .

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. 사용자 정의 옵션은 여기 에 설명되어 있습니다 .


This answer may be a bit delayed, but I would recommend avoiding the whole repository route. You get very little implemented methods of any great practical value. In order to make it work you run into the Java configuration nonsense which you can spend days and weeks on without much help in the documentation.

Instead, go with the MongoTemplate route and create your own Data access layer which frees you from the configuration nightmares faced by Spring programmers. MongoTemplate is really the savior for engineers who are comfortable architecting their own classes and interactions since there is lot of flexibility. The structure can be something like this:

  1. Create a MongoClientFactory class that will run at the application level and give you a MongoClient object. You can implement this as a Singleton or using an Enum Singleton (this is thread safe)
  2. Create a Data access base class from which you can inherit a data access object for each domain object). The base class can implement a method for creating a MongoTemplate object which you class specific methods can use for all DB accesses
  3. Each data access class for each domain object can implement the basic methods or you can implement them in the base class
  4. The Controller methods can then call methods in the Data access classes as needed.

FWIW, regarding updates in a multi-threaded environment:

  • MongoTemplate provides out-of-the-box updateFirst, updateMulti, findAndModify, upsert... methods which allow you to modify a document in a single operation. The Update object used by these methods also allows you to target only the relevant fields.
  • MongoRepository only gives you the basic find, insert, save, delete operations, which work with POJOs containing all the fields. This forces you to either update the documents in several steps (find the document to update, modify the relevant fields from the returned POJO, and then save it), or define your own update queries by hand using @Query.

In a multi-threaded environment, like e.g. a Java back-end with several REST endpoints, single-method updates are the way to go, in order to reduce the chances of two concurrent updates overwriting one another's changes.

Example: given a document like this: { _id: "ID1", field1: "a string", field2: 10.0 } and two different threads concurrently updating it...

With MongoTemplate it would look somewhat like this:

THREAD_001                                                      THREAD_002
|                                                               |
|update(query("ID1"), Update().set("field1", "another string")) |update(query("ID1"), Update().inc("field2", 5))
|                                                               |
|                                                               |

and the final state for the document is always { _id: "ID1", field1: "another string", field2: 15.0 } since each thread is accesing the DB only once and only the specified field is changed.

Whereas the same case scenario with MongoRepository would look like this:

THREAD_001                                                      THREAD_002
|                                                               |
|pojo = findById("ID1")                                         |pojo = findById("ID1")
|pojo.setField1("another string") /* field2 still 10.0 */       |pojo.setField2(pojo.getField2()+5) /* field1 still "a string" */
|save(pojo)                                                     |save(pojo)
|                                                               |
|                                                               |

and the final document being either { _id: "ID1", field1: "another string", field2: 10.0 } or { _id: "ID1", field1: "a string", field2: 15.0 } depending on which save operation hits the DB first.

So I'd say that MongoTemplate is a better option, unless you have a very elaborated POJO model or need the custom queries capabilities of MongoRepository for some reason.

참고URL : https://stackoverflow.com/questions/17008947/whats-the-difference-between-spring-datas-mongotemplate-and-mongorepository

반응형