Перейти к основному содержимому

Руководство по Eclipse JNoSQL

· 11 мин. чтения

1. Обзор

Eclipse JNoSQL — это набор API и реализаций, упрощающих взаимодействие Java-приложений с базами данных NoSQL .

В этой статье мы узнаем, как установить и настроить JNoSQL для взаимодействия с базой данных NoSQL. Мы будем работать как с коммуникационным, так и с картографическим слоем.

2. Коммуникационный уровень Eclipse JNoSQL

С технической точки зрения коммуникационный уровень состоит из двух модулей: Diana API и драйвера.

Хотя API определяет абстракцию для типов баз данных NoSQL, драйвер предоставляет реализации для большинства известных баз данных .

Мы можем сравнить это с JDBC API и драйвером JDBC в реляционных базах данных.

2.1. Eclipse JNoSQL Диана API

Проще говоря, существует четыре основных типа баз данных NoSQL: Key-Value, Column, Document и Graph.

И Eclipse JNoSQL Diana API определяет три модуля:

  1. Диана-ключ-значение
  2. диана-колонна
  3. Диана-документ

Тип графа NoSQL не поддерживается API, поскольку он уже поддерживается Apache ThinkerPop .

API основан на базовом модуле diana-core и определяет абстракцию общих понятий, таких как конфигурация, фабрика, менеджер, сущность и значение.

Для работы с API нам нужно предоставить зависимость соответствующего модуля от нашего типа базы данных NoSQL.

Таким образом, для документо-ориентированной базы данных нам понадобится зависимость diana-document :

<dependency>
<groupId>org.jnosql.diana</groupId>
<artifactId>diana-document</artifactId>
<version>0.0.6</version>
</dependency>

Точно так же мы должны использовать модуль diana-ключ-значение , если рабочая база данных NoSQL ориентирована на ключ-значение:

<dependency>
<groupId>org.jnosql.diana</groupId>
<artifactId>diana-key-value</artifactId>
<version>0.0.6</version>
</dependency>

И, наконец, модуль diana-column , если он ориентирован на столбцы:

<dependency>
<groupId>org.jnosql.diana</groupId>
<artifactId>diana-column</artifactId>
<version>0.0.6</version>
</dependency>

Самые свежие версии можно найти на Maven Central .

2.2. Драйвер Eclipse JNoSQL Диана

Драйвер представляет собой набор реализаций API для наиболее распространенных баз данных NoSQL .

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

Например, cockbase-driver реализует как diana-document, так и diana-key-value, потому что Couchbase ориентирован как на документ, так и на ключ-значение.

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

Чтобы начать работу с драйвером, мы должны включить API и соответствующую реализацию для выбранной базы данных NoSQL.

Например, для MongoDB нам нужно включить следующие зависимости:

<dependency>
<groupId>org.jnosql.diana</groupId>
<artifactId>diana-document</artifactId>
<version>0.0.6</version>
</dependency>
<dependency>
<groupId>org.jnosql.diana</groupId>
<artifactId>mongodb-driver</artifactId>
<version>0.0.6</version>
</dependency>

Процесс работы с драйвером прост.

Во-первых, нам нужен bean-компонент конфигурации . Прочитав файл конфигурации из пути к классам или значений жесткого кодирования, конфигурация может создать фабрику. Затем мы используем его для создания Manager.

Наконец, менеджер отвечает за отправку и извлечение Entity из базы данных NoSQL .

В следующих подразделах мы объясним этот процесс для каждого типа базы данных NoSQL.

2.3. Работа с документно-ориентированной базой данных

В этом примере мы будем использовать встроенную базу данных MongoDB , так как с ней легко начать работу и она не требует установки. Она ориентирована на документы, и следующие инструкции применимы к любой другой базе данных NoSQL, ориентированной на документы.

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

Мы можем предоставить эти настройки либо в mongodb-driver.properties, расположенном в пути к классам:

#Define Host and Port
mongodb-server-host-1=localhost:27017

Или как жестко закодированные значения:

Map<String, Object> map = new HashMap<>();
map.put("mongodb-server-host-1", "localhost:27017");

Затем мы создаем компонент конфигурации для типа документа:

DocumentConfiguration configuration = new MongoDBDocumentConfiguration();

Из этого компонента конфигурации мы можем создать ManagerFactory :

DocumentCollectionManagerFactory managerFactory = configuration.get();

Неявно метод get () компонента Configuration использует настройки из файла свойств. Мы также можем получить эту фабрику из жестко заданных значений:

DocumentCollectionManagerFactory managerFactory 
= configuration.get(Settings.of(map));

У ManagerFactory есть простой метод get(), который принимает имя базы данных в качестве параметра и создает Manager :

DocumentCollectionManager manager = managerFactory.get("my-db");

И, наконец, мы готовы. Менеджер предоставляет все необходимые методы для взаимодействия с базовой базой данных NoSQL через DocumentEntity.

Итак, мы могли бы, например, вставить документ:

DocumentEntity documentEntity = DocumentEntity.of("books");
documentEntity.add(Document.of("_id", "100"));
documentEntity.add(Document.of("name", "JNoSQL in Action"));
documentEntity.add(Document.of("pages", "620"));
DocumentEntity saved = manager.insert(documentEntity);

Мы также можем искать документы:

DocumentQuery query = select().from("books").where("_id").eq(100).build();
List<DocumentEntity> entities = manager.select(query);

И аналогичным образом мы могли бы обновить существующий документ:

saved.add(Document.of("author", "foreach"));
DocumentEntity updated = manager.update(saved);

И, наконец, мы можем удалить сохраненный документ:

DocumentDeleteQuery deleteQuery = delete().from("books").where("_id").eq("100").build();
manager.delete(deleteQuery);

Чтобы запустить пример, нам просто нужно получить доступ к модулю jnosql-diana и запустить приложение DocumentApp .

Мы должны увидеть вывод в консоли:

DefaultDocumentEntity{documents={pages=620, name=JNoSQL in Action, _id=100}, name='books'}
DefaultDocumentEntity{documents={pages=620, author=foreach, name=JNoSQL in Action, _id=100}, name='books'}
[]

2.4. Работа с базой данных, ориентированной на столбцы

В этом разделе мы будем использовать встроенную версию базы данных Cassandra , поэтому установка не требуется.

Процесс работы с базой данных, ориентированной на столбцы, очень похож. Первым делом добавляем в pom драйвер Cassandra и API колонки:

<dependency>
<groupId>org.jnosql.diana</groupId>
<artifactId>diana-column</artifactId>
<version>0.0.6</version>
</dependency>
<dependency>
<groupId>org.jnosql.diana</groupId>
<artifactId>cassandra-driver</artifactId>
<version>0.0.6</version>
</dependency>

Далее нам нужны параметры конфигурации, указанные в файле конфигурации diana-cassandra.properties в пути к классам. В качестве альтернативы мы могли бы также использовать жестко заданные значения конфигурации.

Затем, используя аналогичный подход, мы создадим ColumnFamilyManager и начнем манипулировать ColumnEntity:

ColumnConfiguration configuration = new CassandraConfiguration();
ColumnFamilyManagerFactory managerFactory = configuration.get();
ColumnFamilyManager entityManager = managerFactory.get("my-keySpace");

Итак, чтобы создать новый объект, давайте вызовем метод insert() :

ColumnEntity columnEntity = ColumnEntity.of("books");
Column key = Columns.of("id", 10L);
Column name = Columns.of("name", "JNoSQL in Action");
columnEntity.add(key);
columnEntity.add(name);
ColumnEntity saved = entityManager.insert(columnEntity);

Чтобы запустить пример и просмотреть выходные данные в консоли, запустите приложение ColumnFamilyApp .

2.5. Работа с базой данных, ориентированной на ключ-значение

В этом разделе мы будем использовать Hazelcast. Hazelcast — это база данных NoSQL, ориентированная на ключ-значение . Для получения дополнительной информации о базе данных Hazelcast вы можете проверить эту ссылку .

Процесс работы с типом, ориентированным на ключ-значение, также аналогичен. Начнем с добавления этих зависимостей в pom:

<dependency>
<groupId>org.jnosql.diana</groupId>
<artifactId>diana-key-value</artifactId>
<version>0.0.6</version>
</dependency>
<dependency>
<groupId>org.jnosql.diana</groupId>
<artifactId>hazelcast-driver</artifactId>
<version>0.0.6</version>
</dependency>

Затем нам нужно указать параметры конфигурации. Затем мы можем получить BucketManager , а затем манипулировать KeyValueEntity:

KeyValueConfiguration configuration = new HazelcastKeyValueConfiguration();
BucketManagerFactory managerFactory = configuration.get();
BucketManager entityManager = managerFactory.getBucketManager("books");

Допустим, мы хотим сохранить следующую модель Book :

public class Book implements Serializable {

private String isbn;
private String name;
private String author;
private int pages;

// standard constructor
// standard getters and setters
}

Итак, мы создаем экземпляр Book , а затем сохраняем его, вызывая метод put() ;

Book book = new Book(
"12345", "JNoSQL in Action",
"foreach", 420);
KeyValueEntity keyValueEntity = KeyValueEntity.of(
book.getIsbn(), book);
entityManager.put(keyValueEntity);

Затем, чтобы получить сохраненный экземпляр книги :

Optional<Value> optionalValue = manager.get("12345");
Value value = optionalValue.get(); // or any other adequate Optional handling
Book savedBook = value.get(Book.class);

Чтобы запустить пример и просмотреть выходные данные в консоли, запустите приложение KeyValueApp .

3. Уровень отображения Eclipse JNoSQL

Уровень сопоставления, Artemis API, представляет собой набор API-интерфейсов, которые помогают сопоставлять объекты с аннотациями Java с базами данных NoSQL . Он основан на API-интерфейсе Diana и CDI (внедрение контекста и зависимостей).

Мы можем рассматривать этот API как JPA или ORM, как в мире NoSQL . Этот уровень также предоставляет API для каждого типа NoSQL и один основной API для общих функций.

В этом разделе мы будем работать с документно-ориентированной базой данных MongoDB.

3.1. Требуемые зависимости

Чтобы включить Artemis в приложении, нам нужно добавить зависимость artemis-configuration . Поскольку MongoDB ориентирована на документы , также необходима зависимость artemis-document .

Для других типов баз данных NoSQL мы будем использовать artemis-column, artemis-key-value и artemis-graph .

Также необходим драйвер Diana для MongoDB:

<dependency>
<groupId>org.jnosql.artemis</groupId>
<artifactId>artemis-configuration</artifactId>
<version>0.0.6</version>
</dependency>
<dependency>
<groupId>org.jnosql.artemis</groupId>
<artifactId>artemis-document</artifactId>
<version>0.0.6</version>
</dependency>
<dependency>
<groupId>org.jnosql.diana</groupId>
<artifactId>mongodb-driver</artifactId>
<version>0.0.6</version>
</dependency>

Artemis основан на CDI, поэтому нам также необходимо предоставить эту зависимость от Maven:

<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>

3.2. Файл конфигурации документа

Конфигурация — это набор свойств для данной базы данных, которые позволяют нам предоставлять настройку вне кода. По умолчанию нам нужно предоставить файл jnosql.json в ресурсе META-INF.

Это пример файла конфигурации:

[
{
"description": "The mongodb document configuration",
"name": "document",
"provider": "org.jnosql.diana.mongodb.document.MongoDBDocumentConfiguration",
"settings": {
"mongodb-server-host-1":"localhost:27019"
}
}
]

Нам нужно будет указать имя конфигурации выше, установив атрибут имени в нашем ConfigurationUnit . Если конфигурация находится в другом файле, ее можно указать с помощью атрибута fileName .

Учитывая эту конфигурацию, мы создаем фабрику:

@Inject
@ConfigurationUnit(name = "document")
private DocumentCollectionManagerFactory<MongoDBDocumentCollectionManager> managerFactory;

И из этой фабрики мы можем создать DocumentCollectionManager :

@Produces
public MongoDBDocumentCollectionManager getEntityManager() {
return managerFactory.get("todos");
}

DocumentCollectionManager — это компонент с поддержкой CDI, который используется как в шаблоне , так и в репозитории.

3.3. Отображение

Сопоставление — это управляемый аннотациями процесс, посредством которого модель Entity преобразуется в EntityValue Diana.

Начнем с определения модели Todo :

@Entity
public class Todo implements Serializable {

@Id("id")
public long id;

@Column
public String name;

@Column
public String description;

// standard constructor
// standard getters and setters
}

Как показано выше, у нас есть основные аннотации сопоставления: @Entity, @Id и @Column.

Теперь, чтобы манипулировать этой моделью, нам нужен либо класс Template , либо интерфейс Repository .

3.4. Работа с шаблоном

Шаблон является связующим звеном между моделью сущностей и API Diana . Для базы данных, ориентированной на документы, мы начинаем с внедрения bean- компонента DocumentTemplate :

@Inject
DocumentTemplate documentTemplate;

И тогда мы можем манипулировать сущностью Todo . Например, мы можем создать Todo :

public Todo add(Todo todo) {
return documentTemplate.insert(todo);
}

Или мы можем получить Todo по id :

public Todo get(String id) {
Optional<Todo> todo = documentTemplate
.find(Todo.class, id);
return todo.get(); // or any other proper Optional handling
}

Чтобы выбрать все объекты, мы создаем DocumentQuery , а затем вызываем метод select() :

public List<Todo> getAll() {
DocumentQuery query = select().from("Todo").build();
return documentTemplate.select(query);
}

И, наконец, мы можем удалить объект Todo по id :

public void delete(String id) {
documentTemplate.delete(Todo.class, id);
}

3.5. Работа с репозиторием

В дополнение к классу Template мы также можем управлять сущностями через интерфейс Repository , который имеет методы для создания, обновления, удаления и извлечения информации.

Чтобы использовать интерфейс репозитория , мы просто предоставляем субинтерфейс репозитория:

public interface TodoRepository extends Repository<Todo, String> {
List<Todo> findByName(String name);
List<Todo> findAll();
}

В соответствии со следующими соглашениями об именах методов и параметров реализация этого интерфейса предоставляется во время выполнения в виде компонента CDI.

В этом примере все объекты Todo с совпадающим именем извлекаются методом findByName() .

Теперь мы можем использовать его:

@Inject
TodoRepository todoRepository;

Квалификатор базы данных позволяет нам работать с более чем одной базой данных NoSQL в одном приложении. Он поставляется с двумя атрибутами, типом и поставщиком.

Если БД мультимодельная, то нам нужно указать, с какой моделью мы работаем:

@Inject
@Database(value = DatabaseType.DOCUMENT)
TodoRepository todoRepository;

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

@Inject
@Database(value = DatabaseType.DOCUMENT, provider="org.jnosql.diana.mongodb.document.MongoDBDocumentConfiguration")
TodoRepository todoRepository;

Чтобы запустить пример, просто войдите в модуль jnosql-artemis и вызовите эту команду:

mvn package liberty:run

Эта команда создает, развертывает и запускает сервер Open Liberty благодаря плагину Liberty -maven-plugin .

3.6. Тестирование приложения

Поскольку приложение предоставляет конечную точку REST, мы можем использовать любой клиент REST для наших тестов. Здесь мы использовали инструмент завиток.

Итак, чтобы сохранить класс Todo:

curl -d '{"id":"120", "name":"task120", "description":"Description 120"}' -H "Content-Type: application/json" -X POST http://localhost:9080/jnosql-artemis/todos

и чтобы получить все Todo:

curl -H "Accept: application/json" -X GET http://localhost:9080/jnosql-artemis/todos

Или, чтобы получить только одно задание:

curl -H "Accept: application/json" -X GET http://localhost:9080/jnosql-artemis/todos/120

4. Вывод

В этом руководстве мы рассмотрели, как JNoSQL может абстрагировать взаимодействие с базой данных NoSQL.

Во-первых, мы использовали JNoSQL Diana API для взаимодействия с базой данных с помощью низкоуровневого кода. Затем мы использовали JNoSQL Artemis API для работы с дружественными аннотированными моделями Java .

Как обычно, мы можем найти код, использованный в этой статье , на Github .