Рубрики
Без рубрики

Введение в Morphia – Java ODM для MongoDB

Краткий и практический обзор Morphia – Java ODM для MongoDB.

Автор оригинала: Kumar Chandrakant.

1. Обзор

В этом учебнике мы поймем, как его Морфия , Объект Документ Mapper (ODM) для MongoDB на Java.

В процессе мы также поймем, что такое ODM и как он облегчает работу с MongoDB.

2. Что такое ODM?

Для тех, кто непосвященных в этой области, МонгоДБ — это база данных, ориентированная на документы, созданная для . Документно-ориентированные базы данных, проще говоря, управляют документами, которые являются не чем иным, схема менее способ организации полу структурированных данных . Они подпадают под более широкий и слабо определяемый зонтик баз данных NoS’L, названный в честь их очевидного отхода от традиционной организации баз данных S’L.

MongoDB предоставляет драйверы почти для всех популярных языков программирования, таких как Java. Эти драйверы предлагают слой абстракции для работы с MongoDB, так что мы не работаем с Wire Protocol напрямую. Думайте об этом как Oracle, обеспечивающая реализацию драйвера JDBC для их реляционной базы данных.

Однако, если мы вспомним наши дни работы с JDBC напрямую, мы можем оценить, как грязный он может получить – особенно в объектно-ориентированной парадигмы. К счастью, у нас есть объект реляционного картирования (ORM) рамки, как Hibernate к нашему спасению. Это не очень отличается для MongoDB.

Хотя мы, безусловно, можем работать с драйвером низкого уровня, для выполнения этой задачи требуется гораздо больше шаблонов. Вот, у нас есть аналогичная концепция ORM называется объект документ Mapper (ODM) . Morphia точно заполняет это пространство для языка программирования Java и работает поверх драйвера Java для MongoDB.

3. Настройка зависимостей

Мы видели достаточно теории, чтобы вставить нас в какой-то код. Для наших примеров мы смоосмотрим библиотеку книг и посмотрим, как мы можем управлять ею в MongoDB с помощью Morphia.

Но прежде чем мы начнем, нам нужно настроить некоторые из зависимостей.

3.1. МонгоДБ

Нам нужен бегущий экземпляр MongoDB для работы. Есть несколько способов получить это, и самый простой заключается в том, чтобы скачать и установить сообщество издание на нашей местной машине.

Мы должны оставить все конфигурации по умолчанию как есть, включая порт, на котором работает MongoDB.

3.2. Морфия

Мы можем скачать предварительно построенные JARs для Morphia из Мавен Центральный и использовать их в нашем Java-проекте.

Однако самый простой способ заключается в использовании инструмента управления зависимостью, как Maven:


    dev.morphia.morphia
    core
    1.5.3

4. Как подключиться с помощью Morphia?

Теперь, когда MongoDB установлен и запущен и создал Morphia в нашем Java-проекте, мы готовы подключиться к MongoDB с помощью Morphia.

Давайте посмотрим, как мы можем достичь этого:

Morphia morphia = new Morphia();
morphia.mapPackage("com.baeldung.morphia");
Datastore datastore = morphia.createDatastore(new MongoClient(), "library");
datastore.ensureIndexes();

Это в значительной степени это! Давайте поймем это лучше. Нам нужны две вещи для наших картографических операций для работы:

  1. Mapper: Это отвечает за отображение наших Java POJOs в коллекции MongoDB . В нашем фрагменте кода выше, Морфия это класс, ответственный за это. Обратите внимание, как мы настраиваем пакет, где он должен искать наши POJOs.
  2. Подключение: Это подключение к базе данных MongoDB, на которой картограф может выполнять различные операции. Классная Данные магазина принимает в качестве параметра экземпляр МонгоКлиент (от драйвера Java MongoDB) и названия базы данных MongoDB, возвращение активной связи для работы с .

Итак, мы все готовы использовать этот Данные магазина и работать с нашими организациями.

5. Как работать с организациями?

Прежде чем мы сможем использовать наши свежеотчеканенные Данные магазина , мы должны определить некоторые объекты домена для работы.

5.1. Простое образование

Начнем с определения простого Книжный сущность с некоторыми атрибутами:

@Entity("Books")
public class Book {
    @Id
    private String isbn;
    private String title;
    private String author;
    @Property("price")
    private double cost;
    // constructors, getters, setters and hashCode, equals, toString implementations
}

Есть несколько интересных вещей, чтобы отметить здесь:

  • Обратите внимание на аннотацию @ Организация что квалифицирует этот POJO для ODM картографирования по Морфия
  • Morphia, по умолчанию, отображает сущность для коллекции в MongoDB по имени своего класса, но мы можем явно переопределить это (как мы сделали для сущности Книжный здесь)
  • Morphia, по умолчанию, отображает переменные в сущности к клавишам в коллекции MongoDB по имени переменной, но опять же мы можем переопределить это (как мы сделали для переменной стоимость здесь)
  • Наконец, мы должны пометить переменную в сущности, чтобы выступать в качестве основного ключа по аннотации и Id (как мы используем ISBN для нашей книги здесь)

5.2. Организации с отношениями

В реальном мире, однако, сущности вряд ли так просто, как они выглядят и имеют сложные отношения друг с другом. Например, наша простая сущность Книжный может иметь Издатель и может ссылаться на другие книги-компаньоны. Как мы их моделим?

MongoDB предлагает два механизма построения отношений – ссылки и встраивание . Как следует из названия, со ссылками, MongoDB хранит связанные данные как отдельный документ в той же или другой коллекции и просто ссылается на него, используя свой идентификатор.

Напротив, при встраивании, MongoDB хранит или, скорее, встраивает отношение в сам родительский документ.

Давайте посмотрим, как мы можем их использовать. Начнем с встраивания Издатель в нашем Книжный :

@Embedded
private Publisher publisher;

Достаточно просто. Теперь давайте идти вперед и добавить ссылки на другие книги:

@Reference
private List companionBooks;

Вот и все – Morphia предоставляет удобные аннотации к модели отношений при поддержке MongoDB. Выбор однако ссылки на встраивание и встраивание должны опираться на сложность модели данных, избыточность и среди других соображений.

Упражнение аналогично нормализации в реляционных базах данных.

Теперь мы готовы выполнить некоторые операции на Книжный с помощью Данные магазина .

6. Некоторые основные операции

Давайте посмотрим, как работать с некоторыми из основных операций с помощью Morphia.

6.1. Сохранить

Начнем с простейших операций, создав экземпляр Книжный в нашей базе данных MongoDB библиотечный :

Publisher publisher = new Publisher(new ObjectId(), "Awsome Publisher");

Book book = new Book("9781565927186", "Learning Java", "Tom Kirkman", 3.95, publisher);
Book companionBook = new Book("9789332575103", "Java Performance Companion", 
  "Tom Kirkman", 1.95, publisher);

book.addCompanionBooks(companionBook);

datastore.save(companionBook);
datastore.save(book);

Этого достаточно, чтобы позволить Morphia создать коллекцию в нашей базе данных MongoDB, если ее не существует, и выполнить операцию upsert.

6.2. Запрос

Давайте посмотрим, сможем ли мы запросить книгу, которую мы только что создали в MongoDB:

List books = datastore.createQuery(Book.class)
  .field("title")
  .contains("Learning Java")
  .find()
  .toList();

assertEquals(1, books.size());

assertEquals(book, books.get(0));

Запрос документа в Morphia начинается с создания запроса с использованием Данные магазина а затем декларативно добавляя фильтры, к радости тех, кто влюблен в функциональное программирование!

Morphia поддерживает гораздо больше комплексная конструкция запросов с фильтрами и операторами . Кроме того, Morphia позволяет ограничивать, пропускать и упорядочить результаты в запросе.

Более того, Morphia позволяет использовать необработанные запросы, написанные с драйвером Java для MongoDB для большего контроля, если это необходимо.

6.3. Обновление

Хотя операция сохранения может обрабатывать обновления, если основные ключевые совпадения, Morphia предоставляет способы выборочного обновления документов:

Query query = datastore.createQuery(Book.class)
  .field("title")
  .contains("Learning Java");

UpdateOperations updates = datastore.createUpdateOperations(Book.class)
  .inc("price", 1);

datastore.update(query, updates);

List books = datastore.createQuery(Book.class)
  .field("title")
  .contains("Learning Java")
  .find()
  .toList();

assertEquals(4.95, books.get(0).getCost());

Здесь мы строим запрос и операцию обновления, чтобы увеличить на один цену всех книг, возвращенных запросом.

6.4. Удалить

Наконец, то, что было создано, должно быть удалено! Опять же, с Morphia, это довольно интуитивно:

Query query = datastore.createQuery(Book.class)
  .field("title")
  .contains("Learning Java");

datastore.delete(query);

List books = datastore.createQuery(Book.class)
  .field("title")
  .contains("Learning Java")
  .find()
  .toList();

assertEquals(0, books.size());

Мы создаем запрос так же, как и раньше, и запускаем операцию удаления на Данные магазина .

7. Расширенное использование

MongoDB имеет некоторые передовые операции, такие как агрегация, индексирование и многие другие . Хотя это не возможно выполнить все, что с помощью Morphia, это, безусловно, можно достичь некоторых из них. Для других, к сожалению, нам придется вернуться к драйверу Java для MongoDB.

Давайте сосредоточимся на некоторых из этих передовых операций, которые мы можем выполнить через Morphia.

7.1. Агрегация

Агрегация в MongoDB позволяет нам определить ряд операций в конвейере, которые могут работать на наборе документов и производить агрегированные выходные .

Morphia имеет API для поддержки такого агрегации трубопровода.

Допустим, мы хотим агрегировать наши библиотечные данные таким образом, чтобы у нас были все книги, сгруппированные их автором:

Iterator iterator = datastore.createAggregation(Book.class)
  .group("author", grouping("books", push("title")))
  .out(Author.class);

Итак, как это работает? Мы начинаем с создания агрегации трубопровода с использованием той же старой Данные магазина . Мы должны предоставить объект, на котором мы хотим выполнять операции по агрегированию, например, Книжный здесь.

Далее мы хотим сгруппить документы по “автору” и агрегировать их “название” под ключ под названием “книги”. Наконец, мы работаем с ODM здесь. Таким образом, мы должны определить сущность для сбора наших агрегированных данных – в нашем случае, это Автор .

Конечно, мы должны определить сущность, называемую Автор с переменной под названием книги:

@Entity
public class Author {
    @Id
    private String name;
    private List books;
    // other necessary getters and setters
}

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

7.2. Проекция

Проекция в MongoDB позволяет нам выбрать только поля, которые мы хотим получить из документов в наших запросах . В случае, если структура документов сложна и тяжела, это может быть очень полезно, когда нам нужно всего несколько полей.

Допустим, нам нужно только принести книги с их названием в нашем запросе:

List books = datastore.createQuery(Book.class)
  .field("title")
  .contains("Learning Java")
  .project("title", true)
  .find()
  .toList();
 
assertEquals("Learning Java", books.get(0).getTitle());
assertNull(books.get(0).getAuthor());

Здесь, как мы видим, мы только получить обратно название в нашем результате, а не автор и другие области. Мы должны, однако, быть осторожными в использовании прогнозируемых выходных данных в экономии обратно в MongoDB. Это может привести к потере данных!

7.3. Индексация

Индексы играют очень важную роль в оптимизации запросов с базами данных – реляционными, а также многими не реляционными.

МонгоДБ определяет индексы на уровне коллекции с уникальным индексом, созданным на первичном ключе по умолчанию . Кроме того, MongoDB позволяет создавать индексы на любом поле или под полях в документе. Мы должны создать индекс на ключе в зависимости от запроса, который мы хотим создать.

Например, в нашем примере мы, возможно, пожелаем создать индекс на поле “название” Книжный как мы часто в конечном итоге запрос на нем:

@Indexes({
  @Index(
    fields = @Field("title"),
    options = @IndexOptions(name = "book_title")
  )
})
public class Book {
    // ...
    @Property
    private String title;
    // ...
}

Конечно, мы можем пройти дополнительные варианты индексации, чтобы адаптировать нюансы индекса, который создается. Обратите внимание, что поле должно быть аннотировано Недвижимость для использования в индексе.

Кроме того, помимо индекса уровня класса, Morphia имеет аннотацию для определения индекса на уровне поля.

7.4. Проверка схемы

У нас есть возможность предоставить правила проверки данных для коллекции, которые MongoDB может использовать при выполнении обновления или вставки . Morphia поддерживает это через свои API.

Допустим, мы не хотим вставлять книгу без действительной цены. Для достижения этой цели мы можем использовать проверку схемы:

@Validation("{ price : { $gt : 0 } }")
public class Book {
    // ...
    @Property("price")
    private double cost;
    // ...
}

Существует богатый набор проверк, предоставляемых MongoDB которые могут быть использованы здесь.

8. Альтернативные ОДМ МонгоДБ

Morphia не единственный доступный MongoDB ODM для Java. Есть несколько других, которые мы можем рассмотреть возможность использования в наших приложениях. Обсуждение сравнения с Morphia не возможно здесь, но это всегда полезно знать наши варианты:

  • Весенние данные : Предоставляет весеннюю модель программирования для работы с MongoDB
  • МонгоДжек : Обеспечивает прямое отображение объектов JSON в MongoDB

Это не полный список ODMs MongoDB для Java, но есть несколько интересных альтернатив доступны!

9. Заключение

В этой статье мы поняли основные детали MongoDB и использование ODM для подключения и работы на MongoDB из языка программирования, как Java. Мы также исследовали Morphia как MONgoDB ODM для Java и различных возможностей, которые она имеет.

Как всегда, код можно найти более чем на GitHub.