2013-06-09 10 views
53

Potrzebuję napisać aplikację, za pomocą której mogę wykonywać złożone zapytania za pomocą wiosennych danych i mongodb. Zaczynałem od używania MongoRepository, ale zmagałem się ze złożonymi zapytaniami, aby znaleźć przykłady lub faktycznie zrozumieć składnię.Jaka jest różnica między MongoTemplate a MongoRepository?

mówię zapytaniami tak:

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

lub wykorzystanie JSON zapytań opartych który Próbowałem metodą prób i błędów, bo nie dostać prawo składni. Nawet po przeczytaniu dokumentacji mongodb (niepracujący przykład z powodu złej składni).

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

Po przeczytaniu całej dokumentacji wydaje się, że jest znacznie lepiej mongoTemplate udokumentowane następnie MongoRepository. Chodzi mi o następującej dokumentacji:

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

Czy możesz mi powiedzieć, co jest bardziej wygodne i wydajne w użyciu? mongoTemplate lub MongoRepository? Czy oba są takie same, czy jedno z nich nie ma więcej cech niż drugie?

Odpowiedz

95

"Wygodne" i "użyteczne w użyciu" w pewnym stopniu są sprzeczne z celami. Repozytoria są znacznie wygodniejsze niż szablony, ale te ostatnie dają oczywiście większą kontrolę nad tym, co należy wykonać.

Ponieważ model programowania repozytoriów jest dostępny dla wielu modułów danych sprężynowych, można znaleźć dokładniejszą dokumentację tego w sekcji ogólnej danych sprężynowych MongoDB reference docs.

TL; DR

Ogólnie zaleca się następujące podejście:

  1. Start z repozytorium abstrakcyjne i po prostu zadeklarować prostych zapytań za pomocą mechanizmu uzyskiwania zapytanie lub ręcznie zdefiniowanych zapytań.
  2. W przypadku bardziej złożonych zapytań dodaj ręcznie zaimplementowane metody do repozytorium (zgodnie z dokumentacją tutaj). Do wdrożenia użyj MongoTemplate.

Szczegóły

Dla przykładu to będzie wyglądać mniej więcej tak:

  1. zdefiniować interfejs dla kodu niestandardowego:

    interface CustomUserRepository { 
    
        List<User> yourCustomMethod(); 
    } 
    
  2. Dodaj implementację dla w tej klasie i postępuj zgodnie z konwencją nazewnictwa, aby upewnić się, że możemy znajdź klasę.

    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. Teraz niech interfejs repozytorium baza przedłużyć zwyczaj jedna i ta infrastruktura będzie automatycznie korzystać z wdrożenia niestandardowe:

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

W ten sposób można w zasadzie uzyskać wyboru: wszystko, co tylko proste aby zadeklarować, przechodzi w UserRepository, wszystko, co jest lepiej zaimplementowane ręcznie, przechodzi w CustomUserRepository. Opcje dostosowywania są udokumentowane here.

+0

Cześć Oliver, to w rzeczywistości nie działa. spring-data próbuje automatycznie wygenerować zapytanie poza nazwą niestandardową. yourCustomMethod(). Mówi "twój" nie jest prawidłowym polem w klasie domeny. Postępowałem zgodnie z instrukcją, a także dwukrotnie sprawdzałem, w jaki sposób robisz to w spring-data-jpa-examples. Brak szczęścia. dane sprężyste zawsze próbują automatycznie generować, gdy tylko rozszerzę niestandardowy interfejs na klasę repozytorium. Jedyna różnica polega na tym, że używam MongoRepository, a nie CrudRepository, ponieważ nie chcę na razie pracować z Iteratorami. Jeśli masz wskazówkę, będzie to docenione. –

+4

Najczęstszym błędem jest błędna nazwa klasy implementacji: jeśli twój bazowy interfejs repo nazywa się 'YourRepository', klasa implementacji musi mieć nazwę' YourRepositoryImpl'. Czy tak jest? Jeśli tak, z przyjemnością przyjrzę się przykładowemu projektowi na GitHub lub tym podobnym ... –

+1

Witaj Oliver, klasa Impl została nazwana błędnie, jak zakładałeś. Poprawiłem nazwę i wygląda na to, że działa teraz. Dziękuję bardzo za Twoją opinię. To naprawdę fajne móc korzystać z różnego rodzaju opcji zapytania w ten sposób. Dobrze przemyślane! –

11

Ta odpowiedź może być nieco opóźniona, ale zaleca się unikanie całej trasy repozytorium. Otrzymujesz bardzo mało wdrożonych metod o dowolnej wartości praktycznej. Aby to zadziałało, wpadasz w bzdury konfiguracji Java, które możesz spędzać dniami i tygodniami bez dużej pomocy w dokumentacji.

Zamiast tego należy udać się z trasą MongoTemplate i utworzyć własną warstwę dostępu do danych, która uwalnia od koszmarów konfiguracyjnych, przed którymi stają programiści Spring. MongoTemplate jest naprawdę zbawicielem dla inżynierów, którzy czują się wygodnie w projektowaniu własnych klas i interakcji, ponieważ jest w nich dużo elastyczności. Struktura może być coś takiego:

  1. Utwórz klasę MongoClientFactory, który będzie działał na poziomie aplikacji i dać ci MongoClient obiekt. Możesz to zaimplementować jako Singleton lub używając Enum Singleton (to jest bezpieczne dla wątków)
  2. Utwórz klasę dostępu do danych, z której możesz dziedziczyć obiekt dostępu do danych dla każdego obiektu domeny). Klasa bazowa może zaimplementować metodę tworzenia obiektu MongoTemplate, którego można używać w określonych metodach klas dla wszystkich dostępów DB. Każda klasa dostępu do danych dla każdego obiektu domeny może implementować podstawowe metody lub można je wdrożyć w klasie bazowej
  3. Metody kontrolera mogą następnie wywoływać metody w klasach dostępu do danych w razie potrzeby.
+0

Hi @rameshpa Czy mogę używać zarówno MongoTemplate, jak i repozytorium w tym samym projekcie? .. Czy można użyć – Gauranga

+1

Można, ale implementowany MongoTemplate będzie miał inne połączenie z DB niż połączenie używane przez Repozytorium. Atomowość może być problemem. Również nie polecam używania dwóch różnych połączeń w jednym wątku, jeśli masz potrzeby sekwencjonowania – rameshpa