2013-06-09 4 views
53

Мне нужно написать приложение, с помощью которого я могу выполнять сложные запросы, используя spring-data и mongodb. Я начал использовать MongoRepository, но боролся со сложными запросами, чтобы найти примеры или понять Синтаксис.В чем разница между MongoTemplate и MongoRepository Spring Data?

Я говорю о запросах, как это:

@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

«Удобный» и «мощный в использовании» в какой-то степени противоречат целям. Хранилища гораздо удобнее, чем шаблоны, но последние, конечно, дают вам более тонкий контроль над тем, что нужно выполнять.

Поскольку модель программирования репозитория доступна для нескольких модулей данных Spring, вы найдете более подробную документацию по ней в общем разделе данных Spring MongoDB reference docs.

TL; DR

Обычно мы рекомендуем следующий подход:

  1. Начать с абстрактным хранилище и просто объявить простые запросы, используя механизм выведения запросов или вручную определенные запросы.
  2. Для более сложных запросов добавьте в репозиторий вручную внедренные методы (как описано здесь). Для реализации используйте MongoTemplate.

Подробности

Для примера это будет выглядеть примерно так:

  1. Define интерфейс для пользовательского кода:

    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

Привет, Оливер, это на самом деле не работает. spring-data пытается автоматически генерировать запрос из пользовательского имени. yourCustomMethod(). Он скажет, что «ваш» не является допустимым полем в классе домена. Я выполнил руководство и также дважды проверил, как вы делаете это примеры spring-data-jpa. Не повезло. spring-data всегда пытается автоматически генерировать, как только я расширяю пользовательский интерфейс к классу репозитория. Единственное различие заключается в том, что я использую MongoRepository, а не CrudRepository, так как пока не хочу работать с Iterators. Если бы у вас был намек, это было бы оценено. –

+4

Самая распространенная ошибка - назвать неправильный класс реализации: если ваш базовый интерфейс репо называется 'YourRepository', класс реализации должен быть назван' YourRepositoryImpl'. Это так? Если это так, я с удовольствием посмотрю пример проекта на GitHub или тому подобное ... –

+1

Привет, Оливер, класс Impl был назван неправильным, как вы предполагали. Я скорректировал имя, и теперь он выглядит как его работа. Большое спасибо за ваши отзывы. Это действительно здорово, чтобы иметь возможность использовать различные варианты запросов таким образом. Ну продумал! –

11

Этот ответ может быть немного задержан, но я бы рекомендовал избегать всего маршрута репозитория. Вы получаете очень мало реализованных методов любой большой практической ценности. Чтобы заставить его работать, вы сталкиваетесь с ошибкой конфигурации Java, которую вы можете потратить дни и недели без значительной помощи в документации.

Вместо этого перейдите по маршруту MongoTemplate и создайте свой собственный уровень доступа к данным, который освободит вас от кошмаров конфигурации, с которыми сталкиваются программисты Spring. MongoTemplate - действительно спаситель для инженеров, которые умеют создавать собственные классы и взаимодействия, поскольку существует много гибкости. Структура может быть что-то вроде этого:

  1. Создать MongoClientFactory класс, который будет работать на уровне приложений и дать вам MongoClient объект. Вы можете реализовать это как Singleton или использовать Enum Singleton (это потокобезопасно)
  2. Создайте базовый класс доступа к данным, из которого вы можете наследовать объект доступа к данным для каждого объекта домена). Базовый класс может реализовать метод создания объекта MongoTemplate, который вы можете использовать для каждого доступа к базе данных
  3. Каждый класс доступа к данным для каждого объекта домена может реализовать основные методы или реализовать их в базовом классе
  4. В этом случае методы контроллера могут вызывать методы в классах доступа к данным.
+0

Привет @rameshpa Могу ли я использовать MongoTemplate и репозиторий в том же проекте? .. Можно ли использовать – Gauranga

+1

Вы могли бы, но MongoTemplate, который вы реализуете, будет иметь другое соединение с БД, чем соединение, используемое репозиторием. Атомность может быть проблемой. Также я бы не рекомендовал использовать два разных соединения в одном потоке, если у вас есть потребности в последовательности – rameshpa

Смежные вопросы